您的位置:首页 > 编程语言

关于持久层和业务层代码封装的一点点设计

2017-11-07 11:35 330 查看
前言:

换公司以前写了一年半的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来写自己的业务逻辑
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式