Element中checkbox繫結值為數字,字串問題
1、github官網:https://github.com/baomidou/mybatis-plus
作者:貪挽懶月
連結:https://www.jianshu.com/p/ceb1df475021
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
一、mybatis-plus簡介
二、spring整合mybatis-plus
三、mp的通用crud
四、全域性策略配置
五、條件構造器(EntityWrapper)
前言:
mybatis在持久層框架中還是比較火的,一般專案都是基於ssm。雖然mybatis可以直接在xml中通過SQL語句操作資料庫,很是靈活。但正其操作都要通過SQL語句進行,就必須寫大量的xml檔案,很是麻煩。mybatis-plus就很好的解決了這個問題。
一、mybatis-plus簡介 <--返回目錄
Mybatis-Plus(簡稱MP)是一個 Mybatis 的增強工具,在 Mybatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。這是官方給的定義,關於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注意:這些是核心依賴,本專案還用到了mysql驅動、c3p0、日誌(slf4j-api,slf4j-log4j2)、lombok。整合mybatis-plus要把mybatis、mybatis-spring去掉,避免衝突;lombok是一個工具,添加了這個依賴,開發工具再安裝Lombok外掛,就可以使用它了,最常用的用法就是在實體類中使用它的@Data註解,這樣實體類就不用寫set、get、toString等方法了。關於Lombok的更多用法,請自行百度。 2、log4j.xml:> <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>
<?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:///資料庫名?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、配置資料庫相關引數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; //若沒有開啟駝峰命名,或者表中列名不符合駝峰規則,可通過該註解指定資料庫表中的列名,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的,然後實體類中新增
@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,實現tb_employee 表的 CRUD 操作我們需要做什麼呢?
基於 Mybatis:
需要編寫 EmployeeMapper 介面,並在 EmployeeMapper.xml 對映檔案中手動編寫 CRUD 方法對應的sql語句。
基於 MP:
只需要建立 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("[email protected]"); employee.setGender(1); employee.setAge(20); emplopyeeDao.insert(employee); //mybatisplus會自動把當前插入物件在資料庫中的id寫回到該實體中 System.out.println(employee.getId()); } }
執行新增操作,直接呼叫insert方法傳入實體即可。
2、update操作:
@Test public void testUpdate(){ Employee employee = new Employee(); employee.setId(1); employee.setLastName("更新測試"); //emplopyeeDao.updateById(employee);//根據id進行更新,沒有傳值的屬性就不會更新 emplopyeeDao.updateAllColumnById(employee);//根據id進行更新,沒傳值的屬性就更新為null }
注:注意這兩個update操作的區別,updateById
方法,沒有傳值的欄位不會進行更新,比如只傳入了lastName,那麼age、gender等屬性就會保留原來的值;updateAllColumnById
方法,顧名思義,會更新所有的列,沒有傳值的列會更新為null。
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語句就是where id = 1 and last_name = 更新測試
,若是符合這個條件的記錄不止一條,那麼就會報錯。
(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,資料表中欄位為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集合中,然後呼叫selectBatchIds方法,傳入該list集合即可,該方法返回的是對應id的所有記錄,所有返回值也是用list接收。
(5)、分頁查詢:
List<Employee> employees = emplopyeeDao.selectPage(new Page<>(1,2),null); System.out.println(employees);
注:selectPage方法就是分頁查詢,在page中傳入分頁資訊,後者為null的分頁條件,這裡先讓其為null,講了條件構造器再說其用法。這個分頁其實並不是物理分頁,而是記憶體分頁。也就是說,查詢的時候並沒有limit語句。等配置了分頁外掛後才可以實現真正的分頁。
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即可。
四、全域性策略配置 <--返回目錄
通過上面的小案例我們可以發現,實體類需要加@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 個方法供使用, 可以極其方便的實現單一、批量、分頁等操作,極大的減少開發負擔。但是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 區別不大 .orNew() .like("email","a") );
注:未說分頁查詢,所以用selectList即可,用EntityWrapper的like方法進行模糊查詢,like方法就是指column的值包含value值,此處like方法就是查詢last_name中包含“老師”字樣的記錄;“或者”用or或者orNew方法表示,這兩個方法區別不大,用哪個都可以,可以通過控制檯的sql語句自行感受其區別。
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語句就變為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的區別就是,建立條件構造器時,EntityWrapper是new出來的,而Condition是調create方法創建出來。
5、根據條件更新:
@Test public void testEntityWrapperUpdate(){ Employee employee = new Employee(); employee.setLastName("蒼老師"); employee.setEmail("[email protected]"); 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的所有使用者刪除。
總結:
以上便是mybatis-plus的入門教程,介紹了其如何與spring整合、通用crud的使用、全域性策略的配置以及條件構造器的使用,但是這並不是MP的所有內容,其強大不限於此。避免篇幅過長,想了解mybatis-plus的更多用法請參考《mybatis-plus的使用 ------ 進階》,同時在文末會給出案例的原始碼。