前言:
mybatis在持久層框架中還是比較火的蛾找,一般項目都是基于ssm。雖然mybatis可以直接在xml中通過SQL語句操作數(shù)據(jù)庫颅湘,很是靈活吃引。但正其操作都要通過SQL語句進行,就必須寫大量的xml文件沿后,很是麻煩沿彭。mybatis-plus就很好的解決了這個問題。
歡迎大家關注我的公眾號 javawebkf尖滚,目前正在慢慢地將簡書文章搬到公眾號喉刘,以后簡書和公眾號文章將同步更新,且簡書上的付費文章在公眾號上將免費漆弄。
一睦裳、mybatis-plus簡介:
Mybatis-Plus(簡稱MP)是一個 Mybatis 的增強工具,在 Mybatis 的基礎上只做增強不做改變置逻,為簡化開發(fā)推沸、提高效率而生。這是官方給的定義,關于mybatis-plus的更多介紹及特性鬓催,可以參考mybatis-plus官網(wǎng)肺素。那么它是怎么增強的呢?其實就是它已經(jīng)封裝好了一些crud方法宇驾,我們不需要再寫xml了倍靡,直接調(diào)用這些方法就行,就類似于JPA课舍。
二塌西、spring整合mybatis-plus:
正如官方所說,mybatis-plus在mybatis的基礎上只做增強不做改變筝尾,因此其與spring的整合亦非常簡單捡需。只需把mybatis的依賴換成mybatis-plus的依賴,再把sqlSessionFactory換成mybatis-plus的即可筹淫。接下來看具體操作:
1站辉、pom.xml:
核心依賴如下:
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.14.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- mp 依賴 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.3</version>
</dependency>
注意:這些是核心依賴,本項目還用到了mysql驅動损姜、c3p0饰剥、日志(slf4j-api,slf4j-log4j2)摧阅、lombok汰蓉。集成mybatis-plus要把mybatis、mybatis-spring去掉棒卷,避免沖突顾孽;lombok是一個工具,添加了這個依賴娇跟,開發(fā)工具再安裝Lombok插件岩齿,就可以使用它了,最常用的用法就是在實體類中使用它的@Data注解苞俘,這樣實體類就不用寫set盹沈、get、toString等方法了吃谣。關于Lombok的更多用法乞封,請自行百度。
2岗憋、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肃晚、jdbc.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///數(shù)據(jù)庫名?useUnicode=true&characterEncoding=utf8
jdbc.username=#
jdbc.password=#
4、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>
注:因為是與spring整合仔戈,所有mybatis-plus的大部分都寫在spring的配置文件中关串,這里定義一個空的mybatis-config.xml即可拧廊。
5、spring-dao.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 配置整合mybatis-plus過程 -->
<!-- 1晋修、配置數(shù)據(jù)庫相關參數(shù)properties的屬性:${url} -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 2吧碾、配置數(shù)據(jù)庫連接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- mybatis的sqlsessionFactorybean:org.mybatis.spring.SqlSessionFactoryBean-->
<!-- 3、配置mybatis-plus的sqlSessionFactory -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="typeAliasesPackage" value="com.zhu.mybatisplus.entity"/>
</bean>
<!-- 4墓卦、DAO接口所在包名倦春,Spring會自動查找其下的類 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zhu.mybatisplus.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
6、entity:
@Data
@TableName(value = "tb_employee")//指定表名
public class Employee {
//value與數(shù)據(jù)庫主鍵列名一致落剪,若實體類屬性名與表主鍵列名一致可省略value
@TableId(value = "id",type = IdType.AUTO)//指定自增策略
private Integer id;
//若沒有開啟駝峰命名睁本,或者表中列名不符合駝峰規(guī)則,可通過該注解指定數(shù)據(jù)庫表中的列名忠怖,exist標明數(shù)據(jù)表中有沒有對應列
@TableField(value = "last_name",exist = true)
private String lastName;
private String email;
private Integer gender;
private Integer age;
}
7呢堰、mapper:
public interface EmplopyeeDao extends BaseMapper<Employee> {
}
這樣就完成了mybatis-plus與spring的整合。首先是把mybatis和mybatis-spring依賴換成mybatis-plus的依賴脑又,然后把sqlsessionfactory換成mybatis-plus的暮胧,然后實體類中添加@TableName
、@TableId
等注解问麸,最后mapper繼承BaseMapper
即可。
8钞翔、測試:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class test {
@Autowired
private DataSource dataSource;
@Test
public void testDataSource() throws SQLException {
System.out.println(dataSource.getConnection());
}
}
運行該junit严卖,可輸出獲取到的連接,說明整合沒問題:
本文所有代碼本人均親自測試過布轿,本文涉及代碼又較多哮笆,為了不影響篇幅,故非必要處不再截圖汰扭。接下來的所有操作都是基于此整合好的項目稠肘。
三、mp的通用crud:
需求:
存在一張 tb_employee 表萝毛,且已有對應的實體類 Employee项阴,實現(xiàn)tb_employee 表的 CRUD 操作我們需要做什么呢?
基于 Mybatis:
需要編寫 EmployeeMapper 接口笆包,并在 EmployeeMapper.xml 映射文件中手動編寫 CRUD 方法對應的sql語句环揽。
基于 MP:
只需要創(chuàng)建 EmployeeMapper 接口, 并繼承 BaseMapper 接口。
我們已經(jīng)有了Employee庵佣、tb_employee了歉胶,并且EmployeeDao也繼承了BaseMapper了,接下來就使用crud方法巴粪。
1通今、insert操作:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class test {
@Autowired
private EmplopyeeDao emplopyeeDao;
@Test
public void testInsert(){
Employee employee = new Employee();
employee.setLastName("東方不敗");
employee.setEmail("dfbb@163.com");
employee.setGender(1);
employee.setAge(20);
emplopyeeDao.insert(employee);
//mybatisplus會自動把當前插入對象在數(shù)據(jù)庫中的id寫回到該實體中
System.out.println(employee.getId());
}
}
執(zhí)行添加操作粥谬,直接調(diào)用insert方法傳入實體即可。
2辫塌、update操作:
@Test
public void testUpdate(){
Employee employee = new Employee();
employee.setId(1);
employee.setLastName("更新測試");
//emplopyeeDao.updateById(employee);//根據(jù)id進行更新帝嗡,沒有傳值的屬性就不會更新
emplopyeeDao.updateAllColumnById(employee);//根據(jù)id進行更新,沒傳值的屬性就更新為null
}
注:注意這兩個update操作的區(qū)別璃氢,updateById
方法哟玷,沒有傳值的字段不會進行更新,比如只傳入了lastName一也,那么age巢寡、gender等屬性就會保留原來的值;updateAllColumnById
方法椰苟,顧名思義抑月,會更新所有的列,沒有傳值的列會更新為null舆蝴。
3谦絮、select操作:
(1)、根據(jù)id查詢:
Employee employee = emplopyeeDao.selectById(1);
(2)洁仗、根據(jù)條件查詢一條數(shù)據(jù):
Employee employeeCondition = new Employee();
employeeCondition.setId(1);
employeeCondition.setLastName("更新測試");
//若是數(shù)據(jù)庫中符合傳入的條件的記錄有多條层皱,那就不能用這個方法,會報錯
Employee employee = emplopyeeDao.selectOne(employeeCondition);
注:這個方法的sql語句就是where id = 1 and last_name = 更新測試
赠潦,若是符合這個條件的記錄不止一條叫胖,那么就會報錯。
(3)她奥、根據(jù)查詢條件返回多條數(shù)據(jù):
當符合指定條件的記錄數(shù)有多條時瓮增,上面那個方法就會報錯,就應該用這個方法哩俭。
Map<String,Object> columnMap = new HashMap<>();
columnMap.put("last_name","東方不敗");//寫表中的列名
columnMap.put("gender","1");
List<Employee> employees = emplopyeeDao.selectByMap(columnMap);
System.out.println(employees.size());
注:查詢條件用map集合封裝绷跑,columnMap,寫的是數(shù)據(jù)表中的列名凡资,而非實體類的屬性名砸捏。比如屬性名為lastName,數(shù)據(jù)表中字段為last_name讳苦,這里應該寫的是last_name带膜。selectByMap方法返回值用list集合接收。
(4)鸳谜、通過id批量查詢:
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
idList.add(3);
List<Employee> employees = emplopyeeDao.selectBatchIds(idList);
System.out.println(employees);
注:把需要查詢的id都add到list集合中膝藕,然后調(diào)用selectBatchIds方法,傳入該list集合即可咐扭,該方法返回的是對應id的所有記錄芭挽,所有返回值也是用list接收滑废。
(5)、分頁查詢:
List<Employee> employees = emplopyeeDao.selectPage(new Page<>(1,2),null);
System.out.println(employees);
注:selectPage方法就是分頁查詢袜爪,在page中傳入分頁信息蠕趁,后者為null的分頁條件,這里先讓其為null辛馆,講了條件構造器再說其用法俺陋。這個分頁其實并不是物理分頁,而是內(nèi)存分頁昙篙。也就是說腊状,查詢的時候并沒有l(wèi)imit語句。等配置了分頁插件后才可以實現(xiàn)真正的分頁苔可。
4缴挖、delete操作:
(1)、根據(jù)id刪除:
emplopyeeDao.deleteById(1);
(2)焚辅、根據(jù)條件刪除:
Map<String,Object> columnMap = new HashMap<>();
columnMap.put("gender",0);
columnMap.put("age",18);
emplopyeeDao.deleteByMap(columnMap);
注:該方法與selectByMap類似映屋,將條件封裝在columnMap中,然后調(diào)用deleteByMap方法同蜻,傳入columnMap即可棚点,返回值是Integer類型,表示影響的行數(shù)埃仪。
(3)乙濒、根據(jù)id批量刪除:
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
emplopyeeDao.deleteBatchIds(idList);
注:該方法和selectBatchIds類似,把需要刪除的記錄的id裝進idList卵蛉,然后調(diào)用deleteBatchIds,傳入idList即可么库。
四傻丝、全局策略配置:
通過上面的小案例我們可以發(fā)現(xiàn),實體類需要加@TableName注解指定數(shù)據(jù)庫表名诉儒,通過@TableId注解指定id的增長策略葡缰。實體類少倒也無所謂,實體類一多的話也麻煩忱反。所以可以在spring-dao.xml的文件中進行全局策略配置泛释。
<!-- 5、mybatisplus的全局策略配置 -->
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!-- 2.3版本后温算,駝峰命名默認值就是true怜校,所以可不配置 -->
<!--<property name="dbColumnUnderline" value="true"/>-->
<!-- 全局主鍵自增策略,0表示auto -->
<property name="idType" value="0"/>
<!-- 全局表前綴配置 -->
<property name="tablePrefix" value="tb_"/>
</bean>
這里配置了還沒用注竿,還需要在sqlSessionFactory中注入配置才會生效茄茁。如下:
<!-- 3魂贬、配置mybatisplus的sqlSessionFactory -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="typeAliasesPackage" value="com.zhu.mybatisplus.entity"/>
<!-- 注入全局配置 -->
<property name="globalConfig" ref="globalConfiguration"/>
</bean>
如此一來,實體類中的@TableName注解和@TableId注解就可以去掉了裙顽。
五付燥、條件構造器(EntityWrapper):
以上基本的 CRUD 操作,我們僅僅需要繼承一個 BaseMapper 即可實現(xiàn)大部分單表 CRUD 操作愈犹。BaseMapper 提供了多達 17 個方法供使用, 可以極其方便的實現(xiàn)單一键科、批量、分頁等操作漩怎,極大的減少開發(fā)負擔勋颖。但是mybatis-plus的強大不限于此,請看如下需求該如何處理:
需求:
我們需要分頁查詢 tb_employee 表中扬卷,年齡在 18~50 之間性別為男且姓名為 xx 的所有用戶牙言,這時候我們該如何實現(xiàn)上述需求呢?
使用MyBatis : 需要在 SQL 映射文件中編寫帶條件查詢的 SQL,并用PageHelper 插件完成分頁. 實現(xiàn)以上一個簡單的需求怪得,往往需要我們做很多重復單調(diào)的工作咱枉。
使用MP: 依舊不用編寫 SQL 語句,MP 提供了功能強大的條件構造器 ------ EntityWrapper徒恋。
接下來就直接看幾個案例體會EntityWrapper的使用蚕断。
1、分頁查詢年齡在18 - 50且gender為0入挣、姓名為tom的用戶:
List<Employee> employees = emplopyeeDao.selectPage(new Page<Employee>(1,3),
new EntityWrapper<Employee>()
.between("age",18,50)
.eq("gender",0)
.eq("last_name","tom")
);
注:由此案例可知亿乳,分頁查詢和之前一樣,new 一個page對象傳入分頁信息即可径筏。至于分頁條件葛假,new 一個EntityWrapper對象,調(diào)用該對象的相關方法即可滋恬。between方法三個參數(shù)聊训,分別是column、value1恢氯、value2带斑,該方法表示column的值要在value1和value2之間;eq是equals的簡寫勋拟,該方法兩個參數(shù)勋磕,column和value,表示column的值和value要相等敢靡。注意column是數(shù)據(jù)表對應的字段挂滓,而非實體類屬性字段。
2醋安、查詢gender為0且名字中帶有老師杂彭、或者郵箱中帶有a的用戶:
List<Employee> employees = emplopyeeDao.selectList(
new EntityWrapper<Employee>()
.eq("gender",0)
.like("last_name","老師")
//.or()//和or new 區(qū)別不大
.orNew()
.like("email","a")
);
注:未說分頁查詢墓毒,所以用selectList即可,用EntityWrapper的like方法進行模糊查詢亲怠,like方法就是指column的值包含value值所计,此處like方法就是查詢last_name中包含“老師”字樣的記錄含潘;“或者”用or或者orNew方法表示痘系,這兩個方法區(qū)別不大,用哪個都可以疤苹,可以通過控制臺的sql語句自行感受其區(qū)別习勤。
3踪栋、查詢gender為0,根據(jù)age排序图毕,簡單分頁:
List<Employee> employees = emplopyeeDao.selectList(
new EntityWrapper<Employee>()
.eq("gender",0)
.orderBy("age")//直接orderby 是升序夷都,asc
.last("desc limit 1,3")//在sql語句后面追加last里面的內(nèi)容(改為降序,同時分頁)
);
注:簡單分頁是指不用page對象進行分頁予颤。orderBy方法就是根據(jù)傳入的column進行升序排序囤官,若要降序,可以使用orderByDesc方法蛤虐,也可以如案例中所示用last方法党饮;last方法就是將last方法里面的value值追加到sql語句的后面,在該案例中驳庭,最后的sql語句就變?yōu)?code>select ······ order by desc limit 1, 3刑顺,追加了desc limit 1,3
所以可以進行降序排序和分頁。
4饲常、分頁查詢年齡在18 - 50且gender為0蹲堂、姓名為tom的用戶:
條件構造器除了EntityWrapper,還有Condition贝淤。用Condition來處理一下這個需求:
List<Employee> employees = emplopyeeDao.selectPage(
new Page<Employee>(1,2),
Condition.create()
.between("age",18,50)
.eq("gender","0")
);
注:Condition和EntityWrapper的區(qū)別就是贯城,創(chuàng)建條件構造器時,EntityWrapper是new出來的霹娄,而Condition是調(diào)create方法創(chuàng)建出來。
5鲫骗、根據(jù)條件更新:
@Test
public void testEntityWrapperUpdate(){
Employee employee = new Employee();
employee.setLastName("蒼老師");
employee.setEmail("cjk@sina.com");
employee.setGender(0);
emplopyeeDao.update(employee,
new EntityWrapper<Employee>()
.eq("last_name","tom")
.eq("age",25)
);
}
注:該案例表示把last_name為tom犬耻,age為25的所有用戶的信息更新為employee中設置的信息。
6执泰、根據(jù)條件刪除:
emplopyeeDao.delete(
new EntityWrapper<Employee>()
.eq("last_name","tom")
.eq("age",16)
);
注:該案例表示把last_name為tom枕磁、age為16的所有用戶刪除。
總結:
以上便是mybatis-plus的入門教程术吝,介紹了其如何與spring整合计济、通用crud的使用茸苇、全局策略的配置以及條件構造器的使用,但是這并不是MP的所有內(nèi)容沦寂,其強大不限于此学密。避免篇幅過長,想了解mybatis-plus的更多用法請參考《mybatis-plus的使用 ------ 進階》传藏,同時在文末會給出案例的源碼腻暮。