今天主要改写昨天的组合模式成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的代码,咱们能够看到,这里跟昨天的代码没有什么太大区别,都是对象间的操做,看不到数据库操做的痕迹。
在浏览器访问后的结果
数据库中也有了相应的数据