前言:
mybatis在持久層框架中還是比較火的治泥,一般項目都是基于ssm。雖然mybatis可以直接在xml中通過SQL語句操作數(shù)據(jù)庫,很是靈活。但正其操作都要通過SQL語句進行耙考,就必須寫大量的xml文件,很是麻煩潭兽。mybatis-plus就很好的解決了這個問題倦始。
一、mybatis-plus簡介:
Mybatis-Plus(簡稱MP)是一個 Mybatis 的增強工具山卦,在 Mybatis 的基礎(chǔ)上只做增強不做改變鞋邑,為簡化開發(fā)诵次、提高效率而生。這是官方給的定義枚碗,關(guān)于mybatis-plus的更多介紹及特性逾一,可以參考mybatis-plus官網(wǎng)。那么它是怎么增強的呢肮雨?其實就是它已經(jīng)封裝好了一些crud方法遵堵,我們不需要再寫xml了,直接調(diào)用這些方法就行怨规,就類似于JPA陌宿。
二、spring整合mybatis-plus:
正如官方所說波丰,mybatis-plus在mybatis的基礎(chǔ)上只做增強不做改變壳坪,因此其與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驅(qū)動霜瘪、c3p0、日志(slf4j-api惧磺,slf4j-log4j2)颖对、lombok。集成mybatis-plus要把mybatis磨隘、mybatis-spring去掉缤底,避免沖突;lombok是一個工具番捂,添加了這個依賴个唧,開發(fā)工具再安裝Lombok插件,就可以使用它了设预,最常用的用法就是在實體類中使用它的@Data注解徙歼,這樣實體類就不用寫set、get鳖枕、toString等方法了魄梯。關(guān)于Lombok的更多用法存皂,請自行百度淤击。
2、log4j.xml:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configurationxmlns:log4j="http://jakarta.apache.org/log4j/"><appendername="STDOUT"class="org.apache.log4j.ConsoleAppender"><paramname="Encoding"value="UTF-8"/><layoutclass="org.apache.log4j.PatternLayout"><paramname="ConversionPattern"value="%-5p %d{MM-ddHH:mm:ss,SSS} %m (%F:%L) \n"/></layout></appender><loggername="java.sql"><levelvalue="debug"/></logger><loggername="org.apache.ibatis"><levelvalue="info"/></logger><root><levelvalue="debug"/><appender-refref="STDOUT"/></root></log4j:configuration>
3嵌言、jdbc.properties:
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql:///數(shù)據(jù)庫名?useUnicode=true&characterEncoding=utf8jdbc.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"?><beansxmlns="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ù)庫相關(guān)參數(shù)properties的屬性:${url} --><context:property-placeholderlocation="classpath:jdbc.properties"/><!-- 2、配置數(shù)據(jù)庫連接池 --><beanid="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource"><propertyname="driverClass"value="${jdbc.driver}"/><propertyname="jdbcUrl"value="${jdbc.url}"/><propertyname="user"value="${jdbc.username}"/><propertyname="password"value="${jdbc.password}"/></bean><!-- mybatis的sqlsessionFactorybean:org.mybatis.spring.SqlSessionFactoryBean--><!-- 3退客、配置mybatis-plus的sqlSessionFactory --><beanid="sqlSessionFactory"class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"><propertyname="dataSource"ref="dataSource"/><propertyname="configLocation"value="classpath:mybatis-config.xml"/><propertyname="typeAliasesPackage"value="com.zhu.mybatisplus.entity"/></bean><!-- 4唱矛、DAO接口所在包名,Spring會自動查找其下的類 --><beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer"><propertyname="basePackage"value="com.zhu.mybatisplus.dao"/><propertyname="sqlSessionFactoryBeanName"value="sqlSessionFactory"/></bean></beans>
6井辜、entity:
@Data@TableName(value="tb_employee")//指定表名publicclassEmployee{//value與數(shù)據(jù)庫主鍵列名一致,若實體類屬性名與表主鍵列名一致可省略value@TableId(value="id",type=IdType.AUTO)//指定自增策略privateInteger id;//若沒有開啟駝峰命名管闷,或者表中列名不符合駝峰規(guī)則粥脚,可通過該注解指定數(shù)據(jù)庫表中的列名,exist標(biāo)明數(shù)據(jù)表中有沒有對應(yīng)列@TableField(value="last_name",exist=true)privateString lastName;privateString email;privateInteger gender;privateInteger age;}
7包个、mapper:
publicinterfaceEmplopyeeDaoextendsBaseMapper<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"})publicclasstest{@AutowiredprivateDataSourcedataSource;@TestpublicvoidtestDataSource()throwsSQLException{System.out.println(dataSource.getConnection());}}
運行該junit,可輸出獲取到的連接熄驼,說明整合沒問題:
image.png
本文所有代碼本人均親自測試過像寒,本文涉及代碼又較多,為了不影響篇幅瓜贾,故非必要處不再截圖诺祸。接下來的所有操作都是基于此整合好的項目。
三祭芦、mp的通用crud:
需求:
存在一張 tb_employee 表筷笨,且已有對應(yīng)的實體類 Employee,實現(xiàn)tb_employee 表的 CRUD 操作我們需要做什么呢龟劲?
基于 Mybatis:
需要編寫 EmployeeMapper 接口胃夏,并在 EmployeeMapper.xml 映射文件中手動編寫 CRUD 方法對應(yīng)的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"})publicclasstest{@AutowiredprivateEmplopyeeDaoemplopyeeDao;@TestpublicvoidtestInsert(){Employeeemployee=newEmployee();employee.setLastName("東方不敗");employee.setEmail("dfbb@163.com");employee.setGender(1);employee.setAge(20);emplopyeeDao.insert(employee);//mybatisplus會自動把當(dāng)前插入對象在數(shù)據(jù)庫中的id寫回到該實體中System.out.println(employee.getId());}}
執(zhí)行添加操作,直接調(diào)用insert方法傳入實體即可亥宿。
2卸勺、update操作:
@TestpublicvoidtestUpdate(){Employeeemployee=newEmployee();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=newEmployee();employeeCondition.setId(1);employeeCondition.setLastName("更新測試");//若是數(shù)據(jù)庫中符合傳入的條件的記錄有多條,那就不能用這個方法焚挠,會報錯Employee employee=emplopyeeDao.selectOne(employeeCondition);
注:這個方法的sql語句就是where id = 1 and last_name = 更新測試膏萧,若是符合這個條件的記錄不止一條,那么就會報錯蝌衔。
(3)向抢、根據(jù)查詢條件返回多條數(shù)據(jù):
當(dāng)符合指定條件的記錄數(shù)有多條時,上面那個方法就會報錯胚委,就應(yīng)該用這個方法挟鸠。
Map<String,Object>columnMap=newHashMap<>();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覆享,這里應(yīng)該寫的是last_name。selectByMap方法返回值用list集合接收营袜。
(4)撒顿、通過id批量查詢:
List<Integer>idList=newArrayList<>();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集合即可凤壁,該方法返回的是對應(yīng)id的所有記錄吩屹,所有返回值也是用list接收。
(5)拧抖、分頁查詢:
List<Employee>employees=emplopyeeDao.selectPage(newPage<>(1,2),null);System.out.println(employees);
注:selectPage方法就是分頁查詢煤搜,在page中傳入分頁信息,后者為null的分頁條件唧席,這里先讓其為null擦盾,講了條件構(gòu)造器再說其用法。這個分頁其實并不是物理分頁淌哟,而是內(nèi)存分頁迹卢。也就是說,查詢的時候并沒有l(wèi)imit語句徒仓。等配置了分頁插件后才可以實現(xiàn)真正的分頁腐碱。
4、delete操作:
(1)蓬衡、根據(jù)id刪除:
emplopyeeDao.deleteById(1);
(2)、根據(jù)條件刪除:
Map<String,Object>columnMap=newHashMap<>();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=newArrayList<>();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的全局策略配置 --><beanid="globalConfiguration"class="com.baomidou.mybatisplus.entity.GlobalConfiguration"><!-- 2.3版本后澳泵,駝峰命名默認(rèn)值就是true,所以可不配置 --><!--<property name="dbColumnUnderline" value="true"/>--><!-- 全局主鍵自增策略兼呵,0表示auto --><propertyname="idType"value="0"/><!-- 全局表前綴配置 --><propertyname="tablePrefix"value="tb_"/></bean>
這里配置了還沒用兔辅,還需要在sqlSessionFactory中注入配置才會生效腊敲。如下:
<!-- 3、配置mybatisplus的sqlSessionFactory --><beanid="sqlSessionFactory"class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean"><propertyname="dataSource"ref="dataSource"/><propertyname="configLocation"value="classpath:mybatis-config.xml"/><propertyname="typeAliasesPackage"value="com.zhu.mybatisplus.entity"/><!-- 注入全局配置 --><propertyname="globalConfig"ref="globalConfiguration"/></bean>
如此一來幢妄,實體類中的@TableName注解和@TableId注解就可以去掉了兔仰。
五、條件構(gòu)造器(EntityWrapper):
以上基本的 CRUD 操作蕉鸳,我們僅僅需要繼承一個 BaseMapper 即可實現(xiàn)大部分單表 CRUD 操作乎赴。BaseMapper 提供了多達 17 個方法供使用, 可以極其方便的實現(xiàn)單一、批量潮尝、分頁等操作榕吼,極大的減少開發(fā)負(fù)擔(dān)。但是mybatis-plus的強大不限于此勉失,請看如下需求該如何處理:
需求:
我們需要分頁查詢 tb_employee 表中羹蚣,年齡在 18~50 之間性別為男且姓名為 xx 的所有用戶,這時候我們該如何實現(xiàn)上述需求呢乱凿?
使用MyBatis :需要在 SQL 映射文件中編寫帶條件查詢的 SQL,并用PageHelper 插件完成分頁. 實現(xiàn)以上一個簡單的需求顽素,往往需要我們做很多重復(fù)單調(diào)的工作。
使用MP:依舊不用編寫 SQL 語句徒蟆,MP 提供了功能強大的條件構(gòu)造器 ------? EntityWrapper胁出。
接下來就直接看幾個案例體會EntityWrapper的使用。
1段审、分頁查詢年齡在18 - 50且gender為0全蝶、姓名為tom的用戶:
List<Employee>employees=emplopyeeDao.selectPage(newPage<Employee>(1,3),newEntityWrapper<Employee>().between("age",18,50).eq("gender",0).eq("last_name","tom"));
注:由此案例可知,分頁查詢和之前一樣寺枉,new 一個page對象傳入分頁信息即可抑淫。至于分頁條件,new 一個EntityWrapper對象姥闪,調(diào)用該對象的相關(guān)方法即可始苇。between方法三個參數(shù),分別是column筐喳、value1埂蕊、value2,該方法表示column的值要在value1和value2之間疏唾;eq是equals的簡寫蓄氧,該方法兩個參數(shù),column和value槐脏,表示column的值和value要相等喉童。注意column是數(shù)據(jù)表對應(yīng)的字段,而非實體類屬性字段。
2堂氯、查詢gender為0且名字中帶有老師蔑担、或者郵箱中帶有a的用戶:
List<Employee>employees=emplopyeeDao.selectList(newEntityWrapper<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(newEntityWrapper<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)閟elect ······ order by desc limit 1, 3檐迟,追加了desc limit 1,3所以可以進行降序排序和分頁补胚。
4、分頁查詢年齡在18 - 50且gender為0追迟、姓名為tom的用戶:
條件構(gòu)造器除了EntityWrapper溶其,還有Condition。用Condition來處理一下這個需求:
List<Employee>employees=emplopyeeDao.selectPage(newPage<Employee>(1,2),Condition.create().between("age",18,50).eq("gender","0"));
注:Condition和EntityWrapper的區(qū)別就是敦间,創(chuàng)建條件構(gòu)造器時瓶逃,EntityWrapper是new出來的,而Condition是調(diào)create方法創(chuàng)建出來廓块。
5厢绝、根據(jù)條件更新:
@TestpublicvoidtestEntityWrapperUpdate(){Employeeemployee=newEmployee();employee.setLastName("蒼老師");employee.setEmail("cjk@sina.com");employee.setGender(0);emplopyeeDao.update(employee,newEntityWrapper<Employee>().eq("last_name","tom").eq("age",25));}
注:該案例表示把last_name為tom,age為25的所有用戶的信息更新為employee中設(shè)置的信息带猴。
6昔汉、根據(jù)條件刪除:
emplopyeeDao.delete(newEntityWrapper<Employee>().eq("last_name","tom").eq("age",16));
注:該案例表示把last_name為tom、age為16的所有用戶刪除拴清。
總結(jié):
以上便是mybatis-plus的入門教程靶病,介紹了其如何與spring整合会通、通用crud的使用、全局策略的配置以及條件構(gòu)造器的使用娄周,但是這并不是MP的所有內(nèi)容涕侈,其強大不限于此。避免篇幅過長煤辨,想了解mybatis-plus的更多用法請參考《mybatis-plus的使用 ------ 進階》裳涛,同時在文末會給出案例的源碼。