什么是通用 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相關文章,學習資料都會在里面更新,整理的資料也會放在里面。
覺得寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!