在Spring4中使用通用Mapper

在Spring4中使用通用Mapper

Spring4增長了對泛型注入的支持,這個特性對通用Mapper來講,很是的有用,能夠說有了這個特性,能夠直接在Service中寫Mapper<UserInfo> mapper,能夠經過BaseService<T>來實現通用的Servicehtml

這篇文檔主要講解通用Mapper在Spring4中的**最佳用法**。java

1、在Spring4中配置通用Mapper

和其餘裏面配置的區別就是在Spring4中能夠配置通用Mapper這個類,咱們能夠把通用Mapper中提供的Mapper<T>配置到Spring中,若是你有本身實現的通用Mapper,也能夠這麼配置:git

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.isea533.mybatis.mapper,com.isea533.mybatis.mapperhelper"/>
</bean>

這裏在配置basePackage的時候,將通用Mapper<T>所在的包com.isea533.mybatis.mapperhelper也配置上了。這樣就能在Spring4中直接注入Mapper<T>github

另外就是通用Mapper自身的配置:spring

<bean class="com.isea533.mybatis.mapperhelper.MapperHelper"
        depends-on="sqlSession" init-method="initMapper" scope="singleton" lazy-init="false">
    <property name="mappers">
        <array>
            <value>com.isea533.mybatis.mapperhelper.Mapper</value>
        </array>
    </property>
    <property name="sqlSessions" ref="sqlSession"/>
</bean>

這裏的配置和Spring3沒什麼區別,另外須要保證有sqlSession,能夠按以下配置:sql

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
    <constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>

其餘的配置按照一般的方法進行配置便可,沒有特殊的地方,若是有人不明白完整的配置什麼樣,能夠看下面的例子:數據庫

2、繼承Mapper<T>實現本身的實體接口類

這裏以Country2Mapper爲例:app

public interface Country2Mapper extends Mapper<Country2> {
    //省略其餘本身增長的方法
}

若是你點進去上面的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

3、在Service中使用

在Service中的使用方式有不少種。

第一種、直接注入上面定義的Country2Mapper

@Service
public class DemoService {
    @Autowired
    private Country2Mapper mapper;

    public List<Country2> selectPage(int pageNum,int pageSize){
        PageHelper.startPage(pageNum, pageSize);
        //Spring4支持泛型注入
        return mapper.select(null);
    }
}

這種方式太常見,太普通,這裏很少解釋。

第二種、泛型注入

這種方式用的就不多了,可是Spring4支持泛型注入,所以在第一種的基礎上,咱們能夠寫出以下的代碼:

@Service
public class DemoService {
    @Autowired
    private Mapper<Country2> mapper;

    public List<Country2> selectPage(int pageNum,int pageSize){
        //這裏用到了分頁插件PageHelper
        PageHelper.startPage(pageNum, pageSize);
        //Spring4支持泛型注入
        return mapper.select(null);
    }
}

對於不瞭解泛型注入的,可能會不習慣Mapper<Country2> mapper這種寫法,實際上這麼寫的優點並不明顯。還不如第一種明確。

可是經過第二種,咱們能夠引出第三種,也可能會是很經常使用的通用Service。

第三種、通用Service

通常操做數據庫都在Service中進行,不可避免的就要寫出大量重複的CRUD方法,若是能有一個通用的Service,確定也會減小不少工做量。

這裏經過簡單擴展來說,更復雜的封裝,各位能夠根據本身的狀況動手實踐。

以下簡單例子:

@Service
public abstract class BaseService<T> {

    @Autowired
    protected Mapper<T> mapper;

    public int save(T entity){
        return mapper.insert(entity);
    }

    public int delete(T entity){
        return mapper.deleteByPrimaryKey(entity);
    }

    /**
     * 單表分頁查詢
     * 
     * @param pageNum
     * @param pageSize
     * @return
     */
    public List<T> selectPage(int pageNum,int pageSize){
        PageHelper.startPage(pageNum, pageSize);
        //Spring4支持泛型注入
        return mapper.select(null);
    }
}

建立如上所示的抽象類BaseService<T>,這裏封裝三個方法僅做爲簡單的例子。須要更復雜邏輯的能夠自行摸索。

而後修改剛纔的DemoService例子:

@Service
public class DemoService extends BaseService<Country2>{

}

因爲BaseService<T>封裝了單表的分頁插件,所以目前的DemoService中沒有任何代碼。

假如咱們要增長一個包含校驗的保存方法。添加以下代碼:

@Service
public class DemoService extends BaseService<Country2>{

    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的時候,是多麼的方便。

關於繼承Mapper<T>

我一開始爲何要設計爲必須繼承Mapper<T>實現本身的Mapper呢?

主要考慮到兩個方面。

  1. 經過<T>能夠方便的獲取泛型的類型,在通用的方法中就不須要傳遞實體類型。

  2. 經過繼承的Mapper,例如Country2Mapper,有獨立的Mapper就意味着有獨立的命名空間,能夠緩存結果,而且不須要攔截器就能實現。

如今有了Spring4後,又有了一個很重要的緣由。

  • 支持泛型注入,能夠實現本身的通用Service,在通用Mapper基礎上再次簡化操做,加快開發效率。

最後

若是以前說通用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

上面這個地址只是生成後的項目文檔地址,並非咱們直接用來翻譯的項目。

相關文章
相關標籤/搜索