一、MyBatis介紹java
二、MyBatis架構mysql
四、傳統Dao開發與MyBatis的Mapper動態代理開發spring
六、輸入映射和輸出映射數據庫
6.1 parameterTypeexpress
6.2 resultTypeapache
七、動態sql數組
MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,而且更名爲MyBatis 。2013年11月遷移到Github。
MyBatis是一個優秀的持久層框架,它對jdbc的操做數據庫的過程進行封裝,使開發者只須要關注 SQL 自己,而不須要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。
Mybatis經過xml或註解的方式將要執行的各類statement(statement、preparedStatemnt、CallableStatement)配置起來,並經過java對象和statement中的sql進行映射生成最終執行的sql語句,最後由mybatis框架執行sql並將結果映射成java對象並返回。
一、mybatis配置的sqlMapConfig.xml,此文件做爲mybatis的全局配置文件,配置了mybatis的運行環境等信息。
mapper.xml文件即sql映射文件,文件中配置了操做數據庫的sql語句。此文件須要在sqlMapConfig.xml中加載。
二、經過mybatis環境等配置信息構造SqlSessionFactory即會話工廠
三、由會話工廠建立sqlSession即會話,操做數據庫須要經過sqlSession進行。
四、mybatis底層自定義了Executor執行器接口操做數據庫,Executor接口有兩個實現,一個是基本執行器、一個是緩存執行器。
五、Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應一個Mapped Statement對象,sql的id便是Mapped statement的id。
六、Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo,Executor經過Mapped Statement在執行sql前將輸入的java對象映射至sql中,輸入參數映射就是jdbc編程中對preparedStatement設置參數。
七、Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor經過Mapped Statement在執行sql後將輸出結果映射至java對象中,輸出結果映射過程至關於jdbc編程中對結果的解析處理過程。
1)基本開發環境搭建:基於maven搭建MyBatis開發環境,而後進行測試數據庫建立以及相關jar包的引入
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency>2)建立配置文件:根據架構圖,首先建立sqlMapConfig.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> <properties resource="jdbc.properties"/> <environments default="development"> <environment id="development"> <!-- 使用jdbc事務管理 --> <transactionManager type="JDBC" /> <!-- 數據庫鏈接池 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> </configuration>這裏咱們使用了jdbc.properties將數據庫的相關信息單獨提取出來
3)建立pojo:與數據庫中的表進行匹配,這裏以user表舉例
import java.io.Serializable; import java.util.Date; public class User implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String username;// 用戶姓名 private String sex;// 性別 private Date birthday;// 生日 private String address;// 地址 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address=" + address + "]"; } }4)建立映射文件並集中到sqlMapConfig.xml:爲User.java建立映射文件User.xml,該文件中主要進行SQL語句的編寫
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 寫Sql語句 --> <mapper namespace="user"> <select id="findUserById" parameterType="Integer" resultType="com.panlei.pojo.User"> select * from user where id = #{v} </select> </mapper>這裏的不一樣的聲明用不一樣的id進行區別,parameterType是傳參的類型,resultType是返回值類型,要與後面講到的方法調用進行匹配。namespace是爲了區分不一樣的映射mapper文件集中到sqlMapConfig.xml中可能id衝突的問題,後面還會具體講解。
5)具體測試1:根據id查詢用戶信息,仍是建立SqlSessionFactory,而後獲取SqlSession,再調用selectOne(..)方法,根據傳遞的"user.findUserById"定位到具體的映射文件的具體sql語句,這裏傳遞的參數即是前面定義的所需參數
import com.panlei.pojo.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; public class TestMyBatis { @Test public void test1() { try { String resource = "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); User o = sqlSession.selectOne("user.findUserById", 10); System.out.println(o); } catch (IOException e) { e.printStackTrace(); } } }6)具體測試2:根據用戶名模糊匹配查詢
具體的sql語句格式:select * from user where username like '%五%'
這裏傳遞的參數就是String類型,而後返回值多是一個用戶列表,這裏用的是${value},不是前面的#{},後面具體講解區別
<select id="findUserByUsername" parameterType="String" resultType="com.panlei.pojo.User"> select * from user where username like '%${value}%' </select>// 根據用戶名模糊匹配 @Test public void test2() { try { String resource = "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); List<User> users = sqlSession.selectList("user.findUserByUsername", "五"); for(User u:users) { System.out.println(u); } } catch (IOException e) { e.printStackTrace(); } }7)#{}與${}的區別
#{}表示一個佔位符號,經過#{}能夠實現preparedStatement向佔位符中設置值,自動進行java類型和jdbc類型轉換。#{}能夠有效防止sql注入。 #{}能夠接收簡單類型值或pojo屬性值。 若是parameterType傳輸單個簡單類型值,#{}括號中能夠是value或其它名稱。
${}表示拼接sql串,經過${}能夠將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換, ${}能夠接收簡單類型值或pojo屬性值,若是parameterType傳輸單個簡單類型值,${}括號中只能是value。
8)具體實例3:添加用戶,這裏直接傳遞的參數是自定義的User對象實例,直接進行映射,其屬性要與pojo中的屬性名一致
<!-- 保存用戶 --> <insert id="saveUser" parameterType="com.panlei.pojo.User"> INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}) </insert>這裏在實際應用中可能須要當即獲取新添加用戶的id來進行後續操做,下面演示如何編碼:
<insert id="saveUser" parameterType="com.panlei.pojo.User"> <!-- selectKey 標籤實現主鍵返回 --> <!-- keyColumn:主鍵對應的表中的哪一列 --> <!-- keyProperty:主鍵對應的pojo中的哪個屬性 --> <!-- order:設置在執行insert語句前執行查詢id的sql,仍是在執行insert語句以後執行查詢id的sql --> <!-- resultType:設置返回的id的類型 --> <selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int"> SELECT LAST_INSERT_ID() </selectKey> INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}) </insert>LAST_INSERT_ID():是mysql的函數,返回auto_increment自增列新記錄id值。
而後在測試代碼中能夠直接打印插入用戶的id,發現是最新的自增id。不須要額外的代碼。
Mybatis解決jdbc編程的問題
一、數據庫鏈接建立、釋放頻繁形成系統資源浪費從而影響系統性能,若是使用數據庫鏈接池可解決此問題。
解決:在SqlMapConfig.xml中配置數據鏈接池,使用鏈接池管理數據庫連接。
二、Sql語句寫在代碼中形成代碼不易維護,實際應用sql變化的可能較大,sql變更須要改變java代碼。
解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
三、向sql語句傳參數麻煩,由於sql語句的where條件不必定,可能多也可能少,佔位符須要和參數一一對應。
解決:Mybatis自動將java對象映射至sql語句,經過statement中的parameterType定義輸入參數的類型。
四、對結果集解析麻煩,sql變化致使解析代碼變化,且解析前須要遍歷,若是能將數據庫記錄封裝成pojo對象解析比較方便。
解決:Mybatis自動將sql執行結果映射至java對象,經過statement中的resultType定義輸出結果的類型。
傳統的Dao開發,就是建立Dao,而後建立Dao的實現類,而後在Service中使用便可,仍是須要針對具體的pojo,建立具體的mapper.xml文件。具體實現就再也不詳述。
MyBatis中官方推薦使用編寫Mapper接口(至關於Dao接口),而後交給Mybatis進行處理,根據該接口自動建立該接口的動態代理對象。爲實現這一目標,事先定義了Mapper接口的開發規範:
1.Mapper.xml文件中的namespace與mapper接口的類路徑相同;
2.Mapper接口方法名和Mapper.xml中定義的每一個statement的id相同;
3.Mapper接口方法的輸入參數類型和mapper.xml中定義的每一個sql 的parameterType的類型相同;
4.Mapper接口方法的輸出參數類型和mapper.xml中定義的每一個sql的resultType的類型相同。
下面結合具體實例解釋上述規範:
這樣咱們在具體執行時,會自動生成接口的代理類對象,而後執行接口的具體方法時,會根據規範找到對應mapper文件下的相應方法
package com.panlei.mybatisdemo; import com.panlei.mapper.UserMapper; import com.panlei.pojo.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import java.io.InputStream; import java.util.Date; public class TestMapper { private SqlSessionFactory sqlSessionFactory; @Before public void init() throws Exception { // 建立SqlSessionFactoryBuilder SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 加載SqlMapConfig.xml配置文件 InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml"); // 建立SqlsessionFactory this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); } @Test public void testSaveUser() { // 獲取sqlSession,和spring整合後由spring管理 SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 從sqlSession中獲取Mapper接口的代理對象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setUsername("薩其馬"); user.setSex("2"); user.setBirthday(new Date()); user.setAddress("北京"); // 執行查詢方法 userMapper.saveUser(user); // 至關於 sqlSession.insert("namespace.saveUser", user) // System.out.println(user); sqlSession.commit(); // 和spring整合後由spring管理 sqlSession.close(); } }關於selectOne仍是selectList
動態代理對象調用sqlSession.selectOne()和sqlSession.selectList()是根據mapper接口方法的返回值決定,若是返回list則調用selectList方法,若是返回單個對象則調用selectOne方法。
SqlMapConfig.xml中配置的內容和順序以下:
properties(屬性)
settings(全局配置參數)
typeAliases(類型別名)
typeHandlers(類型處理器)
objectFactory(對象工廠)
plugins(插件)
environments(環境集合屬性對象)
environment(環境子屬性對象)
transactionManager(事務管理)
dataSource(數據源)
mappers(映射器)
1) properties(屬性)
能夠引用java屬性文件中的配置信息,好比前面用到的jdbc.properties
2) typeAliases(類型別名)
咱們前面在傳遞參數,設置類型的時候,都是使用的 包名+類名,這樣比較費勁,那麼能不能像配置基本數據類型或者String同樣來進行配置呢?答案是能夠的,須要利用類型別名。
<typeAliases> <!-- 單個別名定義 --> <typeAlias alias="user" type="com.panlei.pojo.User" /> <!-- 批量別名定義,掃描整個包下的類,別名爲類名(大小寫不敏感) --> <package name="com.panlei.pojo" /> </typeAliases>在sqlMapConfig.xml中利用<typeAliases>的<typeAlias>進行單個別名的定義。當有特別多的類須要定義的時候,一個一個的定義一樣很繁瑣,這就能夠利用<package>來進行統一的配置。
3) mappers(映射器)
<mapper resource=" " />
使用相對於類路徑的資源(如今的使用方式),如:<mapper resource="sqlmap/User.xml" />
<mapper class=" " />
使用mapper接口類路徑,如:<mapper class="com.panlei.mybatis.mapper.UserMapper"/>
注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中。
<package name=""/>
註冊指定包下的全部mapper接口,如:<package name="com.panlei.mybatis.mapper"/>。注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中。
在配置文件的編寫具體語句時,咱們須要傳入一些參數,前面的例子,咱們已經使用了簡單的類型,例如Integer,還有本身定義的POJO的類型,好比咱們自定義的User類型。
還有另一種狀況,就是自定義的類型中有另外一個自定義類型的屬性,好比User中有一個自定義Order類型的屬性,這時咱們須要傳遞POJO包裝對象。下面以一個例子來具體講解:
1)根據用戶名模糊查詢用戶信息,這裏虛設一個只有一個User屬性的包裝類,而後傳遞該包裝類,利用其User屬性的username模糊查詢用戶信息
包裝類
在UserMapper.java中編寫查詢接口方法:
在UserMapper.xml中編寫具體的數據庫查詢代碼,注意四條對應規則(namespace,id,傳參,返回類型):這裏咱們看到傳遞參數的名稱並未使用,而是直接使用了TestUser中的user屬性中的username屬性
編寫測試代碼:
1)輸出簡單類型
測試例子:SELECT COUNT(*) FROM ‘user’
先是在UserMapper接口中定義查詢方法
而後在UserMapper.xml文件中具體編寫查詢語句
測試輸出
2)此外還能夠輸出POJO對象以及POJO的對象列表,這咱們前面已經使用了,再也不詳述
resultType能夠指定將查詢結果映射爲pojo,但須要pojo的屬性名和sql查詢的列名一致方可映射成功。
若是sql查詢字段名和pojo的屬性名不一致,能夠經過resultMap將字段名和屬性名做一個對應關係 ,resultMap實質上還須要將查詢結果映射到pojo對象中。
resultMap能夠實現將查詢結果映射爲複雜類型的pojo,好比在查詢結果映射對象中包括pojo和list實現一對一查詢和一對多查詢。
下面咱們以具體的例子演示:
1) 查詢order表的全部數據
order表的字段及數據以下:這裏的user_id不爲空
而後咱們定義相應的POJO類型,這裏咱們將表中的user_id定義爲userId屬性,模擬字段與屬性不一致的狀況。
爲更好的演示,咱們第一次查詢仍然使用resultType,看一下運行結果,而後再使用resultMap
具體的步驟仍然是建立OrderMapper接口,定義查詢方法,而後在OrderMapper.xml中編寫具體的查詢語句,並設置resultType類型
最終查詢結果輸出以下:能夠看到userId爲null
上面的結果產生緣由就是由於字段與屬性沒有一一對應的緣由。下面咱們使用resultMap進行演示:
只須要修改OrderMapper.xml便可,爲其添加<resultMap>,而後在具體的語句中利用resultMap屬性進行關聯便可,注意裏面的各個屬性的含義。
這裏由於只須要進行user_id與userId的映射,因此其餘屬性能夠不用處理。
而後咱們運行測試,發現userId已經有值了。
經過mybatis提供的各類標籤方法實現動態拼接sql。
需求:根據性別和名字查詢用戶,有時候條件可能爲空,須要進行判斷,爲空就再也不做爲條件
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` WHERE 1=1 <if test="sex != null and sex != ''"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </select>
上面的sql還有where 1=1 這樣的語句,很麻煩
可使用where標籤進行改造
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT id, username, birthday, sex, address FROM `user` <!-- where標籤能夠自動添加where,同時處理sql語句中第一個and關鍵字,也就是刪除 --> <where> <if test="sex != null"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </where> </select>
Sql中可將重複的sql提取出來,使用時用include引用便可,最終達到sql重用的目的。
把上面例子中的id, username, birthday, sex, address提取出來,做爲sql片斷,以下:
<!-- 聲明sql片斷 --> <sql id="userFields"> id, username, birthday, sex, address </sql> <select id="queryUserByWhere" parameterType="user" resultType="user"> <!-- SELECT id, username, birthday, sex, address FROM `user` --> <!-- 使用include標籤加載sql片斷;refid是sql片斷id --> SELECT <include refid="userFields" /> FROM `user` <!-- where標籤能夠自動添加where關鍵字,同時處理sql語句中第一個and關鍵字 --> <where> <if test="sex != null"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </where> </select>若是要使用別的Mapper.xml配置的sql片斷,能夠在refid前面加上對應的Mapper.xml的namespace
<select id="queryUserByWhere" parameterType="user" resultType="user"> SELECT <include refid="com.panlei.mapper.OrderMapper.userFields" /> FROM `user` <!-- where標籤能夠自動添加where關鍵字,同時處理sql語句中第一個and關鍵字 --> <where> <if test="sex != null"> AND sex = #{sex} </if> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> </where> </select>
向sql傳遞數組或List,mybatis使用foreach解析,以下:
根據多個id查詢用戶信息
查詢sql:
SELECT * FROM user WHERE id IN (1,10,24)
對上面用到包裝類添加一個 List<Integer> ids 屬性
UserMapper.xml以下
<!-- 根據ids查詢用戶 --> <select id="queryUserByIds" parameterType="queryVo" resultType="user"> SELECT * FROM `user` <where> <!-- foreach標籤,進行遍歷 --> <!-- collection:遍歷的集合,這裏是QueryVo的ids屬性 --> <!-- item:遍歷的項目,能夠隨便寫,,可是和後面的#{}裏面要一致 --> <!-- open:在前面添加的sql片斷 --> <!-- close:在結尾處添加的sql片斷 --> <!-- separator:指定遍歷的元素之間使用的分隔符 --> <foreach collection="ids" item="item" open="id IN (" close=")" separator=","> #{item} </foreach> </where> </select>測試代碼以下:
@Test public void testQueryUserByIds() { // mybatis和spring整合,整合以後,交給spring管理 SqlSession sqlSession = this.sqlSessionFactory.openSession(); // 建立Mapper接口的動態代理對象,整合以後,交給spring管理 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用userMapper執行根據條件查詢用戶 QueryVo queryVo = new QueryVo(); List<Integer> ids = new ArrayList<>(); ids.add(1); ids.add(10); ids.add(24); queryVo.setIds(ids); List<User> list = userMapper.queryUserByIds(queryVo); for (User u : list) { System.out.println(u); } // mybatis和spring整合,整合以後,交給spring管理 sqlSession.close(); }
需求:查詢全部訂單信息,關聯查詢下單用戶信息。
sql語句:
SELECT o.id, o.user_id userId, o.number, o.createtime, u.username, u.address FROM `order` o LEFT JOIN `user` u ON o.user_id = u.id
方法一:使用resultType
這裏咱們,繼承Order類編寫Order2User類做爲新的pojo類,此pojo類中新增長了訂單信息和用戶信息。這樣返回對象的時候,mybatis自動把用戶信息也注入進來了。
使用OrderMapper接口,並在OrderMapper.xml中添加對應的查詢語句,最後測試。
這裏咱們在sql語句中對數據庫字段的uer_id使用了別名userId,這樣就不須要使用resultMap來進行映射了。
方法二:使用resultMap
這裏直接對Oeder.java進行修改,添加一個User屬性,而後在OrderMapper.xml中創建對應的映射。
需求:查詢全部用戶信息及用戶關聯的訂單信息
sql語句:
SELECT u.id, u.username, u.birthday, u.sex, u.address, o.id oid, o.number, o.createtime, o.note FROM `user` u LEFT JOIN `order` o ON u.id = o.user_id
這裏相似於上面的方法二。修改User類,在UserMapper.xml的配置文件中添加<resultMap>,而後編寫相應查詢語句,最後測試。
一、SqlSessionFactory對象應該放到spring容器中做爲單例存在;
二、傳統dao的開發方式中,應該從spring容器中得到sqlsession對象;
三、Mapper代理形式中,應該從spring容器中直接得到mapper的代理對象;
四、數據庫的鏈接以及數據庫鏈接池事務管理都交給spring容器來完成。
Spring相關jar包:
Spring<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.1.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jms --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-messaging --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>5.1.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.1.4.RELEASE</version> </dependency>MyBatis相關jar包:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency>Spring+mybatis的整合包:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency>Mysql的數據庫驅動jar包:
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency>數據庫鏈接池的jar包:
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency>
1) applicationContext.xml
View Code<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 引入JDBC配置文件 --> <context:property-placeholder location="jdbc.properties"/> <!-- 配置數據庫鏈接池 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 配置數據源 --> <property name="dataSource" ref="dataSource"/> <!-- 配置mybatis核心配置文件 --> <property name="configLocation" value="sqlMapConfig.xml"/> </bean> </beans>2) sqlMapConfig.xml
View Code<?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> <!-- 設置別名 --> <typeAliases> <!-- 2. 指定掃描包,會把包內全部的類都設置別名,別名的名稱就是類名,大小寫不敏感 --> <package name="com.panlei.pojo" /> </typeAliases> </configuration>3) jdbc.properties
View Codejdbc.driverClass=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost/webuser?serverTimezone=GMT%2B8 jdbc.user=root jdbc.password=panlei
4) log4j.properties
View Code# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
這裏的內容前面有所涉及,本次只講解關鍵的內容。
Dao接口與實現類具體代碼再也不展現,注意一點,在dao實現類中由於須要調用對應mapper.xml中的具體sql語句,也就須要SqlSession對象,由於咱們是MyBatis與Spring整合,因此咱們不須要本身去new一個對象了,前面咱們已經在applicationContext.xml中對 SqlSessionFactoryBean 進行了配置,並且在spring與mybaits整合的jar包中對這種必然會使用的操做抽象爲一個類:SqlSessionDaoSupport,咱們須要在具體的Dao實現類中繼承該類,而後使用其中的方法便可,具體以下圖:
還有就是編寫對應的mapper.xml文件,並在sqlMapConfig.xml中加載該文件,最後在applicationContext.xml配置Dao
而後運行測試
這一部分的基礎知識在第4節也有講解,本次也只是講解重要的部分或者沒有涉及的部分。
首先仍是UserMapper接口與UserMapper.xml按規則對應,而後仍是講解一下applicationContext.xml中的配置。
第一種方式是爲每個Mapper接口配置一個<bean>
用到的MapperFactoryBean也是屬於mybatis-spring整合jar包
運行測試
第二種方式是用掃描包的形式配置。第一種方式須要爲每個mapper配置一個<bean>,當數量太多時,顯得太麻煩。這裏能夠不注入SqlSessionFactoryBean,能夠自動注入