您好,登錄后才能下訂單哦!
這篇文章主要介紹“mybatis-plus的使用方法”,在日常操作中,相信很多人在mybatis-plus的使用方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”mybatis-plus的使用方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
關于mybatis-plus的簡介以及基本使用,我在《mybatis-plus的使用 ------ 入門》一文中已做介紹,此處不再贅述。本文主要對mybatis-plus的AR模式、插件、逆向工程、自定義全局操作、公共字段自動填充等知識點進行講解。
Active Record(活動記錄),是一種領域模型模式,特點是一個模型類對應關系型數據庫中的一個表,而模型類的一個實例對應表中的一行記錄。ActiveRecord 一直廣受動態語言( PHP 、 Ruby 等)的喜愛,而 Java 作為準靜態語言,對于 ActiveRecord 往往只能感嘆其優雅,所以 MP 也在 AR 道路上進行了一定的探索,僅僅需要讓實體類繼承 Model 類且實現主鍵指定方法,即可開啟 AR 之旅。接下來看具體代碼:
1、entity:
@Data public class User extends Model<User> { private Integer id; private String name; private Integer age; private Integer gender; //重寫這個方法,return當前類的主鍵 @Override protected Serializable pkVal() { return id; } }
注:實體類繼承Model類,重寫pkVal方法。
2、mapper:
public interface UserDao extends BaseMapper<User> { }
注:雖然AR模式用不到該接口,但是一定要定義,否則使用AR時會報空指針異常。
3、使用AR:
(1)、AR插入操作:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:spring/spring-dao.xml"}) public class TestAR { @Test public void testArInsert(){ User user = new User(); user.setName("林青霞"); user.setAge(22); user.setGender(1); boolean result = user.insert(); System.out.println(result); } }
image.png
注:可以看到我們并不需要注入mapper接口,不過正如剛才所說,不使用但還是要定義,否則會報錯。AR操作是通過對象本身調用相關方法,比如要insert一個user,那就用這個user調用insert方法即可。返回值為布爾類型,由上圖可看到返回了true,是操作成功的。
(2)、AR更新操作:
@Test public void testArUpdate(){ User user = new User(); user.setId(1); user.setName("劉亦菲"); boolean result = user.updateById(); System.out.println(result); }
注:user調用updateById方法,將id為1的用戶進行更新。
(3)、AR查詢操作:
@Test public void testArSelect(){ User user = new User(); //1、根據id查詢 //user = user.selectById(1); //或者這樣用 //user.setId(1); //user = user.selectById(); //2、查詢所有 //List<User> users = user.selectAll(); //3、根據條件查詢 //List<User> users = user.selectList(new EntityWrapper<User>().like("name","劉")); //4、查詢符合條件的總數 int result = user.selectCount(new EntityWrapper<User>().eq("gender",1)); System.out.println(result); }
注:上面的代碼涉及到了四個不同的查詢操作,其實用法與MP的BaseMapper提供的方法的用法差不多,只不過這里是實體對象調用。
(4)、AR刪除操作:
@Test public void testArDelete(){ User user = new User(); //刪除數據庫中不存在的數據也是返回true //1、根據id刪除數據 //boolean result = user.deleteById(1); //或者這樣寫 //user.setId(1); //boolean result = user.deleteById(); //2、根據條件刪除 boolean result = user.delete(new EntityWrapper<User>().like("name","玲")); System.out.println(result); }
注:這里介紹了兩個刪除方法,代碼中已有注釋說明。需要注意的是,刪除數據庫中不存在的數據,結果也是true。
(5)、AR分頁操作:
@Test public void testArPage(){ User user = new User(); Page<User> page = user.selectPage(new Page<>(1,4), new EntityWrapper<User>().like("name","劉")); List<User> users = page.getRecords(); System.out.println(users); }
注:這個分頁方法和BaseMapper提供的分頁一樣都是內存分頁,并非物理分頁,因為sql語句中沒用limit,和BaseMapper的selectPage方法一樣,配置了分頁插件后就可以實現真正的物理分頁。AR的分頁方法與BaseMapper提供的分頁方法不同的是,BaseMapper的selectPage方法返回值是查詢到的記錄的list集合,而AR的selectPage方法返回的是page對象,該page對象封裝了查詢到的信息,可以通過getRecords方法獲取信息。
MP提供了很多好用的插件,而且配置簡單,使用方便。接下來一起看看MP的插件如何使用。
1、分頁插件:
之前就有說到,BaseMapper的selectPage方法和AR提供的selectPage方法都不是物理分頁,需要配置分頁插件后才是物理分頁,那么現在就來看看如何配置這個插件。
<!-- 3、配置mybatisplus的sqlSessionFactory --> <bean id="sqlSessionFactory">
注:在sqlSessionFactory這個bean中,通過<property name="plugins">
配置插件,接下來的所有插件都配置在這個list中。
@Test public void testPage() { //配置了分頁插件后,還是和以前一樣的使用selectpage方法, //但是現在就是真正的物理分頁了,sql語句中有limit了 Page<Employee> page = new Page<>(1, 2); List<Employee> employeeList = emplopyeeDao.selectPage(page, null); System.out.println(employeeList); System.out.println("================= 相關的分頁信息 =================="); System.out.println("總條數:" + page.getTotal()); System.out.println("當前頁碼:" + page.getCurrent()); System.out.println("總頁數:" + page.getPages()); System.out.println("每頁顯示條數:" + page.getSize()); System.out.println("是否有上一頁:" + page.hasPrevious()); System.out.println("是否有下一頁:" + page.hasNext()); //還可以將查詢到的結果set進page對象中 page.setRecords(employeeList); }
image.png
由圖可知,sql語句中已經有了limit,是物理分頁了。
image.png
也可以通過page調用相關方法獲取到相關的分頁信息,而且還可以把查詢到的結果set回page對象中,方便前端使用。
2、性能分析插件:
在plugin的list中添加如下bean即可開啟性能分析插件:
<!-- 輸出每條SQL語句及其執行時間,生產環境不建議使用該插件 --> <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"> <property name="format">
注:這個性能分析插件配置了兩個屬性,第一個是格式化sql語句,設置為true后,sql語句格式就像上面的截圖中的一樣;第二個屬性是sql語句執行的最大時間,超過value值就會報錯,這里表示超過1000毫秒就會停止執行sql語句。
3、執行分析插件:
<!-- 如果是對全表的刪除或更新操作,就會終止該操作 --> <bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor"> <property name="stopProceed" value="true"/> </bean>
注:這個插件配置了一個屬性,stopProceed設置為true后,如果執行的是刪除表中全部內容,那就會拋出異常,終止該操作。該插件主要是防止手抖誤刪數據。
@Test public void testSqlExplain(){ //條件為null,就是刪除全表,執行分析插件會終止該操作 emplopyeeDao.delete(null); }
運行該junit測試,可以看到報如下錯誤,說明該插件生效了。
image.png
MyBatis 的代碼生成器基于xml文件進行生成,可生成: 實體類、Mapper 接口、Mapper 映射文件。
MP 的代碼生成器基于Java代碼進行生成,可生成: 實體類(可以選擇是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 層、Controller 層。
1、添加依賴:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.37</version> </dependency> <!-- mp 依賴 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>2.3</version> </dependency> <!-- mybatisplus逆向工程需要模板引擎,用freemaker也行 --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.0</version> </dependency>
注:上面是必須的三個依賴,為了可以在控制臺直觀的看到生成情況,可以添加日志包(slf4j-api和slf4j-log4j2),為了讓生成的代碼不會報錯,還可以根據情況添加spring相關的依賴、lombok依賴等。
2、生成器示例代碼:
/** * @author: zhu * @date: 2018/8/20 11:17 * mybatis-plus逆向工程示例代碼 */ public class test { @Test public void testGenerator(){ //1、全局配置 GlobalConfig config = new GlobalConfig(); config.setActiveRecord(true)//開啟AR模式 .setAuthor("zhu")//設置作者 //生成路徑(一般都是生成在此項目的src/main/java下面) .setOutputDir("E:\\develop\\Java\\workspace\\ideaworkspace\\mpg\\src\\main\\java") .setFileOverride(true)//第二次生成會把第一次生成的覆蓋掉 .setIdType(IdType.AUTO)//主鍵策略 .setServiceName("%sService")//生成的service接口名字首字母是否為I,這樣設置就沒有I .setBaseResultMap(true)//生成resultMap .setBaseColumnList(true);//在xml中生成基礎列 //2、數據源配置 DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setDbType(DbType.MYSQL)//數據庫類型 .setDriverName("com.mysql.jdbc.Driver") .setUrl("jdbc:mysql:///數據庫名") .setUsername("數據庫用戶名") .setPassword("數據庫密碼"); //3、策略配置 StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setCapitalMode(true)//開啟全局大寫命名 .setDbColumnUnderline(true)//表名字段名使用下劃線 .setNaming(NamingStrategy.underline_to_camel)//下劃線到駝峰的命名方式 .setTablePrefix("tb_")//表名前綴 .setEntityLombokModel(true)//使用lombok .setInclude("表1","表2");//逆向工程使用的表 //4、包名策略配置 PackageConfig packageConfig = new PackageConfig(); packageConfig.setParent("com.zhu.mpg")//設置包名的parent .setMapper("mapper") .setService("service") .setController("controller") .setEntity("entity") .setXml("mapper");//設置xml文件的目錄 //5、整合配置 AutoGenerator autoGenerator = new AutoGenerator(); autoGenerator.setGlobalConfig(config) .setDataSource(dataSourceConfig) .setStrategy(strategyConfig) .setPackageInfo(packageConfig); //6、執行 autoGenerator.execute(); } }
注:以上便是示例代碼,只要運行該junit測試,就會生成entity、mapper接口、mapper的xml文件、service、serviceImpl、controller代碼。每一個設置代碼中均有詳細注釋,此處不再贅述。
(一)、AutoSqlInjector :
BaseMapper提供了17個常用方法,但是有些需求這些方法還是不能很好的實現,那么怎么辦呢?大家肯定會想到是在xml文件中寫sql語句解決。這樣確實可以,因為MP是只做增強不做改變,我們完全可以按照mybatis的原來的方式來解決。不過MP也提供了另一種解決辦法,那就是自定義全局操作。所謂自定義全局操作,也就是我們可以在mapper中自定義一些方法,然后通過某些操作,讓自定義的這個方法也能像BaseMapper的內置方法,供全局調用。接下來就看看如何實現(以deleteAll方法為例)。
1、在mapper接口中定義方法:
public interface EmplopyeeDao extends BaseMapper<Employee> { int deleteAll(); }
public interface UserDao extends BaseMapper<User> { int deleteAll(); }
在這兩個mapper接口中都定義了deleteAll方法。
2、編寫自定義注入類:
public class MySqlInjector extends AutoSqlInjector { @Override public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) { /* 添加一個自定義方法 */ deleteAllUser(mapperClass, modelClass, table); System.out.println(table.getTableName()); } public void deleteAllUser(Class<?> mapperClass, Class<?> modelClass, TableInfo table) { /* 執行 SQL ,動態 SQL 參考類 SqlMethod */ String sql = "delete from ">
注:該類繼承AutoSqlInjector,重寫inject方法。然后編寫sql語句,指定mapper接口中的方法,最后調用addDeleteMappedStatement方法即可。
3、在spring配置文件中配置:
<!-- 定義自定義注入器 --> <bean class="com.zhu.mybatisplus.injector.MySqlInjector" id="mySqlInjector"/>
<!-- 5、mybatisplus的全局策略配置 --> <bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration"> <property name="idType" value="0"/> <property name="tablePrefix" value="tb_"/> <!-- 注入自定義全局操作 --> <property name="sqlInjector" ref="mySqlInjector"/> </bean>
注:先把剛才自定義的類注冊成bean,然后在全局策略配置的bean中引用自定義類的bean即可。
4、測試:
@Test public void testMySqlInjector(){ Integer result = userDao.deleteAll(); System.out.println(result); } @Test public void testMySqlInjector2(){ Integer result = emplopyeeDao.deleteAll(); System.out.println(result); }
注:經測試,當userDao調用deleteAll方法時,會刪除tb_user表的所有數據,employeeDao調用deleteAll方法時,會刪除tb_employee表的所有數據。說明deleteAll方法是有效的。不過在運行這兩個測試時,由于是全表刪除操作,所有要先把執行分析插件關了。
(二)、邏輯刪除:
其實數據并不會輕易的刪除掉,畢竟數據收集不易,所以就有了邏輯刪除。邏輯刪除: 并不會真正的從數據庫中將數據刪除掉,而是將當前被刪除的這條數據中的一個邏輯刪除字段置為刪除狀態,比如該數據有一個字段logic_flag,當其值為1表示未刪除,值為-1表示刪除,那么邏輯刪除就是將1變成-1。
1、數據表:
在數據表中需要添加邏輯刪除字段(logic_flag)。
image.png
2、實體類:
@Data public class User{ private Integer id; private String name; private Integer age; private Integer gender; @TableLogic //標記邏輯刪除屬性 private Integer logicFlag; }
注:數據庫中邏輯刪除字段是logic_flag,所以實體類中的logicFlag需要用@TableLogic注解標記。
3、mapper:
public interface UserDao extends BaseMapper<User> { }
4、配置邏輯刪除:
需要在spring-dao.xml中做如下配置:
首先定義邏輯刪除的bean:
<!-- 邏輯刪除 --> <bean class="com.baomidou.mybatisplus.mapper.LogicSqlInjector">
再在全局配置的bean中注入邏輯刪除以及邏輯刪除值:
<!-- 5、mybatisplus的全局策略配置 --> <bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration"> <!-- 此處省略其他全局配置 --> <!-- 注入自定義全局操作,做邏輯刪除時需要先注釋掉 --> <!--<property name="sqlInjector" ref="mySqlInjector"/>--> <!-- 注入邏輯刪除,先要把自定義的注釋掉 --> <property name="sqlInjector" ref="logicSqlInjector"/> <!-- 注入邏輯刪除值 --> <property name="logicDeleteValue" value="-1"/><!-- -1是刪除狀態 --> <property name="logicNotDeleteValue" value="1"/><!-- 1是未刪除狀態 --> </bean>
注:因為邏輯刪除實際上也是一個sqlInjector,所以先要把剛才做自定義全局操作時注入的自定義全局操作注釋掉,上面代碼中已有詳細注釋說明。
6、測試:
@Test public void testLogicDelete(){ Integer result = userDao.deleteById(1); System.out.println(result); //User user = userDao.selectById(1); //System.out.println(user); }
注:運行該測試,執行刪除操作的時候,真正執行的sql語句是UPDATE tb_user SET logic_flag=-1 WHERE id=?
,就是把邏輯刪除字段的值設置為-1;當邏輯刪除字段的值是-1時再執行查詢操作,sql是SELECT ... FROM tb_user WHERE id=? AND logic_flag=1
,所以查詢結果是null。
我們知道,當我們進行插入或者更新操作時,沒有設置值的屬性,那么在數據表中要么是為null,要么是保留原來的值。有的時候我們我們沒有賦值但是卻不想讓其為空,比如name屬性,我們插入時會默認賦上“林志玲”,更新時會默認賦值上“朱茵”,那么就可以用公共字段自動填充。
1、使用@TableField注解標記填充字段
@TableField(fill = FieldFill.INSERT_UPDATE)//插入和更新時填充 private String name;
2、編寫公共字段填充處理器類:
public class MyMetaObjectHandler extends MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { Object fieldValue = getFieldValByName("name",metaObject); //獲取需要填充的字段 if(fieldValue == null){ //如果該字段沒有設置值 setFieldValByName("name","林志玲",metaObject); //那就將其設置為"林志玲" } } @Override public void updateFill(MetaObject metaObject) { Object fieldValue = getFieldValByName("name",metaObject);//獲取需要填充的字段 if(fieldValue == null){ //如果該字段沒有設置值 setFieldValByName("name","朱茵",metaObject); //那就將其設置為"朱茵" } } }
注:該類繼承了MetaObjectHandler類,重寫了insertFill和updateFill方法,在這兩個方法獲取需要填充的字段以及默認填充的值。
3、在spring-dao.xml中配置:
<!-- 公共字段填充處理器 --> <bean class="com.zhu.mybatisplus.handler.MyMetaObjectHandler" id="myMetaObjectHandler"/>
<!-- 5、mybatisplus的全局策略配置 --> <bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration"> <!-- 此處省略其他配置 --> <!-- 注入公共字段填充處理器 --> <property name="metaObjectHandler" ref="myMetaObjectHandler"/> </bean>
注:和配置邏輯刪除一樣,都是先將自定義的類注冊成bean,再在全局策略配置中引用這個bean即可。
4、測試:
@Test public void testHandlerInsert() { User user = new User(); user.setGender(1); user.setAge(22); user.setLogicFlag(1); userDao.insert(user); }
image.png
注:可以看到,雖然我們并沒有給name賦值,但是已經自動把“林志玲”傳進去了。更新時也一樣有效,此處就不將測試代碼貼出來了。
到此,關于“mybatis-plus的使用方法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。