前言:mybatis在持久層框架中還是比較火的,一般項目都是基于ssm。雖然mybatis可以直接在xml中通過SQL語句操作數據庫,很是靈活。但正其操作都要通過SQL語句進行,就必須寫大量的xml文件,很是麻煩。mybatis-plus就很好的解決了這個問題。 一、mybatis-plus簡介:Mybatis-Plus(簡稱MP)是一個 Mybatis 的增強工具,在 Mybatis 的基礎上只做增強不做改變,為簡化開發(fā)、提高效率而生。這是官方給的定義,關于mybatis-plus的更多介紹及特性,可以參考mybatis-plus官網。那么它是怎么增強的呢?其實就是它已經封裝好了一些crud方法,我們不需要再寫xml了,直接調用這些方法就行,就類似于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./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-ddHH: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.Driverjdbc.url=jdbc:mysql:///數據庫名?useUnicode=true&characterEncoding=utf8jdbc.username=#jdbc.password=# 4、mybatis-config.xml: <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-////DTD Config 3.0//EN""http:///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./schema/beans" xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns:p="http://www./schema/p" xmlns:aop="http://www./schema/aop" xmlns:context="http://www./schema/context" xmlns:jee="http://www./schema/jee" xmlns:tx="http://www./schema/tx" xsi:schemaLocation=" http://www./schema/aop http://www./schema/aop/spring-aop-4.0.xsd http://www./schema/beans http://www./schema/beans/spring-beans-4.0.xsd http://www./schema/context http://www./schema/context/spring-context-4.0.xsd http://www./schema/jee http://www./schema/jee/spring-jee-4.0.xsd http://www./schema/tx http://www./schema/tx/spring-tx-4.0.xsd"> <!-- 配置整合mybatis-plus過程 --> <!-- 1、配置數據庫相關參數properties的屬性:${url} --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 2、配置數據庫連接池 --> <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與數據庫主鍵列名一致,若實體類屬性名與表主鍵列名一致可省略value @TableId(value = "id",type = IdType.AUTO)//指定自增策略 private Integer id; //若沒有開啟駝峰命名,或者表中列名不符合駝峰規(guī)則,可通過該注解指定數據庫表中的列名,exist標明數據表中有沒有對應列 @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的,然后實體類中添加 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:需求:存在一張 tbemployee 表,且已有對應的實體類 Employee,實現tbemployee 表的 CRUD 操作我們需要做什么呢? 基于 Mybatis:需要編寫 EmployeeMapper 接口,并在 EmployeeMapper.xml 映射文件中手動編寫 CRUD 方法對應的sql語句。 基于 MP:只需要創(chuàng)建 EmployeeMapper 接口, 并繼承 BaseMapper 接口。 我們已經有了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會自動把當前插入對象在數據庫中的id寫回到該實體中 System.out.println(employee.getId()); }} 執(zhí)行添加操作,直接調用insert方法傳入實體即可。 2、update操作: @Testpublic void testUpdate(){ Employee employee = new Employee(); employee.setId(1); employee.setLastName("更新測試"); //emplopyeeDao.updateById(employee);//根據id進行更新,沒有傳值的屬性就不會更新 emplopyeeDao.updateAllColumnById(employee);//根據id進行更新,沒傳值的屬性就更新為null} 注:注意這兩個update操作的區(qū)別, 3、select操作: (1)、根據id查詢: Employee employee = emplopyeeDao.selectById(1); (2)、根據條件查詢一條數據: Employee employeeCondition = new Employee();employeeCondition.setId(1);employeeCondition.setLastName("更新測試");//若是數據庫中符合傳入的條件的記錄有多條,那就不能用這個方法,會報錯Employee employee = emplopyeeDao.selectOne(employeeCondition); 注:這個方法的sql語句就是 (3)、根據查詢條件返回多條數據: 當符合指定條件的記錄數有多條時,上面那個方法就會報錯,就應該用這個方法。 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,寫的是數據表中的列名,而非實體類的屬性名。比如屬性名為lastName,數據表中字段為lastname,這里應該寫的是lastname。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集合中,然后調用selectBatchIds方法,傳入該list集合即可,該方法返回的是對應id的所有記錄,所有返回值也是用list接收。 (5)、分頁查詢: List<Employee> employees = emplopyeeDao.selectPage(new Page<>(1,2),null);System.out.println(employees); 注:selectPage方法就是分頁查詢,在page中傳入分頁信息,后者為null的分頁條件,這里先讓其為null,講了條件構造器再說其用法。這個分頁其實并不是物理分頁,而是內存分頁。也就是說,查詢的時候并沒有l(wèi)imit語句。等配置了分頁插件后才可以實現真正的分頁。 4、delete操作: (1)、根據id刪除: emplopyeeDao.deleteById(1); (2)、根據條件刪除: Map<String,Object> columnMap = new HashMap<>();columnMap.put("gender",0);columnMap.put("age",18);emplopyeeDao.deleteByMap(columnMap); 注:該方法與selectByMap類似,將條件封裝在columnMap中,然后調用deleteByMap方法,傳入columnMap即可,返回值是Integer類型,表示影響的行數。 (3)、根據id批量刪除: List<Integer> idList = new ArrayList<>(); idList.add(1); idList.add(2); emplopyeeDao.deleteBatchIds(idList); 注:該方法和selectBatchIds類似,把需要刪除的記錄的id裝進idList,然后調用deleteBatchIds,傳入idList即可。 四、全局策略配置:通過上面的小案例我們可以發(fā)現,實體類需要加@TableName注解指定數據庫表名,通過@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 即可實現大部分單表 CRUD 操作。BaseMapper 提供了多達 17 個方法供使用, 可以極其方便的實現單一、批量、分頁等操作,極大的減少開發(fā)負擔。但是mybatis-plus的強大不限于此,請看如下需求該如何處理: 需求:我們需要分頁查詢 tb_employee 表中,年齡在 18~50 之間性別為男且姓名為 xx 的所有用戶,這時候我們該如何實現上述需求呢? 使用MyBatis : 需要在 SQL 映射文件中編寫帶條件查詢的 SQL,并用PageHelper 插件完成分頁. 實現以上一個簡單的需求,往往需要我們做很多重復單調的工作。 使用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對象,調用該對象的相關方法即可。between方法三個參數,分別是column、value1、value2,該方法表示column的值要在value1和value2之間;eq是equals的簡寫,該方法兩個參數,column和value,表示column的值和value要相等。注意column是數據表對應的字段,而非實體類屬性字段。 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,根據age排序,簡單分頁: List<Employee> employees = emplopyeeDao.selectList( new EntityWrapper<Employee>() .eq("gender",0) .orderBy("age")//直接orderby 是升序,asc .last("desc limit 1,3")//在sql語句后面追加last里面的內容(改為降序,同時分頁)); 注:簡單分頁是指不用page對象進行分頁。orderBy方法就是根據傳入的column進行升序排序,若要降序,可以使用orderByDesc方法,也可以如案例中所示用last方法;last方法就是將last方法里面的value值追加到sql語句的后面,在該案例中,最后的sql語句就變?yōu)? 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是調create方法創(chuàng)建出來。 5、根據條件更新: @Testpublic 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、根據條件刪除: emplopyeeDao.delete( new EntityWrapper<Employee>() .eq("last_name","tom") .eq("age",16)); 注:該案例表示把last_name為tom、age為16的所有用戶刪除。 |
|