1.在Spring4中使用通用Mapper
Spring4增加了對泛型注入的支援,這個特性對通用Mapper來說,非常的有用,可以說有了這個特性,可以直接在Service中寫Mapper mapper,可以通過BaseService來實作通用的Service。
這篇文檔主要講解通用Mapper在Spring4中的最佳用法。
2.一、在Spring4中配置通用Mapper
和Spring3中的配置一樣,配置方法請看這裡有關Spring配置的資訊。
如果有人不明白完整的配置什麼樣,可以看下面的例子:
Mybatis-Spring4項目
applicationContext.xml
3.二、繼承Mapper實作自己的實體接口類
這裡以Country2Mapper為例:
public interface Country2Mapper extends Mapper {
//省略其他自己增加的方法
}
如果你點進去上面的Country2Mapper檢視,會發現裡面還有一些Example的方法,這些是代碼生成器生成的,生成的方法不包含通用的CRUD,隻有Example的方法,還有一個對應的Country2Mapper.xml。
這個例子主要說明,除了通用Mapper的方法外,你可以添加自己的方法,和原來的沒有差別。
這裡的實體Country2代碼如下:
@Table(name="country")
public class Country2 {
@Id
private Integer id;
private String countryname;
private String countrycode;
//省略getter和setter方法
}
這裡配置對應的表名為country。隻有一個主鍵id。
4.三、在Service中使用
在Service中的使用方式有很多種。
5.第一種、直接注入上面定義的Country2Mapper
@Service
public class DemoService {
@Autowired
private Country2Mapper mapper;
public List selectPage(int pageNum,int pageSize){
PageHelper.startPage(pageNum, pageSize);
//Spring4支援泛型注入
return mapper.select(null);
}
}
這種方式太常見,太普通,這裡不多解釋。
6.第二種、泛型注入
這種方式用的就很少了,但是Spring4支援泛型注入,是以在第一種的基礎上,我們可以寫出如下的代碼:
@Service
public class DemoService {
@Autowired
private Mapper mapper;
public List selectPage(int pageNum,int pageSize){
//這裡用到了分頁插件PageHelper
PageHelper.startPage(pageNum, pageSize);
//Spring4支援泛型注入
return mapper.select(null);
}
}
對于不了解泛型注入的,可能會不習慣Mapper mapper這種寫法,實際上這麼寫的優勢并不明顯。還不如第一種明确。
但是通過第二種,我們可以引出第三種,也可能會是很常用的通用Service。
7.第三種、通用Service
一般操作資料庫都在Service中進行,不可避免的就要寫出大量重複的CRUD方法,如果能有一個通用的Service,肯定也會減少很多工作量。
這裡通過簡單擴充來講,更複雜的封裝,各位可以根據自己的情況動手實踐。
如下簡單例子:
@Service
public abstract class BaseService {
@Autowired
protected Mapper mapper;
public int save(T entity){
return mapper.insert(entity);
}
public int delete(T entity){
return mapper.deleteByPrimaryKey(entity);
}
public List selectPage(int pageNum,int pageSize){
PageHelper.startPage(pageNum, pageSize);
//Spring4支援泛型注入
return mapper.select(null);
}
}
建立如上所示的抽象類BaseService,這裡封裝三個方法僅作為簡單的例子。需要更複雜邏輯的可以自行摸索。
然後修改剛才的DemoService例子:
@Service
public class DemoService extends BaseService{
}
由于BaseService封裝了單表的分頁插件,是以目前的DemoService中沒有任何代碼。
假如我們要增加一個包含校驗的儲存方法。添加如下代碼:
@Service
public class DemoService extends BaseService{
public int save(Country2 country2) {
if (country2 == null) {
throw new NullPointerException("儲存的對象不能為空!");
}
if (country2.getCountrycode() == null || country2.getCountrycode().equals("")) {
throw new RuntimeException("國家代碼不能為空!");
}
if (country2.getCountryname() == null || country2.getCountryname().equals("")) {
throw new RuntimeException("國家名稱不能為空!");
}
return super.save(country2);
}
}
上面隻是個例子,是否抛出異常各位不用計較。
從這個例子應該也能看到,當使用Spring4和通用Mapper的時候,是多麼的友善。
8.關于繼承Mapper
我一開始為什麼要設計為必須繼承Mapper實作自己的Mapper呢?
主要考慮到兩個方面。
1.通過可以友善的擷取泛型的類型,在通用的方法中就不需要傳遞實體類型。
2.通過繼承的Mapper,例如Country2Mapper,有獨立的Mapper就意味着有獨立的命名空間,可以緩存結果,并且不需要攔截器就能實作。
現在有了Spring4後,又有了一個很重要的原因。
支援泛型注入,可以實作自己的通用Service,在通用Mapper基礎上再次簡化操作,加快開發效率。
9.最後
如果之前說通用Mapper不如Mybatis-Generator自動生成好,我也隻能說看個人喜好,不需要通用Mapper的可以不用,通用Mapper隻是為了滿足一部分的人需要。
現在來看,如果還有人說通用Mapper不如Mybatis-Generator自動生成好,我會建議他看看這篇文檔
實際上,不需要說那個更好,适合自己的才好。
另外看完這篇文檔後,不需要再說通用Mapper不如Mybatis-Generator自動生成好,因為我和一些朋友正在翻譯Mybatis-Generator,最後還會提供Mybatis-Generator和通用Mapper的內建插件,可以用Mybatis-Generator直接生成實體類、繼承通用Mapper的實體Mapper以及XML檔案。
Mybatis-Generator中文文檔位址:http://generator.sturgeon.mopaas.com/
Mybatis-Generator官方英文位址:http://mybatis.github.io/generator/index.html
這個文檔還沒有翻譯完,而且譯者水準有限,如果發現翻譯錯誤或者不合适的地方,可以在下面的位址提ISSUE
送出ISSUE
上面這個位址隻是生成後的項目文檔位址,并不是我們直接用來翻譯的項目。