SpringBoot教程(十一) | SpringBoot集成Mybatis

      網友投稿 933 2025-04-07

      上一篇文章我們介紹了springboot集成JdbcTemplate.簡單體驗了一下JdbcTemplate框架的用法,今天的內容比較重要,我們來介紹一下springboot集成Mybatis的步驟。


      1、 Mybatis 介紹

      MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,并且改名為MyBatis 。iBATIS一詞來源于“internet”和“abatis”的組合,是一個基于Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO)。

      MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優秀的持久層框架。MyBatis 避免了幾乎所有的 JDBC 代碼和手工設置參數以及抽取結果集。MyBatis 使用簡單的 XML 或注解來配置和映射基本體,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。

      Mybatis特點:

      1、Mybatis實現了接口綁定,使用更加方便。

      2、對象關系映射的改進,效率更高

      3、MyBatis采用功能強大的基于OGNL的表達式來消除其他元素。

      優點:

      1、簡單易學

      mybatis本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar文件+配置幾個sql映射文件易于學習,易于使用,通過文檔和源代碼,可以比較完全的掌握它的設計思路和實現。

      2、靈活

      mybatis不會對應用程序或者數據庫的現有設計強加任何影響。 sql寫在xml里,便于統一管理和優化。通過sql基本上可以實現我們不使用數據訪問框架可以實現的所有功能,或許更多。

      3、解除sql與程序代碼的耦合

      通過提供DAL層,將業務邏輯和數據訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和代碼的分離,提高了可維護性。

      4、提供映射標簽,支持對象與數據庫的orm字段關系映射

      5、提供對象關系映射標簽,支持對象關系組建維護

      6、提供xml標簽,支持編寫動態sql。

      缺點:

      1、編寫SQL語句時工作量很大,尤其是字段多、關聯表多時,更是如此。

      2、SQL語句依賴于數據庫,導致數據庫移植性差,不能更換數據庫。

      3、框架還是比較簡陋,功能尚有缺失,雖然簡化了數據綁定代碼,但是整個底層數據庫查詢實際還是要自己寫的,工作量也比較大,而且不太容易適應快速數據庫修改。

      4、二級緩存機制不佳

      上面的內容都是從網上拷貝的,因為我想大多數的人應該都用過mybatis,并且我們本文的側重點主要是SpringBoot的集成方式,而不是從頭介紹Mybatis,如果大家對Mybatis的使用不太了解,建議先去學習一下Mybatis的用法。

      2、集成步驟

      接下來我們開始進行集成。為了方便操作,由于我們上次剛剛集成過JdbcTemplate, 代碼中共存多個DAO層框架可能會有問題,我們在原有項目基礎上拉取一個新的分支來進行開發,分支名就叫 feature/mybaits。完成的代碼都會托管到gitCode上,大家可在文末獲取地址。

      2.1 引入依賴

      首先我們先引入Mybatis所需依賴,mybatis本身已經提供了用于適配springBoot的Starter, 同時我們還需要引入 mysql-connector. 在pom.xml中添加:

      org.projectlombok lombok 1.18.22 provided org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.1 mysql mysql-connector-java runtime

      2.2 配置數據庫連接

      在spring的配置文件中,配置我們需要訪問的數據庫的連接信息,這個配置和前面jdbcTemplate的配置一樣

      spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/springboot_learning username: root password: root

      2.3 開發Mapper

      在JdbcTemplate中我們訪問數據庫的這一層使用dao表示的。但是在mybatis中,我們一般都把這一層稱之為mapper, 并且一般類名也用這個結尾,其實代表的都是一個意思,就是使用習慣的問題。在Mybatis中的Mapper也是分為接口和實現,比較特殊的是mapper的實現一般使用xml文件的形式來體現。我們的sql也都是寫在xml文件中。

      我們在項目中創建一個mapper的文件夾,用來存放所有的Mapper接口。我們在里邊創建UserMapper用來處理user表的增刪改查操作。

      @Mapper public interface UserMapper { /** * 刪除操作 * @param id * @return */ int deleteByPrimaryKey(Integer id); /** * 插入操作 * @param record * @return */ int insert(User record); /** * 插如操作 * @param record * @return */ int insertSelective(User record); /** * 根據id查詢操作 * @param id * @return */ User selectByPrimaryKey(Integer id); /** * 更新操作 * @param record * @return */ int updateByPrimaryKeySelective(User record); /** * 更新操作 * @param record * @return */ int updateByPrimaryKey(User record); }

      SpringBoot教程(十一) | SpringBoot集成Mybatis

      然后在resources 資源目錄下(application.yml同級目錄下)創建一個mapper文件夾,用于存放xml格式的mapper實現。在里面寫一個UserMapper.xml

      id, name, age,address,create_time, update_time delete from t_user where id = #{id,jdbcType=INTEGER} insert into t_user ( name, age,address,create_time ,update_time ) values (#{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER},#{address},#{createTime,jdbcType=TIMESTAMP},#{updateTime,jdbcType=TIMESTAMP} ) insert into t_user id, name, age, address, create_time, update_time, #{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}, #{address}, #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP}, update t_user name = #{name,jdbcType=VARCHAR}, age = #{age,jdbcType=INTEGER}, address = #{address}, create_time = #{createTime,jdbcType=TIMESTAMP}, update_time = #{updateTime,jdbcType=TIMESTAMP} where id = #{id,jdbcType=INTEGER} update t_user set name = #{name,jdbcType=VARCHAR}, age = #{age,jdbcType=INTEGER}, address = #{address,jdbcType=VARCHAR}, create_time = #{createTime,jdbcType=TIMESTAMP}, update_time = #{updateTime,jdbcType=TIMESTAMP} where id = #{id,jdbcType=INTEGER}

      然后在Service層中引用mapper.

      2.4 配置Mapper的路徑

      我們現在是把xml類型的文件都放在了resources下的mapper文件夾中了。但是這個路徑對與我們的項目中的mybatis來說他是不知道的,所以我們需要告訴它這個路徑的位置。怎么告訴呢,就是在application.yml中配置一下。

      mybatis: mapper-locations: classpath:mapper/*.xml 復制代碼

      mapper的位置位于 classpath下的mapper文件夾中的所有xml結尾的文件。

      這里還有一個問題也提下。就是mapper的接口的位置我們并沒有配置,他是怎么知道的呢,其實是我們在每個Mapper的接口上都加上了@Mapper的注解,所以他可以自動掃描到。如果要加這個注解,那么所有的Mapper接口上就都需要加,這其實是比較麻煩的。怎么辦呢,我們可以都不加這個注解,然后在SpringBoot的啟動類上,加上一個MapperScan注解,將mapper的包路徑配置進去,就都不用加了。

      我們去掉@Mapper注解,也不加任何配置會報錯:

      我們在主類上添加注解:

      @SpringBootApplication @MapperScan("com.lsqingfeng.springboot.mapper") public class SpringBootLearningApplication { public static void main(String[] args) { SpringApplication.run(SpringBootLearningApplication.class, args); } }

      再次啟動:

      成功了。

      3、 接口測試

      組裝好項目后,我們來調用一下接口。繼續使用之前的jdbc里寫好的Controller進行測試。

      調用成功后,觀察數據庫。

      李四這條使我們剛剛插入進去的,只不過兩個時間是空值,因為我們并沒有給時間賦值。

      再看看查詢接口。

      4、mybatis自動填充時間

      上面的案例中,由于我們沒有對時間進行設置,導致創建時間和修改時間都是空的。其實Mybatis中為我們提供了-的機制,相當于可以對每次執行的sql進行攔截,這樣我們就可以對對操作進行判斷,如果是插入操作,就直接設置創建時間和修改時間為當前時間。如果是更新操作則設置更新時間為當前時間。

      -代碼如下。

      import org.apache.ibatis.binding.MapperMethod.ParamMap; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlCommandType; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Signature; import org.springframework.stereotype.Component; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.Date; /** * Mybatis-,用能與設置創建時間和更新時間 */ @Component @Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) }) public class CreateTimeSetInterceptor implements Interceptor { private static final String CREATE_TIME_SETTER = "setCreateTime"; private static final String UPDATE_TIME_SETTER = "setUpdateTime"; @Override public Object intercept(Invocation invocation) throws Throwable { MappedStatement ms = (MappedStatement) invocation.getArgs()[0]; Object parameter = invocation.getArgs()[1]; if (ms.getSqlCommandType() == SqlCommandType.INSERT) { setTimeIfNeccesary(parameter, CREATE_TIME_SETTER); setTimeIfNeccesary(parameter, UPDATE_TIME_SETTER); } else if (ms.getSqlCommandType() == SqlCommandType.UPDATE) { setTimeIfNeccesary(parameter, UPDATE_TIME_SETTER); } return invocation.getMethod().invoke(invocation.getTarget(), invocation.getArgs()); } private void setTimeIfNeccesary(Object param, String methodName) { Class cls = param.getClass(); if (cls == ParamMap.class) { @SuppressWarnings("unchecked") ParamMap map = (ParamMap) param; map.entrySet().forEach(entry -> { if (!entry.getKey().equals("et")) { setIfSetterExist(entry.getValue(), methodName); } }); } else { setIfSetterExist(param, methodName); } } private void setIfSetterExist(Object param, String methodName) { Class cls = param.getClass(); try { Method m = null; try { m = cls.getDeclaredMethod(methodName, new Class[] { Date.class }); if (m != null) { m.setAccessible(true); m.invoke(param, new Date()); } } catch (NoSuchMethodException e1) { m = cls.getDeclaredMethod(methodName, new Class[] { Timestamp.class }); if (m != null) { m.setAccessible(true); m.invoke(param, new Timestamp(System.currentTimeMillis())); } } } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } } }

      接下來我們再來執行一個插入操作》

      再次觀察數據庫:

      發現時間已經有值了。

      5、 mybatis-generator 插件

      我們上面通過User表創建了UserMapper接口和UserMapper的xml實現。其實這類文件中的內容是比較有規律的,所以如果每次沒有都去自己寫,是比較耗費時間的,所有mybatis為我們提供了mybatis-generator插件,通過這個插件,我們可以設置對應的數據庫連接和表名,然后插件就會幫我們自動生成對應的實體,mapper接口和Mapper實現,里面的方法只有常用的增刪改查操作。能夠大大較少我們操作的工作量。 這個步驟,我們一般稱之為 mybatis 逆向生成。 逆向生成的方法比較多,有興趣的自己去找找吧,這里不想展開了,因為現在隨著mybatisPlus的普及,使用mybatis-plus-generator的更多一些。

      好了關于SpringBoot集成Mybatis我們就介紹這么多。歡迎大家一起交流,有問題隨時留言。

      另: 配套項目代碼已托管中gitCode: gitcode.net/lsqingfeng/…

      所有文章也會在微信公眾號首發更新,歡迎關注: 一縷82年的清風

      MyBatis Spring Boot

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:新一代WPS Office 2013發布吉祥物“朋鳥”
      下一篇:怎么設置WPS背景顏色
      相關文章
      亚洲av无码不卡私人影院| 亚洲精品天堂无码中文字幕| 色噜噜噜噜亚洲第一| 亚洲伊人久久大香线蕉结合| 亚洲精品国产电影午夜| 日本久久久久亚洲中字幕| 久久久久亚洲av无码专区| 亚洲视频在线视频| 亚洲综合一区二区精品久久| 亚洲美女大bbbbbbbbb| 亚洲国产精品综合一区在线| 亚洲激情视频网站| 亚洲av无码片在线观看| 亚洲人成77777在线播放网站不卡 亚洲人成77777在线观看网 | 亚洲中文无码卡通动漫野外 | 国产L精品国产亚洲区久久| 亚洲第一福利网站在线观看| 亚洲性在线看高清h片| 在线亚洲97se亚洲综合在线| 亚洲国产三级在线观看| 久久亚洲精品成人综合| 久久久久亚洲精品影视| 亚洲精品白色在线发布| 亚洲一区欧洲一区| 亚洲AV无码国产一区二区三区| 亚洲av成人一区二区三区在线播放| 激情小说亚洲图片| 久久亚洲av无码精品浪潮| 国产亚洲欧洲精品| 亚洲va在线va天堂va四虎| 亚洲最新在线视频| 国产成人亚洲综合一区| 亚洲AV永久无码精品放毛片| 亚洲国产高清在线一区二区三区| 亚洲熟伦熟女新五十路熟妇| 亚洲精品无码永久中文字幕| 亚洲永久永久永久永久永久精品| 亚洲国产精品成人精品软件 | 亚洲视频在线观看一区| www.亚洲成在线| 性色av极品无码专区亚洲|