今天主要改寫昨天的組合模式成Web系統。數據庫
容器接口爲瀏覽器
public interface TreeProduct { /** * 展現全部產品 * @return */ List<TreeProduct> allProducts(); /** * 增長一個產品 * @param product * @return */ boolean addProduct(TreeProduct product); /** * 增長一組產品 * @param products * @return */ boolean addProducts(List<TreeProduct> products); /** * 移除產品 * @param product * @return */ boolean removeProduct(TreeProduct product); /** * 保存數據進數據庫 * @param product * @return */ int save(TreeProduct product); }
產品分類表結構以下app
產品表結構以下ide
對數據庫操做的Dao工具
@Mapper public interface ProductDao { @Insert("insert into type_product (id,name) values (#{id},#{name})") int saveType(TypeProduct type); @Insert("insert into product (id,name,model,price) values (#{id},#{name},#{model},#{price})") int saveProduct(Product product); @Update("update type_product t set t.parent_id=#{sourceId} where t.id=#{id}") int addType(Param param); @Update("update product p set p.type_id=#{sourceId} where p.id=#{id}") int addProduct(Param param); @Delete("delete from type_product where id=#{id}") int removeType(Long id); @Delete("delete from product where id=#{id}") int removeProduct(Long id); }
SpringBoot上下文工具this
public class SpringBootUtil { private static ApplicationContext applicationContext = null; public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if(SpringBootUtil.applicationContext == null){ SpringBootUtil.applicationContext = applicationContext; } } //獲取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } //經過name獲取 Bean. public static Object getBean(String name){ return getApplicationContext().getBean(name); } //經過class獲取Bean. public static <T> T getBean(Class<T> clazz){ return getApplicationContext().getBean(clazz); } //經過name,以及Clazz返回指定的Bean public static <T> T getBean(String name,Class<T> clazz){ return getApplicationContext().getBean(name, clazz); } }
在Springboot main方法中獲取SpringbootApplication上下文spa
@EnableTransactionManagement @SpringBootApplication public class ProductApplication { public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(ProductApplication.class, args); SpringBootUtil.setApplicationContext(applicationContext); } }
產品類型類對象
@NoArgsConstructor @ToString public class TypeProduct implements TreeProduct { @Getter @Setter private Long id; @Getter @Setter private String name; //下級產品列表 @Getter private List<TreeProduct> treeProducts = new CopyOnWriteArrayList<>(); public TypeProduct(Long id,String name) { this.id = id; this.name = name; } @Override public List<TreeProduct> allProducts() { return this.treeProducts; } @Override public boolean addProduct(TreeProduct product) { ProductDao productDao = SpringBootUtil.getBean(ProductDao.class); Param param = null; if (product instanceof TypeProduct) { param = new Param(this.id,((TypeProduct) product).getId()); productDao.addType(param); }else if (product instanceof Product) { param = new Param(this.id,((Product) product).getId()); productDao.addProduct(param); } return treeProducts.add(product); } @Override public boolean removeProduct(TreeProduct product) { ProductDao productDao = SpringBootUtil.getBean(ProductDao.class); if (product instanceof TypeProduct) { productDao.removeType(((TypeProduct) product).getId()); }else if (product instanceof Product) { productDao.removeProduct(((Product) product).getId()); } return treeProducts.remove(product); } @Override public boolean addProducts(List<TreeProduct> products) { for (TreeProduct product:products) { this.addProduct(product); } return true; } @Override public int save(TreeProduct product) { ProductDao productDao = SpringBootUtil.getBean(ProductDao.class); if (product instanceof TypeProduct) { return productDao.saveType((TypeProduct) product); } return 0; } }
產品類blog
@Data @AllArgsConstructor @NoArgsConstructor @ToString public class Product implements TreeProduct { private Long id; private String name; private String model; private BigDecimal price; @Override public List<TreeProduct> allProducts() { return Arrays.asList(this); } @Override public boolean addProduct(TreeProduct product) { throw new RuntimeException("不支持此方法"); } @Override public boolean removeProduct(TreeProduct product) { throw new RuntimeException("不支持此方法"); } @Override public boolean addProducts(List<TreeProduct> products) { throw new RuntimeException("不支持此方法"); } @Override public int save(TreeProduct product) { ProductDao productDao = SpringBootUtil.getBean(ProductDao.class); if (product instanceof Product) { return productDao.saveProduct((Product) product); } return 0; } }
跟以往的貧血模式不一樣,咱們將全部的業務方法放在了實體類中。接口
產品工廠
public class ProductFactory { public static TreeProduct createType(Long id,String name) { TreeProduct product = new TypeProduct(id,name); product.save(product); return product; } public static TreeProduct createProduct(Long id, String name, String model, BigDecimal price) { TreeProduct product = new Product(id,name,model,price); product.save(product); return product; } }
由產品工廠類,咱們能夠看到,當工廠生產一個產品時,就在數據庫中產生一條數據。
對外部的Controller
@RestController public class ProductController { @Autowired private IdService idService; @Transactional @GetMapping("/showall") public TreeProduct showAll() { //生產一個根目錄 TreeProduct root = ProductFactory.createType(idService.genId(),"根目錄"); //生產一個可樂的產品類型 TreeProduct type1 = ProductFactory.createType(idService.genId(),"可樂"); //生產一個咖啡的產品類型 TreeProduct type2 = ProductFactory.createType(idService.genId(),"咖啡"); //產品類型列表 List<TreeProduct> types1 = new ArrayList<>(); types1.add(type1); types1.add(type2); //生產一個可口可樂的產品 TreeProduct product1 = ProductFactory.createProduct(idService.genId(),"可口可樂","500ml",new BigDecimal(3)); //生產一個雀巢咖啡的產品 TreeProduct product2 = ProductFactory.createProduct(idService.genId(),"雀巢咖啡","600ml",new BigDecimal(6)); //將產品類型列表添加到根目錄中 root.addProducts(types1); //將可口可樂放入可樂類型中 type1.addProduct(product1); //將雀巢咖啡放入咖啡類型中 type2.addProduct(product2); //返回整個產品類型和產品 return root; } }
對比昨天的Java SE的代碼,咱們能夠看到,這裏跟昨天的代碼沒有什麼太大區別,都是對象間的操做,看不到數據庫操做的痕跡。
在瀏覽器訪問後的結果
數據庫中也有了相應的數據