1. 程式人生 > >關於持久層和業務層程式碼封裝的一點點設計

關於持久層和業務層程式碼封裝的一點點設計

前言:
換公司以前寫了一年半的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來寫自己的業務邏輯