您好,登錄后才能下訂單哦!
本篇內容主要講解“SpringBoot集成怎么使用MyBatis配置XML文件”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“SpringBoot集成怎么使用MyBatis配置XML文件”吧!
對象關系映射(Object Relational Mapping,ORM)模式是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術。簡單的說,ORM 是通過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關系數據庫中。
為什么需要ORM?
當你開發一個應用程序的時候(不使用 O/R Mapping),可能會寫不少數據訪問層代碼,用來從數據庫保存、刪除、讀取對象信息等;在 DAL 中寫了很多的方法來讀取對象數據、改變狀態對象等任務,而這些代碼寫起來總是重復的。針對這些問題 ORM 提供了解決方案,簡化了將程序中的對象持久化到關系數據庫中的操作。
ORM 框架的本質是簡化編程中操作數據庫的編碼,在 Java 領域發展到現在基本上就剩兩家最為流行,一個是宣稱可以不用寫一句 SQL 的 Hibernate,一個是以動態 SQL 見長的 MyBatis,兩者各有特點。在企業級系統開發中可以根據需求靈活使用,會發現一個有趣的現象:傳統企業大都喜歡使用 Hibernate,而互聯網行業通常使用 MyBatis。
MyBatis 是一款標準的 ORM 框架,被廣泛的應用于各企業開發中。MyBatis 最早是 Apache 的一個開源項目 iBatis,2010 年這個項目由 Apache Software Foundation 遷移到了 Google Code,并且改名為 MyBatis,2013 年 11 月又遷移到 Github。從 MyBatis 的遷移史,也可以看出源碼托管平臺的發展史,GitHub 目前已經成為世界上最大的開源軟件托管平臺,建議大家多多關注這個全球最大的同性社交網站。
MyBatis 支持普通的 SQL 查詢,存儲過程和高級映射的優秀持久層框架。MyBatis 消除了幾乎所有的 JDBC 代碼和參數的手工設置以及對結果集的檢索封裝。MaBatis 可以使用簡單的 XML 或注解用于配置和原始映射,將接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 對象)映射成數據庫中的記錄。
1. MyBatis的優點
SQL 被統一提取出來,便于統一管理和優化
SQL 和代碼解耦,將業務邏輯和數據訪問邏輯分離,使系統的設計更清晰、更易維護、更易單元測試
提供映射標簽,支持對象與數據庫的 ORM 字段關系映射
提供對象關系映射標簽,支持對象關系組件維護
靈活書寫動態 SQL,支持各種條件來動態生成不同的 SQL
2. MyBatis的缺點
編寫 SQL 語句時工作量很大,尤其是字段多、關聯表多時,更是如此
SQL 語句依賴于數據庫,導致數據庫移植性差
3. MyBatis幾個重要的概念
Mapper 配置可以使用基于 XML 的 Mapper 配置文件來實現,也可以使用基于 Java 注解的 MyBatis 注解來實現,甚至可以直接使用 MyBatis 提供的 API 來實現。
Mapper 接口是指自行定義的一個數據操作接口,類似于通常所說的 DAO 接口。早期的 Mapper 接口需要自定義去實現,現在 MyBatis 會自動為 Mapper 接口創建動態代理對象。Mapper 接口的方法通常與 Mapper 配置文件中的 select、insert、update、delete 等 XML 結點存在一一對應關系。
Executor,MyBatis 中所有的 Mapper 語句的執行都是通過 Executor 進行的,Executor 是 MyBatis 的一個核心接口。
SqlSession,是 MyBatis 的關鍵對象,是執行持久化操作的獨享,類似于 JDBC 中的 Connection,SqlSession 對象完全包含以數據庫為背景的所有執行 SQL 操作的方法,它的底層封裝了 JDBC 連接,可以用 SqlSession 實例來直接執行被映射的 SQL 語句。
SqlSessionFactory,是 MyBatis 的關鍵對象,它是單個數據庫映射關系經過編譯后的內存鏡像。SqlSessionFactory 對象的實例可以通過 SqlSessionFactoryBuilder 對象類獲得,而 SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個預先定制的 Configuration 的實例構建出。
4. MyBatis的工作流如下:
首先加載 Mapper 配置的 SQL 映射文件,或者是注解的相關 SQL 內容。
創建會話工廠,MyBatis 通過讀取配置文件的信息來構造出會話工廠(SqlSessionFactory)。
創建會話。根據會話工廠,MyBatis 就可以通過它來創建會話對象(SqlSession),會話對象是一個接口,該接口中包含了對數據庫操作的增、刪、改、查方法。
創建執行器。因為會話對象本身不能直接操作數據庫,所以它使用了一個叫做數據庫執行器(Executor)的接口來幫它執行操作。
封裝 SQL 對象。在這一步,執行器將待處理的 SQL 信息封裝到一個對象中(MappedStatement),該對象包括 SQL 語句、輸入參數映射信息(Java 簡單類型、HashMap 或 POJO)和輸出結果映射信息(Java 簡單類型、HashMap 或 POJO)。
操作數據庫。擁有了執行器和 SQL 信息封裝對象就使用它們訪問數據庫了,最后再返回操作結果,結束流程。
mybatis-spring-boot-starter 是 MyBatis 幫助我們快速集成 Spring Boot 提供的一個組件包,使用這個組件可以做到以下幾點:
構建獨立的應用
幾乎可以零配置
需要很少的 XML 配置
mybatis-spring-boot-starter 依賴于 MyBatis-Spring 和 Spring Boot,最新版 1.3.2 需要 MyBatis-Spring 1.3 以上,Spring Boot 版本 1.5 以上。
注意 mybatis-spring-boot-starter 是 MyBatis 官方開發的 Starter,而不是 Spring Boot 官方開發的啟動包,其實是 MyBatis 看 Spring Boot 市場使用度非常高,因此主動開發出 Starter 包進行集成,但這一集成確實解決了很多問題,使用起來比以前簡單很多。mybatis-spring-boot-starter 主要提供了兩種解決方案,一種是簡化后的 XML 配置版,一種是使用注解解決一切問題。
MyBatis 以前只有 XML 配置這種使用的形式,到了后來注解使用特別廣泛,MyBatis 也順應潮流提供了注解的支持,從這里可以看出 MyBatis 一直都跟隨著主流技術的變化來完善自己。接下來給大家介紹一下如何使用 XML 版本。
XML 版本保持映射文件的方式,最新版的使用主要體現在不需要實現 Dao 的實現層,系統會自動根據方法名在映射文件中找到對應的 SQL。
初始化腳本
為了方便項目演示,需要在 test 倉庫創建 users 表,腳本如下:
DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵id', `userName` varchar(32) DEFAULT NULL COMMENT '用戶名', `passWord` varchar(32) DEFAULT NULL COMMENT '密碼', `user_sex` varchar(32) DEFAULT NULL, `nick_name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
關鍵依賴包
當然任何模式都需要首先引入 mybatis-spring-boot-starter 的 pom 文件,現在最新版本是 1.3.2。
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency>
application配置
application.properties 添加相關配置
mybatis.config-location=classpath:mybatis/mybatis-config.xml mybatis.mapper-locations=classpath:mybatis/mapper/*.xml mybatis.type-aliases-package=com.neo.model spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.config-location,配置 mybatis-config.xml 路徑,mybatis-config.xml 中配置 MyBatis 基礎屬性;
mybatis.mapper-locations,配置 Mapper 對應的 XML 文件路徑;
mybatis.type-aliases-package,配置項目中實體類包路徑;
spring.datasource.*,數據源配置。
Spring Boot 啟動時數據源會自動注入到 SqlSessionFactory 中,使用 SqlSessionFactory 構建 SqlSessionFactory,再自動注入到 Mapper 中,最后我們直接使用 Mapper 即可。
啟動類
在啟動類中添加對 Mapper 包掃描 @MapperScan,Spring Boot 啟動的時候會自動加載包路徑下的 Mapper。
@Spring BootApplication @MapperScan("com.neo.mapper") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
或者直接在 Mapper 類上面添加注解 @Mapper,建議使用上面那種,不然每個 mapper 加個注解也挺麻煩的。
示例演示
MyBatis 公共屬性
mybatis-config.xml 主要配置常用的 typeAliases,設置類型別名,為 Java 類型設置一個短的名字。它只和 XML 配置有關,存在的意義僅在于用來減少類完全限定名的冗余。
<configuration> <typeAliases> <typeAlias alias="Integer" type="java.lang.Integer" /> <typeAlias alias="Long" type="java.lang.Long" /> <typeAlias alias="HashMap" type="java.util.HashMap" /> <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" /> <typeAlias alias="ArrayList" type="java.util.ArrayList" /> <typeAlias alias="LinkedList" type="java.util.LinkedList" /> </typeAliases> </configuration>
resultType="Integer" //或者 parameterType="Long"
添加 User 的映射文件
<mapper namespace="com.neo.mapper.UserMapper" >
<resultMap id="BaseResultMap" type="com.neo.model.User" > <id column="id" property="id" jdbcType="BIGINT" /> <result column="userName" property="userName" jdbcType="VARCHAR" /> <result column="passWord" property="passWord" jdbcType="VARCHAR" /> <result column="user_sex" property="userSex" javaType="com.neo.enums.UserSexEnum"/> <result column="nick_name" property="nickName" jdbcType="VARCHAR" /></resultMap>
這里為了更好的貼近工作情況,將類的兩個字段和數據庫字段設置為不一致,其中一個使用了枚舉。使用枚舉有一個非常大的優點,插入此屬性的數據會自動進行校驗,如果不是枚舉的內容會報錯。
<select id="getAll" resultMap="BaseResultMap" > SELECT * FROM users </select>
第三步,寫具體的 SQL 語句,比如這樣:
第二步,配置表結構和類的對應關系:
第一步,指明對應文件的 Mapper 類地址:
MyBatis XML 有一個特點是可以復用 XML,比如我們公用的一些 XML 片段可以提取出來,在其他 SQL 中去引用。例如:
<sql id="Base_Column_List" > id, userName, passWord, user_sex, nick_name </sql> <select id="getAll" resultMap="BaseResultMap" > SELECT <include refid="Base_Column_List" /> FROM users </select>
這個例子就是,上面定義了需要查詢的表字段,下面 SQL 使用 include 引入,避免了寫太多重復的配置內容。
下面是常用的增、刪、改、查的例子:
<select id="getOne" parameterType="Long" resultMap="BaseResultMap" > SELECT <include refid="Base_Column_List" /> FROM users WHERE id = #{id} </select> <insert id="insert" parameterType="com.neo.model.User" > INSERT INTO users (userName,passWord,user_sex) VALUES (#{userName}, #{passWord}, #{userSex}) </insert> <update id="update" parameterType="com.neo.model.User" > UPDATE users SET <if test="userName != null">userName = #{userName},</if> <if test="passWord != null">passWord = #{passWord},</if> nick_name = #{nickName} WHERE id = #{id} </update> <delete id="delete" parameterType="Long" > DELETE FROM users WHERE id =#{id} </delete>
上面 update 的 SQL 使用了 if 標簽,可以根據不同的條件生產動態 SQL,這就是 MyBatis 最大的特點。
編寫 Dao 層的代碼
public interface UserMapper { List<UserEntity> getAll(); UserEntity getOne(Long id); void insert(UserEntity user); void update(UserEntity user); void delete(Long id); }
注意:這里的方法名需要和 XML 配置中的 id 屬性一致,不然會找不到方法去對應執行的 SQL。
測試使用
按照 Spring 一貫使用形式,直接將對應的 Mapper 注入即可。
@Resource private UserMapper userMapper;
如果使用的是 Idea,這塊的注解經常會報“could not autowire”,Eclipse 卻沒有問題,其實代碼是正確的,這是 Idea 的誤報。可以選擇降低 Autowired 檢測的級別,不要提示就好。在 File | Settings | Editor | Inspections 選項中使用搜索功能找到 Autowiring for Bean Class,將 Severity 的級別由之前的 error 改成 warning 即可。
接下來直接使用 userMapper 進行數據庫操作即可。
@Test public void testUser() { //增加 userMapper.insert(new User("aa", "a123456", UserSexEnum.MAN)); //刪除 int count=userMapper.delete(2l); User user = userMapper.getOne(1l); user.setNickName("smile"); //修改 userMapper.update(user); //查詢 List<User> users = userMapper.getAll(); }
分頁查詢
多條件分頁查詢是實際工作中最常使用的功能之一,MyBatis 特別擅長處理這類的問題。在實際工作中,會對分頁進行簡單的封裝,方便前端使用。另外在 Web 開發規范使用中,Web 層的參數會以 param 為后綴的對象進行傳參,以 result 結尾的實體類封裝返回的數據。
先定義一個分頁的基礎類(默認每頁 3 條記錄,可以根據前端傳參進行修改):
public class PageParam { private int beginLine; //起始行 private Integer pageSize = 3; private Integer currentPage=0; // 當前頁 //getter setter省略 public int getBeginLine() { return pageSize*currentPage;//自動計算起始行 } }
user 的查詢條件參數類繼承分頁基礎類:
public class UserParam extends PageParam{ private String userName; private String userSex; //getter setter省略 }
接下來配置具體的 SQL,先將查詢條件提取出來。
<sql id="Base_Where_List"> <if test="userName != null and userName != ''"> and userName = #{userName} </if> <if test="userSex != null and userSex != ''"> and user_sex = #{userSex} </if> </sql>
從對象 UserParam 中獲取分頁信息和查詢條件,最后進行組合。
<select id="getList" resultMap="BaseResultMap" parameterType="com.neo.param.UserParam"> select <include refid="Base_Column_List" /> from users where 1=1 <include refid="Base_Where_List" /> order by id desc limit #{beginLine} , #{pageSize} </select>
前端需要展示總共的頁碼,因此需要統計出查詢結果的總數。
<select id="getCount" resultType="Integer" parameterType="com.neo.param.UserParam"> select count(1) from users where 1=1 <include refid="Base_Where_List" /> </select>
Mapper 中定義的兩個方法和配置文件相互對應。
public interface UserMapper { List<UserEntity> getList(UserParam userParam); int getCount(UserParam userParam); }
具體使用:
@Test public void testPage() { UserParam userParam=new UserParam(); userParam.setUserSex("WOMAN"); userParam.setCurrentPage(1); List<UserEntity> users=userMapper.getList(userParam); long count=userMapper.getCount(userParam); Page page = new Page(userParam,count,users); System.out.println(page); }
在實際使用中,只需要傳入 CurrentPage 參數即可,默認 0 就是第一頁,傳 1 就是第二頁的內容,最后將結果封裝為 Page 返回給前端。
public class Page<E> implements Serializable { private int currentPage = 0; //當前頁數 private long totalPage; //總頁數 private long totalNumber; //總記錄數 private List<E> list; //數據集 }
Page 將分頁信息和數據信息進行封裝,方便前端顯示第幾頁、總條數和數據,這樣分頁功能就完成了。
配置文件
首先我們需要配置兩個不同的數據源,注意,需要提前在 test1 和 test2 庫中創建好 User 表結構
mybatis.config-location=classpath:mybatis/mybatis-config.xml spring.datasource.one.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.one.username=root spring.datasource.one.password=root spring.datasource.one.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.two.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.two.username=root spring.datasource.two.password=root spring.datasource.two.driver-class-name=com.mysql.cj.jdbc.Driver
第一個數據源以 spring.datasource.one.* 為前綴連接數據庫 test1,第二個數據源以 spring.datasource.two.* 為前綴連接數據庫 test2。 第一個數據源以 spring.datasource.one.* 為前綴連接數據庫 test1,第二個數據源以 spring.datasource.two.* 為前綴連接數據庫 test2。
數據源配置
為兩個數據源創建不同的 Mapper 包路徑,將以前的 UserMapper 復制到包 com.neo.mapper.one 和 com.neo.mapper.two 路徑下,并且分別重命名為:User1Mapper、User2Mapper。
配置第一個數據源,新建 DataSource1Config,首先加載配置的數據源
@Bean(name = "oneDataSource") @ConfigurationProperties(prefix = "spring.datasource.one") @Primary public DataSource testDataSource() { return DataSourceBuilder.create().build(); }
根據創建的數據源,構建對應的 SqlSessionFactory。
@Bean(name = "oneSqlSessionFactory") @Primary public SqlSessionFactory testSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/one/*.xml")); return bean.getObject(); }
代碼中需要指明加載的 Mapper xml 文件。
同時將數據源添加到事務中。
@Bean(name = "oneTransactionManager") @Primary public DataSourceTransactionManager testTransactionManager(@Qualifier("oneDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); }
接下來將上面創建的 SqlSessionFactory 注入,創建我們在 Mapper 中需要使用的 SqlSessionTemplate。
@Bean(name = "oneSqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); }
最后將上面創建的 SqlSessionTemplate 注入到對應的 Mapper 包路徑下,這樣這個包下面的 Mapper 都會使用第一個數據源來進行數據庫操作。
@Configuration @MapperScan(basePackages = "com.neo.mapper.one", sqlSessionTemplateRef = "oneSqlSessionTemplate") public class OneDataSourceConfig { ... }
basePackages 指明 Mapper 地址。
sqlSessionTemplateRef 指定 Mapper 路徑下注入的 sqlSessionTemplate。
第二個數據源配置
DataSource2Config 的配置和上面類似,方法上需要去掉 @Primary 注解,替換對應的數據源和 Mapper 路徑即可。下面是 DataSource2Config 完整示例:
@Configuration @MapperScan(basePackages = "com.neo.mapper.two", sqlSessionTemplateRef = "twoSqlSessionTemplate") public class DataSource2Config { @Bean(name = "twoDataSource") @ConfigurationProperties(prefix = "spring.datasource.two") public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "twoSqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/two/*.xml")); return bean.getObject(); } @Bean(name = "twoTransactionManager") public DataSourceTransactionManager testTransactionManager(@Qualifier("twoDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "twoSqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
從上面的步驟我們可以總結出來,創建多數據源的過程就是:首先創建 DataSource,注入到 SqlSessionFactory 中,再創建事務,將 SqlSessionFactory 注入到創建的 SqlSessionTemplate 中,最后將 SqlSessionTemplate 注入到對應的 Mapper 包路徑下。其中需要指定分庫的 Mapper 包路徑。
注意,在多數據源的情況下,我們不需要在啟動類添加 @MapperScan("com.xxx.mapper") 的注解。
這樣 MyBatis 多數據源的配置就完成了,如果有更多的數據源請參考第二個數據源的配置即可。
測試
配置好多數據源之后,在項目中想使用哪個數據源就把對應數據源Mapper注入到類中使用即可。
@RunWith(SpringRunner.class) @SpringBootTest public class UserMapperTest { @Autowired private User1Mapper user1Mapper; @Autowired private User2Mapper user2Mapper; @Test public void testInsert() throws Exception { user1Mapper.insert(new User("aa111", "a123456", UserSexEnum.MAN)); user1Mapper.insert(new User("bb111", "b123456", UserSexEnum.WOMAN)); user2Mapper.insert(new User("cc222", "b123456", UserSexEnum.MAN)); } }
上面的測試類中注入了兩個不同的 Mapper,對應了不同的數據源。在第一個數據源中插入了兩條數據,第二個數據源中插入了一條信息,運行測試方法后查看數據庫1有兩條數據,數據庫2有一條數據,證明多數據源測試成功。
介紹了 ORM 框架 和 MyBatis 框架相關概念介紹,以用戶數據為例演示了 MyBatis 的增、刪、改、查,以及分頁查詢、多數據源處理等常見場景。通過上面的示例可以發現 MyBatis 將執行 SQL 和代碼做了隔離,保證代碼處理和 SQL 的相對獨立,層級劃分比較清晰,MyBatis 對動態 SQL 支持非常友好,可以在 XML 文件中復用代碼高效編寫動態 SQL。
springboot一種全新的編程規范,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程,SpringBoot也是一個服務于框架的框架,服務范圍是簡化配置文件。
到此,相信大家對“SpringBoot集成怎么使用MyBatis配置XML文件”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。