关于持久层和业务层代码封装的一点点设计
2017-11-07 11:35
330 查看
前言:
换公司以前写了一年半的ERP,持久层框架用的mybatis,基本的一些类和xml是通过mybatis逆向工程自动生成的,所以反射的数据库有多少表就会生成多少个dao,实际上生成的这些dao里面的增删改查方法都是一样的,不一样的只是实体类型而已,以前没什么经验只知道这部分代码重复也不知道怎么办,现在来到这家公司,看了看代码,发现这里已经对持久层的dao和业务层的service进行了封装,于是自己动手写了个demo体现一下这种设计,非常好的利用了java的泛型、继承和多态。
老规矩先上目录结构:
ps:包名带_1的是传统的逆向生成的代码,为了掩饰就写了2个方法。
实体类都是一样:
先看一下_1包里面的代码结构
(结构很清晰,数据库中每个表都有自己对应的:实体-mapper-service-serviceImpl):
总结:以上是传统的不带任何设计的持久层和业务层,缺点非常明显,没有充分利用java语言的特点,这样有多少表就会生成多少重复代码,现在看一下带有设计的代码结构:
总结:
1.多出一个泛型实体的BaseMapper来统一管理mybatis提供的增删改查,保留原来的Mapper去继承BaseMapper,简化了重复的增删改查,每个Mapper只写与自己相关的方法
2.多出一个泛型Mapper和实体的BaseService来统一管理,这样写serviceImpl时继承BaseService传入Mapper和实体后,就不用在serviceImpl注入Mapper,由于BaseService是抽象类还能写一些公共方法让子类自由实现(体现多态),还能实现自己的service来写自己的业务逻辑
换公司以前写了一年半的ERP,持久层框架用的mybatis,基本的一些类和xml是通过mybatis逆向工程自动生成的,所以反射的数据库有多少表就会生成多少个dao,实际上生成的这些dao里面的增删改查方法都是一样的,不一样的只是实体类型而已,以前没什么经验只知道这部分代码重复也不知道怎么办,现在来到这家公司,看了看代码,发现这里已经对持久层的dao和业务层的service进行了封装,于是自己动手写了个demo体现一下这种设计,非常好的利用了java的泛型、继承和多态。
老规矩先上目录结构:
ps:包名带_1的是传统的逆向生成的代码,为了掩饰就写了2个方法。
实体类都是一样:
public class User { private Integer id; private String name; private String gender; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } } public class Company { private Integer id; private String name; private String address; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
先看一下_1包里面的代码结构
(结构很清晰,数据库中每个表都有自己对应的:实体-mapper-service-serviceImpl):
@Component public interface CompanyMapper { Company selectByPrimaryKey(Integer id); } public interface CompanyService { Company selectById(Integer id); } @Service public class CompanyServiceImpl implements CompanyService{ @Autowired private CompanyMapper companyMapper; @Override public Company selectById(Integer id) { return companyMapper.selectByPrimaryKey(id); } } @Component public interface UserMapper { User selectByPrimaryKey(Integer id); } public interface UserService { User selectById(Integer id); } @Service public class UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override public User selectById(Integer id) { return userMapper.selectByPrimaryKey(id); } }
总结:以上是传统的不带任何设计的持久层和业务层,缺点非常明显,没有充分利用java语言的特点,这样有多少表就会生成多少重复代码,现在看一下带有设计的代码结构:
@Component public interface BaseMapper<T> { T selectByPrimaryKey(Integer id); void updateByPrimaryKey(T t); } @Component public interface CompanyMapper extends BaseMapper<Company>{ } public interface CompanyService { } public abstract class BaseService<D extends BaseMapper<T>,T> { @Autowired protected D dao; public abstract void saveById(Integer id); } @Service public class CompanyServiceImpl extends BaseService<CompanyMapper,Company> implements CompanyService { @Override public void saveById(Integer id) { Company company = this.dao.selectByPrimaryKey(id); company.setAddress("new address"); this.dao.updateByPrimaryKey(company); } } @Component public interface UserMapper extends BaseMapper<User>{ } public interface UserService { } @Service public class UserServiceImpl extends BaseService<UserMapper,User> implements UserService{ @Override public void saveById(Integer id) { User user = this.dao.selectByPrimaryKey(id); user.setGender("F"); this.dao.updateByPrimaryKey(user); } }
总结:
1.多出一个泛型实体的BaseMapper来统一管理mybatis提供的增删改查,保留原来的Mapper去继承BaseMapper,简化了重复的增删改查,每个Mapper只写与自己相关的方法
2.多出一个泛型Mapper和实体的BaseService来统一管理,这样写serviceImpl时继承BaseService传入Mapper和实体后,就不用在serviceImpl注入Mapper,由于BaseService是抽象类还能写一些公共方法让子类自由实现(体现多态),还能实现自己的service来写自己的业务逻辑
相关文章推荐
- 关于业务系统中代码的管理
- 关于跨浏览器的部分代码的封装
- 性能测试技术的研究_关于性能测试业务场景设计的研究
- 关于对H264码流的TS的封装的相关代码实现
- 关于对H264码流的PS的封装的相关代码实现
- 【性能测试思想】性能测试技术的研究_关于性能测试业务场景设计的研究
- 代码重构(一)之从代码设计层面着手实践:App.Config的读写封装
- 周报 关于G711a+H264封装成MP4(代码是转自http://blog.csdn.net/skdkjzz/article/details/40393891)
- Android 设计模式实战之关于封装计费代码库的策略模式详谈
- UserControl 中包含封装了集合对象的属性被设计器自动初始化所引起的错误!也有关于List的问题
- 关于android封装代码问题
- 网页设计关于表单输入框的技巧代码
- 关于把设计时代码从运行时代码中分离出来的问题
- 关于对H264码流的PS的封装的相关代码实现
- android简洁代码封装 -- popupwindow/dialog在实际业务中的封装
- 对企业库的封装,业务层开启事务的解决方案(可直接使用的代码)
- 对主流框架OKHttp的封装,达到一行代码实现一个业务逻辑
- 0907期《程序员》架构栏目文章《关于大规模系统缓存设计的一些考虑(上)》示例代码
- 关于网站设计的一点点讨论
- 业务需要,得到了两段正则表达式的代码,JAVASCRIPT的(关于车牌号码的校验问题)。