一、MybatisPlus簡(jiǎn)介
1.1.簡(jiǎn)介
Mybatis-Plus(簡(jiǎn)稱MP)是一個(gè) Mybatis 的增強(qiáng)工具,在 Mybatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開發(fā)、提高效率而生。
1.2.文檔地址
1.3.MybatisPlus的特性
- 無(wú)侵入:Mybatis-Plus 在 Mybatis 的基礎(chǔ)上進(jìn)行擴(kuò)展,只做增強(qiáng)不做改變,引入 Mybatis-Plus 不會(huì)對(duì)您現(xiàn)有的 Mybatis 構(gòu)架產(chǎn)生任何影響,而且 MP 支持所有 Mybatis 原生的特性
- 依賴少:僅僅依賴 Mybatis 以及 Mybatis-Spring
-
損耗小:
啟動(dòng)即會(huì)自動(dòng)注入基本 CURD,性能基本無(wú)損耗,直接面向?qū)ο蟛僮?/code> - 預(yù)防Sql注入:內(nèi)置 Sql 注入剝離器,有效預(yù)防Sql注入攻擊
-
通用CRUD操作:
內(nèi)置通用 Mapper、通用 Service,僅僅通過(guò)少量配置即可實(shí)現(xiàn)單表大部分 CRUD 操作,更有強(qiáng)大的條件構(gòu)造器,滿足各類使用需求 - 多種主鍵策略:支持多達(dá)4種主鍵策略(內(nèi)含分布式唯一ID生成器),可自由配置,完美解決主鍵問題
- 支持熱加載:Mapper 對(duì)應(yīng)的 XML 支持熱加載,對(duì)于簡(jiǎn)單的 CRUD 操作,甚至可以無(wú) XML 啟動(dòng)
- 支持ActiveRecord:支持 ActiveRecord 形式調(diào)用,實(shí)體類只需繼承 Model 類即可實(shí)現(xiàn)基本 CRUD 操作
- 支持代碼生成:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來(lái)使用(P.S. 比 Mybatis 官方的 Generator 更加強(qiáng)大?。?/li>
- 支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 支持關(guān)鍵詞自動(dòng)轉(zhuǎn)義:支持?jǐn)?shù)據(jù)庫(kù)關(guān)鍵詞(order、key......)自動(dòng)轉(zhuǎn)義,還可自定義關(guān)鍵詞
- 內(nèi)置分頁(yè)插件:基于 Mybatis 物理分頁(yè),開發(fā)者無(wú)需關(guān)心具體操作,配置好插件之后,寫分頁(yè)等同于普通List查詢
-
內(nèi)置性能分析插件:
可輸出 Sql 語(yǔ)句以及其執(zhí)行時(shí)間,建議開發(fā)測(cè)試時(shí)啟用該功能,能有效解決慢查詢 - 內(nèi)置全局?jǐn)r截插件:提供全表 delete 、 update 操作智能分析阻斷,預(yù)防誤操作
二、集成MybatisPlus
2.1.Maven導(dǎo)入MybatisPlus依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.0-gamma</version>
</dependency>
2.2.修改sqpsessionFactoryBean
<!-- 配置SqlSessionFactoryBean
Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
-->
<!-- 配置sqlsessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 數(shù)據(jù)源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 別名處理 -->
<property name="typeAliasesPackage" value="com.luo.beans"></property>
</bean>
三、入門的Hello World
3.1.準(zhǔn)備數(shù)據(jù)表
DROP TABLE IF EXISTS `tbl_user`;
CREATE TABLE `tbl_user` (
`email` varchar(50) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`gender` char(255) DEFAULT NULL,
`user_name` varchar(255) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
INSERT INTO `tbl_user` VALUES ('243518985@qq.com', 24, '1', '羅康元 ', 1);
INSERT INTO `tbl_user` VALUES ('1835856@qq.com', 34, '2', '張三', 2);
INSERT INTO `tbl_user` VALUES ('323134435@163.com', 53, '1', '李四', 3);
INSERT INTO `tbl_user` VALUES ('345464566@qq.com', 43, '1', '王五', 4);
INSERT INTO `tbl_user` VALUES ('luokangyuansb@gmail.com', 45, '1', '趙六', 5);
3.2.準(zhǔn)備Java實(shí)體類
public class User {
private Integer id;
private String userName;
private String email;
private Integer gender;
private Integer age;
}
3.3.加入依賴的jar包
<dependencies>
<!-- mp依賴:mybatisPlus 會(huì)自動(dòng)的維護(hù)Mybatis 以及MyBatis-spring相關(guān)的依賴-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.3</version>
</dependency>
<!--junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- mysql -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
</dependencies>
3.5.mybatis-config.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
3.6.log4j.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
3.7.db.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong
jdbc.username=root
jdbc.password=jiamei@20141107.
3.8.applicationContext.xml文件
<!-- 數(shù)據(jù)源 -->
<context:property-placeholder location="classpath:db.properties" />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--事務(wù)管理器 -->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--基于注解的事務(wù)管理 -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager" />
<!-- 配置SqlSessionFactoryBean
Mybatis提供的: org.mybatis.spring.SqlSessionFactoryBean
MP提供的:com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean
-->
<!-- 配置sqlsessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 數(shù)據(jù)源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 別名處理 -->
<property name="typeAliasesPackage" value="com.luo.beans"></property>
</bean>
<!-- 配置mybatis掃描的mapper接口路徑-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.luo.mapper"></property>
</bean>
3.9.通用的CRUD操作
假設(shè)我們有一張user表,我們需要對(duì)這個(gè)表進(jìn)行增刪改查操作,如果說(shuō)沒有代碼生成的話,在mybatis我們需要編寫UserMapper接口,手寫CRUD方法,在UserMapper.xml文件中寫對(duì)應(yīng)的sql語(yǔ)句,但是,在MybatisPlus中,我們只需要?jiǎng)?chuàng)建UserMapper接口,繼承BaseMapper接口,就可以完成CRUD操作,甚至不需要?jiǎng)?chuàng)建SQl映射文件。
public interface UserMapper extends BaseMapper<User>{
}
然后,我們就寫一些基本的單元測(cè)試方法,測(cè)試我們的CRUD,來(lái)到我們的測(cè)試類中,如下:
public class TestMp {
private ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
private UserMapper userMapper = ioc.getBean("userMapper",UserMapper.class);
}
說(shuō)明:在測(cè)試類中我們將使用從SpringIOC容器中獲取的userMapper進(jìn)行CRUD一系列操作
保存一條數(shù)據(jù)userMapper.insert(user);
@Test
public void insert(){
User user = new User();
user.setUserName("luokangyuan");
user.setAge(66);
user.setEmail("2356775645@qq.com");
user.setGender(2);
Integer result = userMapper.insert(user);
System.out.println(result);
// 直接獲取插入數(shù)據(jù)返回的自增主鍵值
System.out.println(user.getId()+"======");
}
插入數(shù)據(jù)的方法有兩個(gè):insert和insertAllColumn,二者的執(zhí)行結(jié)果是一樣的,區(qū)別在于,前者會(huì)根據(jù)實(shí)體類的每一個(gè)屬性值進(jìn)行一個(gè)非空校驗(yàn),在插入的sql語(yǔ)句中不會(huì)出現(xiàn)實(shí)體類屬性為空的字段;
注意:在沒有使用全局配置之前,我們需要指定實(shí)體類對(duì)應(yīng)的數(shù)據(jù)庫(kù)表和主鍵生成策略
- 主鍵生成策略:
@TableId(type = IdType.AUTO,value = "id"),value屬性值當(dāng)實(shí)體類字段名和數(shù)據(jù)庫(kù)一致時(shí)可以不寫,這里的value指的是數(shù)據(jù)庫(kù)字段名稱,type的類型有以下幾種:- IdType.AUTO:數(shù)據(jù)庫(kù)ID自增
- IdType.INPUT:用戶輸入ID
- IdType.ID_WORKER:全局唯一ID,內(nèi)容為空自動(dòng)填充(默認(rèn)配置)
- IdType.UUID:全局唯一ID,內(nèi)容為空自動(dòng)填充
- 實(shí)體對(duì)應(yīng)表名注解:
@TableName(value = "tbl_user");指定當(dāng)前實(shí)體類對(duì)應(yīng)的數(shù)據(jù)庫(kù)表 - 數(shù)據(jù)庫(kù)字段映射名稱:
@TableField(value = "user_name"),當(dāng)禁止駝峰映射規(guī)則后可以使用 - 忽略插入到表的字段:
@ableField(exist = false),如下,數(shù)據(jù)庫(kù)沒有money這個(gè)字段,如果不忽略,那么插入就會(huì)報(bào)錯(cuò),找不到這個(gè)字段;
@TableField(exist = false)
private Double money;
更新一條數(shù)據(jù)
@Test
public void update(){
User user = new User();
user.setId(7);
user.setUserName("王八");
user.setAge(56);
//user.setEmail("2356775645@qq.com");
user.setGender(2);
Integer result = userMapper.updateById(user);
}
同理:更新方法也有兩個(gè)updateById和updateAllColumnById,前者會(huì)對(duì)實(shí)體類屬性名進(jìn)行非空校驗(yàn),為空的就不會(huì)出現(xiàn)在sql語(yǔ)句中,也就是不會(huì)更新原有數(shù)據(jù),后者是會(huì)更新所有列,如果實(shí)體類屬性值為空,則數(shù)據(jù)庫(kù)對(duì)應(yīng)字段名更新為null;
查詢一條數(shù)據(jù)
@Test
public void select(){
// 1.通過(guò)ID查詢一條數(shù)據(jù)
User user = userMapper.selectById(7);
// 2.通過(guò)多個(gè)列進(jìn)行查詢,如果查處的數(shù)據(jù)有多條就會(huì)報(bào)錯(cuò)
User u = new User();
u.setId(2);
u.setUserName("張三");
User user1 = userMapper.selectOne(u);
// 3.查詢符合多個(gè)ID的數(shù)據(jù),使用的是in關(guān)鍵字查詢
List<Integer> ids = new ArrayList<Integer>();
ids.add(3);
ids.add(4);
ids.add(5);
List<User> users = userMapper.selectBatchIds(ids);
// 4.通過(guò)封裝map條件,注意的是封裝的是列字段名,不是實(shí)體里屬性名,
// map中的key充當(dāng)sql中的條件名稱
Map<String,Object> maps = new HashMap<String, Object>();
maps.put("user_name","張三");
maps.put("age",347);
List<User> users1 = userMapper.selectByMap(maps);
// 5.分頁(yè)查詢方法,查看第二頁(yè),每頁(yè)2條數(shù)據(jù),在sql語(yǔ)句并沒有l(wèi)imit關(guān)鍵字
// 所以要實(shí)現(xiàn)物理分頁(yè),還需借助插件,例如mybatis的pageHepler或者M(jìn)ybatisPlus提供的分頁(yè)插件
List<User> users2 = userMapper.selectPage(new Page<User>(2, 2), null);
}
刪除一條數(shù)據(jù)
@Test
public void delete(){
// 1.根據(jù)ID刪除
Integer integer = userMapper.deleteById(8);
// 2.根據(jù)條件刪除,map中的key為列名,千萬(wàn)注意
Map<String ,Object> maps = new HashMap<String, Object>();
maps.put("age",66);
maps.put("gender",2);
Integer integer1 = userMapper.deleteByMap(maps);
// 3.根據(jù)ID批量刪除,使用in關(guān)鍵字
List<Integer> ids = new ArrayList<Integer>();
ids.add(5);
ids.add(7);
Integer integer2 = userMapper.deleteBatchIds(ids);
}
3.10.MybatisPlus全局配置
在前面的CRUD操作中,我們會(huì)使用直接注解指定主鍵生成策略和表名到實(shí)體類的映射,但是配置的僅僅會(huì)對(duì)當(dāng)前實(shí)體類起作用,所以,引入了全局配置,如下:
<!-- 定義MybatisPlus的全局策略配置-->
<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--映射數(shù)據(jù)庫(kù)下劃線字段名到數(shù)據(jù)庫(kù)實(shí)體類的駝峰命名的映射-->
<property name="dbColumnUnderline" value="true"></property>
<!-- 全局的主鍵策略 -->
<property name="idType" value="0"></property>
<!-- 全局的表前綴策略配置 -->
<property name="tablePrefix" value="tbl_"></property>
</bean>
然后,將MybatisPlus全局配置注入到sqlSessionFactoryBean中
<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>
3.11.mybatisPlusCRUD總結(jié)
在前面,我們實(shí)現(xiàn)了基本的CRUD操作,操作簡(jiǎn)單,僅僅只需繼承一個(gè)BaseMapper就可以完成,實(shí)現(xiàn)單一,批量,分頁(yè)等等一系列操作,很大的減少了開發(fā)負(fù)擔(dān),但這僅僅是Mybatisplus的冰山一角,當(dāng)我們需要多條件查詢的時(shí)候,就會(huì)使用到MybatisPlus中強(qiáng)大的條件構(gòu)造器EntityWrapper;
四、條件查詢
條件構(gòu)造器就是EntityWrapper,就是一個(gè)封裝查詢條件對(duì)象,讓開發(fā)者自由的定義查詢條件,主要用于sql的拼接,排序或者實(shí)體參數(shù)等;條件構(gòu)造器
注意:使用的參數(shù)是數(shù)據(jù)庫(kù)字段名稱,不是Java類屬性名
4.1.selectPage中的條件查詢
@Test
public void entityWrapperTedst(){
// 分頁(yè)查詢第一頁(yè),每頁(yè)2條記錄,年齡在41-53之間,genger為1,user_name為王五的用戶
List<User> users = userMapper.selectPage(new Page<User>(1, 2),
new EntityWrapper<User>()
.between("age", 41, 53)
.eq("gender",1)
.eq("user_name","王五")
);
}
4.2.模糊查詢和或查詢
@Test
public void selectListTest(){
List<User> users = userMapper.selectList(new EntityWrapper<User>()
.eq("gender", 1)
.like("user_name", "三")
.orNew()
.like("email", "5")
);
}
使用或條件查詢可以使用or()也可以使用orNew(),二者的區(qū)別在于sql中的條件部分不一樣,如下:
使用or()的sql語(yǔ)句
SELECT id AS id,user_name AS userName,email,gender,age FROM tbl_user WHERE (gender = ? AND user_name LIKE ? OR email LIKE ?)
使用orNew()的sql語(yǔ)句
SELECT id AS id,user_name AS userName,email,gender,age FROM tbl_user WHERE (gender = ? AND user_name LIKE ?) OR (email LIKE ?)
4.3.修改滿足條件的數(shù)據(jù)
@Test
public void updataByEntityWrapper(){
User user = new User();
user.setEmail("luokangyuan@sina,com");
user.setAge(24);
user.setUserName("四川麻醬");
Integer update = userMapper.update(user, new EntityWrapper<User>()
.eq("user_name","李四")
.eq("age",53)
);
}
4.4.刪除滿足條件的數(shù)據(jù)
@Test
public void deleteByEntityWrapper(){
userMapper.delete(new EntityWrapper<User>()
.eq("user_name","王八")
.eq("age",56)
);
}
4.5.條件查詢之Condition
Condition繼承了Wrapper類,另外,我們不需要再new一個(gè)Condition對(duì)象,直接調(diào)用condition類的靜態(tài)方法create就可以得到一個(gè)condition對(duì)象,然后使用wrapper的所有方法,簡(jiǎn)單使用如下:
@Test
public void testCondition(){
userMapper.selectPage(new Page<User>(1,2), Condition.create()
.between("age",45,56)
);
}
五、活動(dòng)記錄AR
Active Record(活動(dòng)記錄),簡(jiǎn)稱AR,是一種領(lǐng)域模型模式,特點(diǎn)就是一個(gè)模型類對(duì)應(yīng)關(guān)系型數(shù)據(jù)庫(kù)中的一個(gè)表,而模型類的一個(gè)實(shí)例對(duì)應(yīng)表中的一條記錄;
5.1.開啟AR模式
開啟AR模式的方法很簡(jiǎn)單,就是讓我們的實(shí)體類繼承Model類,并實(shí)現(xiàn)其抽象方法,指定主鍵即可,如下
public class User extends Model<User> {
@Override
protected Serializable pkVal() {
return id;
}
}
5.2.插入一條數(shù)據(jù)
@Test
public void insert(){
User user = new User();
user.setUserName("杉木");
user.setAge(25);
user.setEmail("shancnu@163.com");
user.setGender(1);
boolean rs = user.insert();
}
5.3.修改一條數(shù)據(jù)
@Test
public void update(){
User user = new User();
user.setUserName("杉木博客");
user.setAge(35);
user.setId(10);
boolean rs = user.updateById();
}
說(shuō)明:和通用的CRUD中的更新方法一樣,
updateAllColumnById()會(huì)更新所有列
5.4.查詢數(shù)據(jù)
@Test
public void select(){
User user = new User();
user.setId(2);
// 根據(jù)ID查詢一條數(shù)據(jù)
User user1 = user.selectById();
// 查詢所有的數(shù)據(jù)
List<User> users = user.selectAll();
// 根據(jù)條件查詢
List<User> usersList = user.selectList(new EntityWrapper<User>()
.like("user_name", "三"));
// 統(tǒng)計(jì)滿足條件的數(shù)據(jù)數(shù)量
int gender = user.selectCount(new EntityWrapper<User>().eq("gender", 1));
// 統(tǒng)計(jì)全表數(shù)量
int count = user.selectCount(null);
}
5.5.刪除一條數(shù)據(jù)
@Test
public void delete(){
User user = new User();
user.setId(7);
boolean rs = user.deleteById();
System.out.print(rs);
}
當(dāng)然,也可以根據(jù)條件刪除多條數(shù)據(jù),這里需要注意的是:當(dāng)刪除不存在的數(shù)據(jù)時(shí)候,返回的結(jié)果也是true;
// 刪除不存在邏輯屬于成功
public static boolean delBool(Integer result) {
return null != result && result >= 0;
}
5.6.分頁(yè)查詢數(shù)據(jù)
在前面的CRUD中的分頁(yè)查詢返回的是list數(shù)據(jù)集合,但是在AR中返回的卻是Page對(duì)象,如下
@Test
public void selectPage(){
User user = new User();
Page<User> userPage = user.selectPage(new Page<User>(1, 2),
new EntityWrapper<User>().like("user_name", "三"));
List<User> records = userPage.getRecords();
}
5.7.AR總結(jié)
AR提供的是一種更為快速的實(shí)現(xiàn)CRUD操作,本質(zhì)很是調(diào)用Mybatis對(duì)應(yīng)的方法,說(shuō)的簡(jiǎn)單一點(diǎn)就是語(yǔ)法糖;
糖雖然好吃,但是,不要管不住嘴;
六、代碼生成器
我們知道m(xù)ybatis有一個(gè)代碼生成器MBG,可以生成Java實(shí)體類mapper接口和映射文件,但是MybatisPlus卻更加強(qiáng)大,可以生成service和controller,可以配置實(shí)體類是否支持AR等,代碼生成器
說(shuō)明:建議數(shù)據(jù)庫(kù)表名和字段名采用駝峰命名方式,和實(shí)體來(lái)一致,可以避免在對(duì)應(yīng)實(shí)體類產(chǎn)生的性能損耗
6.1.導(dǎo)入依賴
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
說(shuō)明:MybatisPlus默認(rèn)使用的是velocity模版引
6.2.編寫配置類
@Test
public void testMbg(){
// 1.全局配置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setActiveRecord(true)// 是否開啟AR模式
.setAuthor("luokangyuan") // 指定作者
.setOutputDir("/Users/luokangyuan/Documents/project/mybatisdemo/src/main/java")
.setFileOverride(true) // 指定文件覆蓋
.setIdType(IdType.AUTO) // 設(shè)置主鍵自增策略
.setServiceImplName("%sService") // 設(shè)置生成的services接口的名字的首字母是否為I
.setBaseResultMap(true) // 基本的字段映射
.setBaseColumnList(true); // 基本的sql片段
// 2.配置數(shù)據(jù)源
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL) // 設(shè)置數(shù)據(jù)庫(kù)類型
.setDriverName("com.mysql.jdbc.Driver")
.setUrl("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong")
.setUsername("root")
.setPassword("jiamei@20141107.");
// 3.策略配置
StrategyConfig strategyConfig = new StrategyConfig();
strategyConfig.setCapitalMode(true) //全局大寫命名
.setDbColumnUnderline(true) // 指定表名和字段名是否使用了下劃線
.setNaming(NamingStrategy.underline_to_camel) // 數(shù)據(jù)庫(kù)字段下劃線轉(zhuǎn)駝峰命令策略
.setTablePrefix("tbl_") // 設(shè)置表前綴
.setInclude("tbl_dept","tbl_file"); // 設(shè)置需要生成的表
// 4.包名策略配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("com.luo") // 設(shè)置父包
.setMapper("mapper")
.setService("service")
.setController("controller")
.setEntity("beans")
.setXml("mapper");
// 5. 開始生成代碼
AutoGenerator autoGenerator = new AutoGenerator();
autoGenerator.setGlobalConfig(globalConfig)
.setDataSource(dataSourceConfig)
.setStrategy(strategyConfig)
.setPackageInfo(packageConfig);
autoGenerator.execute();
}
6.3.生成的service代碼查看
@Service
public class DeptService extends ServiceImpl<DeptMapper, Dept> implements IDeptService {
}
DeptService繼承了ServiceImpl,在ServiceImpl中就已經(jīng)注入了DeptMapper,所以,我們就不需要再次注入,在ServiceImpl中也幫我們提供了常用的CRUD方法,我們可以直接使用,
@Controller
@RequestMapping("/dept")
public class DeptController {
@Autowired
private IDeptService service;
public String select(){
service.selectList(null);
return null;
}
}
七、插件擴(kuò)展
7.1.注冊(cè)分頁(yè)插件
<bean id="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<!-- 數(shù)據(jù)源 -->
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 別名處理 -->
<property name="typeAliasesPackage" value="com.luo.beans"></property>
<!-- 注入全局MP策略配置 -->
<property name="globalConfig" ref="globalConfiguration"></property>
<property name="plugins">
<list>
<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>
</list>
</property>
</bean>
真正的分頁(yè)查詢
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
private UserMapper userMapper = ioc.getBean("userMapper",UserMapper.class);
@Test
public void testPage(){
Page<User> page = new Page<User>(1,4);
List<User> users = userMapper.selectPage(page,null);
page.setRecords(users);
System.out.print("總記錄數(shù)"+page.getTotal());
System.out.print("當(dāng)前頁(yè)碼"+page.getCurrent());
System.out.print("總頁(yè)碼"+page.getPages());
System.out.print("每頁(yè)記錄數(shù)"+page.getSize());
System.out.print("是否有前一頁(yè)"+page.hasPrevious());
System.out.print("是否有后一頁(yè)"+page.hasNext());
}
說(shuō)明:我們可以將分頁(yè)查詢的數(shù)據(jù)放在page對(duì)象中,返回前端一個(gè)page對(duì)象即可
7.2.執(zhí)行分析插件
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
<property name="stopProceed" value="true"></property>
</bean>
測(cè)試如下:
@Test
public void testDeltetAll(){
userMapper.delete(null);
}
sql分析插件只支持mysql5.6.3以上的版本,本質(zhì)就是通過(guò)sql分析命令Explain分析當(dāng)前的sql語(yǔ)句,根據(jù)結(jié)果集中的Extra列來(lái)斷定當(dāng)前是否全表操作;
7.3.性能分析插件
性能分析插件用于輸出每秒sql語(yǔ)句和其執(zhí)行時(shí)間,首先注冊(cè)插件,如下:
<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
<property name="format" value="true"></property>
</bean>
測(cè)試如下:
@Test
public void testPer(){
Dept dept = new Dept();
dept.setDeptName("開發(fā)部");
dept.setDeptCount("34");
dept.setDeptBegintime(new Date());
dept.insert();
}
結(jié)果如下:
Time:142 ms - ID:com.luo.mapper.DeptMapper.insert
Execute SQL:
INSERT
INTO
tbl_dept
( dept_count, dept_name, dept_beginTime )
VALUES
( '34', '開發(fā)部', '2018-08-26 23:09:17.293' )]
7.4.樂觀鎖插件
當(dāng)我們?cè)陂_發(fā)中,有時(shí)需要判斷,當(dāng)我們更新一條數(shù)據(jù)庫(kù)記錄時(shí),希望這條記錄沒有被別人更新,這個(gè)時(shí)候就可以使用樂觀鎖插件,他的原理就是,取出記錄時(shí),獲取當(dāng)前的version,更新的時(shí)候帶上這個(gè)version,執(zhí)行更新的時(shí)候set version = yourVersion+1 where version = yourVersion,如果version不對(duì),則更新失敗,注意的是:@version用于注解實(shí)體字段,必須要有;
首先,注冊(cè)插件
<bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"></bean>
實(shí)體類添加對(duì)應(yīng)屬性,同時(shí)數(shù)據(jù)庫(kù)表也要添加對(duì)應(yīng)字段
@Version
private Integer version;
測(cè)試如下:
@Test
public void testVersion(){
Dept dept = new Dept();
dept.setDeptName("測(cè)試部");
dept.setVersion(1);
dept.setId(1);
dept.updateById();
}
如果:這個(gè)時(shí)候?qū)?shù)據(jù)庫(kù)version改為2,在執(zhí)行更新就會(huì)顯示更新記錄數(shù)為0;
八、自定義全局操作
8.1.自定義全局實(shí)例
自定義全局操作,就是將我們需要的sql在項(xiàng)目啟動(dòng)的時(shí)候就注入到全局中,操作步驟如下:
- 在Mapper接口中定義我們需要注入的方法;
- 擴(kuò)展AutoSqlInjector中的inject方法,實(shí)現(xiàn)Mapper中我們自定義方法要注入的sql;
- 最后,在全局配置中,配置我們自定義的注入器即可;
第一步:mapper中定義方法
public interface UserMapper extends BaseMapper<User> {
int deleteAll();
}
第二步:重寫inject方法
public class MySqlInjector extends AutoSqlInjector {
@Override
public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
// 構(gòu)造sql語(yǔ)句
String sql = "delete from " + table.getTableName();
// 構(gòu)造方法名
String method = "deleteAll";
// 構(gòu)造SqlSource對(duì)象
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
// 構(gòu)造一個(gè)刪除的MapperStatement
this.addDeleteMappedStatement(mapperClass,method,sqlSource);
}
}?
第三步:注入自定義配置
<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--映射數(shù)據(jù)庫(kù)下劃線字段名到數(shù)據(jù)庫(kù)實(shí)體類的駝峰命名的映射-->
<property name="dbColumnUnderline" value="true"></property>
<!-- 全局的主鍵策略 -->
<property name="idType" value="0"></property>
<!-- 全局的表前綴策略配置 -->
<property name="tablePrefix" value="tbl_"></property>
<!--注入自定義全局操作-->
<property name="sqlInjector" ref="mySqlInjector"></property>
</bean>
<bean class="com.luo.injector.MySqlInjector" id="mySqlInjector"></bean>
測(cè)試
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
private UserMapper userMapper = ioc.getBean("userMapper",UserMapper.class);
@Test
public void testInject(){
int rs = userMapper.deleteAll();
}
8.2.邏輯刪除
所謂邏輯刪除,就是不真正的刪除數(shù)據(jù)的記錄,而是變?yōu)闊o(wú)效狀態(tài),在MybatisPlus中,給我們提供logicSqlInjector
第一步:數(shù)據(jù)庫(kù)添加邏輯字段
第二步:實(shí)體類添加對(duì)應(yīng)屬性和注解
@TableLogic
private Integer logicFlag;
第三步:MybatisPlus全局配置中加入logicSqlInjector
<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--映射數(shù)據(jù)庫(kù)下劃線字段名到數(shù)據(jù)庫(kù)實(shí)體類的駝峰命名的映射-->
<property name="dbColumnUnderline" value="true"></property>
<!-- 全局的主鍵策略 -->
<property name="idType" value="0"></property>
<!-- 全局的表前綴策略配置 -->
<property name="tablePrefix" value="tbl_"></property>
<!--注入自定義全局操作-->
<property ref="logicSqlInjector" name="sqlInjector"></property>
<!--注入邏輯刪除全局值-->
<property name="logicDeleteValue" value="-1"></property>
<property name="logicNotDeleteValue" value="1"></property>
</bean>
<!--邏輯刪除-->
<bean class="com.baomidou.mybatisplus.mapper.LogicSqlInjector" id="logicSqlInjector"></bean>
測(cè)試
@Test
public void testLogin(){
Integer integer = userMapper.deleteById(1);
}
說(shuō)明:我們做的是刪除操作,但是,執(zhí)行的卻是update操作,同時(shí),
查詢的時(shí)候自動(dòng)添加了有效判斷
九、公共字段填充
這里涉及到一個(gè)元數(shù)據(jù)處理接口MetaObjectHandler,元對(duì)象是Mybatis提供的一個(gè)用于更加方便,更加優(yōu)雅的訪問對(duì)象的屬性,給對(duì)象的屬性賦值的一個(gè)對(duì)象,本質(zhì)上metaObject獲取對(duì)象的值或者是給對(duì)象的屬性賦值,都是通過(guò)反射獲取到屬性對(duì)應(yīng)方法的Invoker;
9.1.使用實(shí)例
第一步:注解需要填充的字段
@TableField(value = "user_name",fill = FieldFill.INSERT_UPDATE)
private String userName;
第二步:自定義填充處理器
public class MetaHandler extends MetaObjectHandler {
/**
* 插入操作:自動(dòng)填充
* @param metaObject
*/
public void insertFill(MetaObject metaObject) {
// 獲取到需要被填充的字段值
Object userName = getFieldValByName("userName", metaObject);
if(userName == null){
setFieldValByName("userName","四川碼醬",metaObject);
}
}
/**
* 更新操作:自動(dòng)填充
* @param metaObject
*/
public void updateFill(MetaObject metaObject) {
// 獲取到需要被填充的字段值
Object userName = getFieldValByName("userName", metaObject);
if(userName == null){
setFieldValByName("userName","康哥哥",metaObject);
}
}
}
第三步:注入全局配置
<bean id ="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--映射數(shù)據(jù)庫(kù)下劃線字段名到數(shù)據(jù)庫(kù)實(shí)體類的駝峰命名的映射-->
<property name="dbColumnUnderline" value="true"></property>
<!-- 全局的主鍵策略 -->
<property name="idType" value="0"></property>
<!-- 全局的表前綴策略配置 -->
<property name="tablePrefix" value="tbl_"></property>
<!--注入自定義全局操作-->
<!--<property name="sqlInjector" ref="mySqlInjector"></property>-->
<property ref="logicSqlInjector" name="sqlInjector"></property>
<!--注入邏輯刪除全局值-->
<property name="logicDeleteValue" value="-1"></property>
<property name="logicNotDeleteValue" value="1"></property>
<!--注入公共字段填充處理器-->
<property name="metaObjectHandler" ref="metaHandler"></property>
</bean>
<!--自定義公共字段填充處理器-->
<bean class="com.luo.bandler.MetaHandler" id="metaHandler"></bean>
第四步:測(cè)試
@Test
public void testCom(){
User user = new User();
user.setId(11);
user.setLogicFlag(1);
user.updateById();
}
十、IEDA開發(fā)插件
10.1.安裝方法
打開IDEA設(shè)置--Plugins--Browse repositories --搜索mybatisx,安裝即可
10.2.支持的功能
根據(jù)mapper接口方法自動(dòng)生成xml文件,接口方法定位xml,xml自動(dòng)定位mapper接口;