1. 程式人生 > 實用技巧 >解放雙手,不寫SQL!一個開源mybatis神器

解放雙手,不寫SQL!一個開源mybatis神器

什麼是通用 Mapper?

它是一個可以方便的使用 Mybatis 進行單表的增刪改查優秀開源產品。它使用攔截器來實現具體的執行 Sql,完全使用原生的 Mybatis 進行操作。在 Github 上標星 5.9K!

為什麼要用 Mapper?

它提供了所有單表的基本增刪改查方法,大大節省了我們書寫基本 mapper.xml 的時間。尤其對於新工程和新表來說,極大的提高...

不客氣的說,使用這個通用 Mapper 甚至能改變你對 Mybatis 單表基礎操作不方便的想法,使用它你能簡單的使用單表的增刪改查,包含動態的增刪改查。

同時,在程式碼結構合理的前提下,更換 RDBMS 也無須修改 sql,只需修改部分配置即可實現。

如何使用 Mapper?

先通過 maven 引入 jar 包:

<dependency>  
    <groupId>tk.mybatis</groupId>  
    <artifactId>mapper</artifactId>  
    <version>x.x.x</version>  
</dependency>  

新增配置檔案:

配置方式分為 Java 編碼方式和 spring 整合方式。

Java 編碼方式

MapperHelper mapperHelper = new MapperHelper();  
//特殊配置  
Config config = new Config();//具體支援的引數看後面的文件  
config.setXXX(XXX);//設定配置  
mapperHelper.setConfig(config);// 註冊自己專案中使用的通用Mapper介面,這裡沒有預設值,必須手動註冊  
mapperHelper.registerMapper(Mapper.class);  
//配置完成後,執行下面的操作  
mapperHelper.processConfiguration(session.getConfiguration());  

2). 純Spring配置方式

<bean >  
    <property name="basePackage" value="com.isea533.mybatis.mapper"/>  
    <property name="properties">  
        <value>  
            mappers=tk.mybatis.mapper.common.Mapper        </value>  
    </property>  
</bean>  
 

你沒看錯,就是這麼配置的,注意這裡是 tk.mybatis.xxx, 和 MyBatis 的唯一區別就是 org. 改成了 tk.,方便修改和記憶。

通用 Mapper 的各項屬性通過 properties 屬性進行配置,如果預設配置就是一行 mappers=tk.mybatis.mapper.common.Mapper 時,可以不寫,就會變成:

<bean >  
    <property name="basePackage" value="com.isea533.mybatis.mapper"/>  
</bean> 

繼承通用 Mapper 介面(注意必須要加泛型):

@Repository  
public interface MaterialDao extends Mapper<MaterialMeta>,   
InsertUseGeneratedKeysMapperr<MaterialMeta> {}  

上圖示例繼承了Mapper和InsertUseGeneratedKeysMapper,則直接擁有了這2個介面的所有方法。

上圖中實體類的寫法示例:

@Table(name = "tb\_helpcenter\_material")  
public class MaterialMeta {  
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long id;  
    private String title;  
    private String tags;  
    private Long classificationId;  
    private String platform;  
    private String lecturerName;  
    // Setters&Getters  
}  

實體類的規則:

1. 表名預設使用類名, 駝峰轉下劃線 (只對大寫字母進行處理), 如 UserInfo 預設對應的表名為 user_info。

2. 表名可以使用 @Table(name = "tableName") 進行指定, 對不符合第一條預設規則的可以通過這種方式指定表名.

3. 欄位預設和 @Column 一樣, 都會作為表字段, 表字段預設為 Java 物件的 Field 名字駝峰轉下劃線形式.

4. 可以使用 @Column(name = "fieldName") 指定不符合第 3 條規則的欄位名

5. 使用 @Transient 註解可以忽略欄位, 新增該註解的欄位不會作為表字段使用.

6. 建議一定是有一個 @Id 註解作為主鍵的欄位, 可以有多個 @Id 註解的欄位作為聯合主鍵.

7. 預設情況下, 實體類中如果不存在包含 @Id 註解的欄位, 所有的欄位都會作為主鍵欄位進行使用 (這種效率極低).

8. 實體類可以繼承使用, 可以參考測試程式碼中的 tk.mybatis.mapper.model.UserLogin2 類.

9. 由於基本型別, 如 int 作為實體類欄位時會有預設值 0, 而且無法消除, 所以實體類中建議不要使用基本型別.

10.@NameStyle 註解,用來配置物件名 / 欄位和表名 / 欄位之間的轉換方式,該註解優先於全域性配置 style,可選值:

另外,建議實體類的所有 Field 全部使用裝箱類,不要使用基本型別。

id 欄位上的 @GeneratedValue 註解用來表示該表使用的主鍵策略型別。

使用 Mybatis-Generator 來生成實體類:

使用方法參見:http://ks.netease.com/blog?id=8920

關於主鍵策略

主鍵策略主要用於 insert 場景。通常情況下,可以不用設定表物件的主鍵策略。不設定時,預設會使用 JDBC 的 getGeneratedKeys 方法來取出由資料庫內部生成的主鍵。

你也可以以 @GeneratedValue(generator = “”) 的形式來指定主鍵策略命令。如:@GeneratedValue(strategy = GenerationType.IDENTITY

,generator = “select last_insert_id()”) 等。

同時,可以根據實際需要,在全域性配置中指定主鍵策略的執行 ORDER。

用 Mybatis-Generator 生成實體類,並建立一個繼承了 Mapper 介面的 dao 以後,還要寫什麼呢?

答案是不用了,可以直接用了

就像這樣:

MaterialMeta materialMeta = ReflectUtil.convertObj(MaterialMeta.class, material, false);  
materialMeta.setPlatform(platformStr);  
materialDao.insertSelective(materialMeta);  

還有這樣:

Example example = new Example(MaterialMeta.class);  
example.createCriteria().andEqualTo("classificationId", material.getClassificationId()).andEqualTo("deleted",false);  
  
example.orderBy("sort").desc();  
PageHelper.startPage(1, 1);  
List<MaterialMeta> materialMetas = materialDao.selectByExample(example);  

或者這樣:

materialMeta.setStatus(MaterialStatus.online);  
materialMeta.setPublishDate(new Date());  
materialDao.updateByPrimaryKeySelective(materialMeta);  

如此一來,一行 sql 都不需要寫,mapper.xml 檔案也不需要了(特殊 sql 仍然需要手寫)

只是引入了原生的 Mapper 嗎?有沒有什麼缺陷?我們做了什麼改動?

fork 的 Mapper 版本是 3.4.2 的,最新 3.4.3 還沒有 release。

像這樣的通用框架,幾乎支援了市面上所有主流的 rdbms,但是大網易的 DDB 就呵呵噠了。

腫麼辦呢,當然是改啦。主要的問題是主鍵策略不支援。於是題主就給她新增了一種逐漸策略,名字就叫 “DDB”。同樣是通過攔截器修改 mybatis 的 Configuration 實現的。

同時新增了一個支援 DDB 批量 Insert 的 Mapper,使用全域性替換符的形式實現。

在對原生的 Mapper 做了這 2 個增強以後,就可以愉快的支援 DDB 的增刪改查了。

使用時,請引入以下 jar 包:

<dependency>  
<groupId>com.netease.pop.mybatis</groupId>  
<artifactId>mapper</artifactId>  
<version>4.0.0</version>  
</dependency>  

同時,在配置檔案中增加如下 2 行:

INDENTITY=DDB 表示使用名稱為 DDB 的主鍵策略 (或者也可以在實體類的 GeneratedValue 註解中指定 generator 命令)

ORDER=BEFORE 表示在 insert 命令前執行該主鍵策略 (這是為了在 insert 前獲取主鍵 id 值來使用)

其他

除了節省書寫 sql 的時間外,配合另一個分頁的開源外掛 PageHelper 使用,可以事半功倍。使用上簡單到可怕。

用法示例如下:

PageHelper.offsetPage(offset, limit);  
Page<MaterialMeta> metas = (Page<MaterialMeta>) materialDao.selectByExample(example); 

沒錯,就只有這麼一行。。。

具體的接入方式可以參看以下文件:https://github.com/pagehelper/MybatisPageHelper/blob/master/README_zh.md

寫在最後

歡迎大家關注我的公眾號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裡面更新,整理的資料也會放在裡面。

覺得寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!