您好,登錄后才能下訂單哦!
如何集成與使用Spring Boot + Mybatis-Plus,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
當Spring Boot應用從主方法main()啟動后,首先加載Spring Boot注解類@SpringBootApplication。
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
在該類里加載注解類@EnableAutoConfiguration。
在EnableAutoConfiguration類使用注解類@Import導入了AutoConfigurationImportSelector自動配置選擇器類來加載其他可自動配置的組件,步驟如下:
1、AutoConfigurationImportSelector自動配置選擇器調用getCandidateConfigurations方法,方法中SpringFactoriesLoader類通過loadFactoryNames方法掃描獲取各jar包類路徑下的META-INF/spring.factories文件
2、將掃描到的META-INF/spring.factories文件封裝成Properties對象
3、遍歷Properties對象,從中取出屬性名org.springframework.boot.autoconfigure.EnableAutoConfiguration.EnableAutoConfiguration對應的值,值就為當前Jar包需Spring Boot加載的配置類,加載到容器中,并根據配置條件實例化配置類中的類對象
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; }
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) { MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader); if (result != null) { return result; } else { try { //掃描META-INF/spring.factories文件 Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories"); LinkedMultiValueMap result = new LinkedMultiValueMap(); while(urls.hasMoreElements()) { URL url = (URL)urls.nextElement(); UrlResource resource = new UrlResource(url); //通過spring.factories文件Url封成Properties對象 Properties properties = PropertiesLoaderUtils.loadProperties(resource); Iterator var6 = properties.entrySet().iterator(); while(var6.hasNext()) { Entry<?, ?> entry = (Entry)var6.next(); String factoryClassName = ((String)entry.getKey()).trim(); String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue()); int var10 = var9.length; for(int var11 = 0; var11 < var10; ++var11) { String factoryName = var9[var11]; result.add(factoryClassName, factoryName.trim()); } } } cache.put(classLoader, result); return result; } catch (IOException var13) { throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13); } } }
來看下mybatis-plus-boot-starter包下的META-INF/spring.factories文件
文件中只有一條配置屬性值,對應的自動配置類為MybatisPlusAutoConfiguration。至此,MyBatis-Plus是如何被自動配置并加載容器介紹到這里,后續會講解Spring Boot時會更細致自動配置原理,各位同伴們繼續關注。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
了解Spring Boot是如何自動配置MyBatis-Plus后,接下來講解使用MyBatis-Plus進行通用的CRUD操作以及相關操作的配置。
上一章節,我們準備了一個sql腳本,執行腳本后創建t_sys_log表,表結構可以查看上一章節。接著我們在項目中創建對應entity類和mapper接口
1. 目錄結構如下
2. 實體類SysLog屬性如下
public class SysLog implements Serializable { private int logId; private Integer optionType; private String optionPerson; private String optionContent; private String optionIp; private String optionStatus; private String errorInfo; private Date optionTime; //get與set方法
3. 在SysLogMapper接口中繼承MyBatis-Plus包中BaseMapper接口,接口定義泛型,使用SysLog類
import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface SysLogMapper extends BaseMapper<SysLog> { }
4. 注入mapper接口,需要將mapper實例到Spring容器中,在這三種方式
在Spring Boot主方法類上加上@MapperScan("com.banxun.demo.mapper"),配置mapper接口所在包路徑,自動掃描此路徑下的mapper接口
@SpringBootApplication @MapperScan("com.banxun.demo.mapper") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
直接在mapper接口上加入@Mapper注解
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; @Mapper public interface SysLogMapper extends BaseMapper<SysLog> { }
在項目中新建config目錄,再新建MybatisConfig配置類,使用注解@Configuration定義此類為配置類,使用注解注解@Bean。容器啟動時,創建MapperScannerConfigurer對象,設置basePackage屬性值為mapper接口的包路徑
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisConfig { @Bean public MapperScannerConfigurer MapperScannerConfigurer(){ MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer(); scannerConfigurer.setBasePackage("com.banxun.demo.mapper"); return scannerConfigurer; } }
到此,MyBatis-Plus基本配置完成,我們來使用junit進行測試,看看測試有什么問題,針對具體問題來解決。后續章節中對MyBatis-Plus其他配置一一進行講解。
在junit測試類中注入SysLogMapper,編寫如下代碼插入一條日志記錄,執行junit測試方法
@RunWith(SpringRunner.class) @SpringBootTest public class BootApplicationTests { @Autowired private SysLogMapper sysLogMapper; @Test public void contextLoads() { SysLog sysLog = new SysLog(); sysLog.setOptionTime(new Date()); sysLog.setOptionType(1); sysLog.setOptionContent("測試mybatis-plus"); sysLogMapper.insert(sysLog); } }
問題1: Error updating database. Cause: java.sql.SQLSyntaxErrorException: Table 'wechat.sys_log' doesn't exist
執行完成控制臺輸出打印上面的異常信息,報sys_log表不存在,而我們創建的表名為t_sys_log,有前綴"t_"。在現在配置下,MyBatis-Plus默認自動按駝峰結構類名進行映射成帶下劃線_隔離的表名,解決此問題有兩種方法:
在實體類名SysLog上加@TableName注解指定映射表名
@TableName("t_sys_log") public class SysLog implements Serializable {
在配置文件application.properties添加全局配置屬性統一處理未注解指定表名實體類映射表名時加入前綴"t_"
mybatis-plus.global-config.db-config.table-prefix=t_
問題2: Cause: java.sql.SQLSyntaxErrorException: Unknown column 'log_id' in 'field list'
根據問題1配置完成后再次執行junit測試方法,控制臺輸出打印上面的異常信息,報log_id列不存在。在t_sys_log表中,主鍵名為f_log_id,這里同樣缺少字段前綴,解決方法有兩種:
默認MyBatis-Plus會根據屬性駝峰命名自動進行字段映射及主鍵名叫id都可無注解指定字段名
屬性名上加@TableField("字段名")注解指定映射字段名,主鍵字段使用@TableId("字段名")注解
通過配置文件application.properties添加全局配置屬性統一處理,%s對應自動映射字段名
mybatis-plus.global-config.db-config.column-format=f_%s
問題3:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: Could not set property 'logId' of 'class com.banxun.demo.entity.SysLog' with value '1164549971505057794' Cause: java.lang.IllegalArgumentException: argument type mismatch
配置完問題2后,控制臺輸出再次打印上面的異常信息。此問題原因是插入數據時MyBatis-Plus為主鍵生成的Id值過長,需要配置主鍵生成策略。這問題解決也有兩種方式:
在主鍵性加上@TableId(value = "f_log_id", type = IdType.AUTO),IdType有六個選項值,默認ID_WORKER,我們表使用鍵值自動遞增,所以選AUTO
public enum IdType { AUTO(0), //數據庫自增 NONE(1), //無狀態 INPUT(2), //自行輸入 ID_WORKER(3), //分布式全局唯一ID 長整型類型 UUID(4), //32位UUID字符串 ID_WORKER_STR(5); //分布式全局唯一ID 字符串類型
在配置文件application.properties添加全局配置屬性統一處理
mybatis-plus.global-config.db-config.id-type=auto
經過前面的配置后,junit方法執行成功,在庫中插入了一條日志記錄
根據id查詢
@Test public void contextLoads() { SysLog sysLog = sysLogMapper.selectById(173); System.out.println(sysLog.getOptionContent()); }
控制臺打印輸入前面插入的日志內容信息
2019-08-22 23:16:00.489 INFO 5112 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. _ _ |_ _ _|_. ___ _ | _ | | |\/|_)(_| | |_\ |_)||_|_\ / | 3.1.2 2019-08-22 23:16:00.867 INFO 5112 --- [ main] com.banxun.demo.DemoApplicationTests : Started DemoApplicationTests in 2.204 seconds (JVM running for 3.16) 測試mybatis-plus 2019-08-22 23:16:01.132 INFO 5112 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2019-08-22 23:16:01.317 INFO 5112 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
根據內容模糊查詢,這使用QueryWrapper條件構造器進行條件查詢
@Test public void contextLoads() { QueryWrapper<SysLog> queryWrapper = new QueryWrapper<>(); queryWrapper.like("f_option_content", "plus"); List<SysLog> sysLogs = sysLogMapper.selectList(queryWrapper); for (SysLog sysLog : sysLogs) { System.out.println(sysLog.getOptionContent()); } }
@Test public void contextLoads() { SysLog sysLog = new SysLog(); sysLog.setLogId(173); sysLog.setOptionContent("測試Spring Boot + MyBatis-Plus"); sysLogMapper.updateById(sysLog); }
執行完成后,我們再通過上面根據id查詢,可以看到控制臺打印輸入更新的日志內容信息
2019-08-22 23:26:57.358 INFO 22964 --- [ main] com.banxun.demo.DemoApplicationTests : Starting DemoApplicationTests on LAPTOP-6AQTBBR1 with PID 22964 (started by karanatarm in E:\ideaplace\demo) 2019-08-22 23:26:57.359 INFO 22964 --- [ main] com.banxun.demo.DemoApplicationTests : No active profile set, falling back to default profiles: default 2019-08-22 23:26:58.369 INFO 22964 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2019-08-22 23:26:58.813 INFO 22964 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. _ _ |_ _ _|_. ___ _ | _ | | |\/|_)(_| | |_\ |_)||_|_\ / | 3.1.2 2019-08-22 23:26:59.167 INFO 22964 --- [ main] com.banxun.demo.DemoApplicationTests : Started DemoApplicationTests in 2.087 seconds (JVM running for 3.044) 測試Spring Boot + MyBatis-Plus 2019-08-22 23:26:59.456 INFO 22964 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2019-08-22 23:26:59.518 INFO 22964 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
@Test public void tes() { SysLog sysLog = new SysLog(); sysLog.setLogId(173); sysLogMapper.deleteById(sysLog); }
執行完成后,我們再根據id查詢,可以看到控制臺沒有打印輸入日志內容
看完上述內容,你們掌握如何集成與使用Spring Boot + Mybatis-Plus的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。