1. MyBatis
1.1. 作用
MyBatis是持久層框架,它是支持JDBC的!簡化了持久層開發!
使用MyBatis時,只需要通過接口指定數據操作的抽象方法,然后配置與之關聯的SQL語句,即可完成!
持久化存儲:在程序運行過程中,數據都是在內存(RAM,即內存條)中的,內存中的數據不是永久存儲的,例如程序可以對這些數據進行銷毀,或者由於斷電也會導致內存中所有數據丟失!而把數據存儲到硬盤中的某個文件中,會使得這些數據永久的存儲下來,常見做法是存儲到數據庫中,當然,也可以使用其它技術把數據存儲到文本文件、XML文件等其它文件中!
1.2. 基本使用
1.2.1. 創建項目
使用此前相同的創建流程即可!注意:請檢查有沒有多余的配置,如果有,請刪除,例如在spring.xml
是否存在攔截器的配置!
此次使用MyBatis框架,所以,需要添加新的依賴:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
如果下載的依賴jar包是損壞的,應該先關閉Eclipse,然后刪除對應的jar包文件,再次啟動Eclipse,對項目點擊右鍵,選擇Maven > Update Project,並且在彈出的對話框中勾選
Force Update ...
選項即可。
MyBatis是一個獨立的框架,即只添加該依賴就可以實現持久層編程,但是,開發過程相對比較繁瑣,而實際應用中,通常會與Spring、SpringMVC一起使用,整合使用時,可以簡化大量的配置,使得開發更加簡便!整合時,還需要添加相關依賴:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
整合的SSM框架是基於JDBC的,所以,還需要添加spring-jdbc的依賴:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
添加以上依賴時,直接將此前的spring-webmvc的依賴代碼復制一次,將spring-webmvc改成spring-jdbc即可!凡是Spring官方(Group ID是org.springframework)推出的以spring-作為前綴的依賴,必須使用相同的版本,否則,可能存在不兼容的風險!
在實現過程中,肯定得先建立與數據庫的連接,然后再繼續編程,所以,還應該添加數據源管理的依賴,即數據庫連接池的依賴:
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
由於本次將使用MySQL數據庫,所以,還需要該數據庫的連接驅動的依賴:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.8</version>
</dependency>
1.2.2. 創建數據庫與數據表
創建數據庫tedu_mybatis
:
CREATE DATABASE tedu_mybatis;
創建數據表t_user
:
CREATE TABLE t_user(
id INT AUTO_INCREMENT,
username VARCHAR(20) UNIQUE NOT NULL,
password VARCHAR(20) NOT NULL,
age INT,
phone VARCHAR(20) ,
email VARCHAR(30),
PRIMARY KEY(id)
) DEFAULT CHARSET=UTF8;
1.2.3. 配置數據源
在src\main\resources
下創建db.properties
文件,用於配置與數據庫連接相關的信息:
url=jdbc:mysql://localhost:3306/tedu_mybatis?useUnicode=true&characterEncoding=utf8
driver=com.mysql.jdbc.Driver
username=root
password=root
initialSize=2
maxActive=10
以上配置的值以自己使用的數據庫為准!
以上配置需要被應用到項目中,則在Spring的配置中通過<util:properties />
可以讀取該文件:
<!-- 讀取db.properties -->
<util:properties id="dbconfig"
location="classpath:db.properties" />
最后,需要把這些配置應用到數據源(數據庫連接池)中,當前項目使用的是Apache的commons-dbcp
,則對應的數據源是BasicDataSource
類:
<!-- 配置數據源 -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="url"
value="#{dbconfig.url}" />
<property name="driverClassName"
value="#{dbconfig.driver}" />
<property name="username"
value="#{dbconfig.username}" />
<property name="password"
value="#{dbconfig.password}" />
<property name="initialSize"
value="#{dbconfig.initialSize}" />
<property name="maxActive"
value="#{dbconfig.maxActive}" />
</bean>
完成以上配置后,可以測試到目前為止的配置是否正確,做法就是:獲取BasicDataSource
的對象,調用它的getConnection()
方法,嘗試在Java程序中獲取與數據庫的連接,如果能夠正常連接,則配置無誤,如配置有誤,將無法獲取連接:
@Test
public void getConnection() throws SQLException {
AbstractApplicationContext ac
= new ClassPathXmlApplicationContext(
"spring.xml");
BasicDataSource ds
= ac.getBean("dataSource", BasicDataSource.class);
Connection conn = ds.getConnection();
System.out.println(conn);
ac.close();
}
1.2.4. 通過MyBatis插入數據
MyBatis的編碼模式是:
- 創建接口,並聲明數據訪問的抽象方法;
- 配置與抽象方法對應的XML映射。
首先,創建cn.tedu.mybatis.entity.User
實體類,並添加與t_user
數據表匹配的屬性。
通常,每張數據表都有一個與之匹配的實體類!
創建cn.tedu.mybatis.mapper.UserMapper
接口,並在接口中聲明抽象方法:
Integer insert(User user);
在MyBatis中,執行insert/update/delete操作時,均返回受影響的行數,所以,設計抽象方法時,如果對應的是這幾種操作,返回值均設計為Integer類型。
通常,一個完整的項目中,會存在許多MyBatis的映射文件,為了便於管理,會在src\main\resources
下創建一個名為mappers
的文件夾,然后,下載共享的SomeMapper.zip
,將解壓得到的XML文件復制到剛才創建的mappers
文件夾中:
其實,在mappers
下的映射文件的名稱並不重要!但是,為了便於管理,通常會使用與接口對應的名稱,所以,將SomeMapper.xml
重命名為UserMapper.xml
。
所有映射文件中,根節點都是<mapper>
節點,且該節點必須配置名為namespace
的屬性,屬性值是對應的Java接口,例如:
<mapper namespace="cn.tedu.mybatis.mapper.UserMapper">
</mapper>
經過以上配置,指定了XML映射文件與接口文件的對應關系。
然后,在該文件內部,使用各級子節點配置與抽象方法的對應關系,子節點名稱的選取,取決於要執行的操作的類型,例如要執行的數據操作是insert類型,則使用<insert>
節點,這些節點都必須指定id屬性,屬性值是與之對應的抽象方法的方法名:
<!-- id:抽象方法的名稱 -->
<insert id="insert">
</insert>
在<insert>
節點中,添加parameterType
屬性,用於指定參數的類型,即抽象方法中的參數類型:
<!-- id:抽象方法的名稱 -->
<!-- parameterType:抽象方法中的參數的類型 -->
<insert id="insert"
parameterType="cn.tedu.mybatis.entity.User">
</insert>

然后,在節點內部,編寫需要執行的SQL語句:
<!-- id:抽象方法的名稱 -->
<!-- parameterType:抽象方法中的參數的類型 -->
<insert id="insert"
parameterType="cn.tedu.mybatis.entity.User">
INSERT INTO t_user (
username, password,
age, phone, email
) VALUES (
#{username}, #{password},
#{age}, #{phone}, #{email}
)
</insert>
執行SQL語句時的參數值均使用#{}
類似的語法,其中的名稱是User
類中的屬性名:
1.2.5. 最后的配置
首先,需要配置SqlSessionFactoryBean
,通過它指定數據源與XML映射的文件位置:
<!-- SqlSessionFactoryBean -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定數據源,值為以上配置的數據源 -->
<property name="dataSource"
ref="dataSource" />
<!-- 指定XML映射文件的位置 -->
<property name="mapperLocations"
value="classpath:mappers/*.xml" />
</bean>
以上配置中,XML映射文件的位置使用了mappers/*.xml
,即:在mappers
文件夾下的所有XML文件都應該是MyBatis的映射文件,所以,后續使用時,不可以在這個文件夾中存放其它XML文件。
然后,還需要配置MapperScannerConfigurer
,用於指定接口文件在哪里:
<!-- MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定接口文件的位置 -->
<property name="basePackage"
value="cn.tedu.mybatis.mapper" />
</bean>

至此,配置完成!
1.2.6. 執行單元測試
在src\test\java
下創建測試類,並添加測試方法,以執行測試:
@Test
public void insert() {
// 加載Spring配置文件,獲取Spring容器
AbstractApplicationContext ac
= new ClassPathXmlApplicationContext(
"spring.xml");
// 從Spring容器中獲取對象
// bean-id與接口名一致,首字母為小寫
UserMapper userMapper
= ac.getBean("userMapper", UserMapper.class);
// 測試功能
User user = new User();
user.setUsername("root");
user.setPassword("1234");
Integer rows = userMapper.insert(user);
System.out.println("rows=" + rows);
// 釋放資源
ac.close();
}
1.2.7. 小結
關於配置
使用MyBatis添加了一些新的依賴,及一些配置,這些屬於固定的一次性操作,在后續的項目中,每個項目中只需要做1次即可。
關於這些配置,需要記住配置的作用,及可能需要修改的位置,至少包括:
- db.properties的文件名,因為
<util:properties>
需要使用它; - 在db.properties中配置的值,重點是數據庫名稱、訪問數據庫的密碼,在更換項目或更換計算機后都可能需要調整;
- 在配置
SqlSessionFactoryBean
時指定的映射文件的位置; - 在配置
MapperScannerConfigurer
時指定的接口文件所在的包;
關於開發
- 每張數據表,都應該有1個與之對應的實體類;
- 每種數據(視為每個實體類)的處理都應該有對應的接口文件,例如項目中有
User
實體類,則應該有UserMapper
接口; - 在接口中聲明抽象方法時,如果最終將執行insert/delete/update操作,返回值類型應該是
Integer
; - 每個持久層接口,都應該有對應的XML映射文件,例如有
UserMapper.java
接口,就應該有UserMapper.xml
文件; - 在配置XML文件內部,根據執行操作選擇節點,如果執行的是insert操作,則通過
<insert>
節點進行配置; - 在XML映射中,每個節點都必須配置
id
屬性,取值是接口中抽象方法的名稱,由於id具有唯一的特性,所以,在接口中聲明抽象方法時,不要使用重載; - 在配置SQL語句時,使用
#{}
表示預編譯時的?
對應的值,括號中的名稱是參數名稱,或參數對象中的屬性名稱; - 當執行delete/update時,配置的節點不需要指定
parameterType
屬性。
1.2.7. 刪除指定的數據
設置目標為根據id刪除指定的數據。
先在接口中聲明抽象方法:
Integer deleteUserById(Integer id);
然后,在XML映射中配置以上方法對應的節點:
<delete id="deleteUserById">
DELETE FROM t_user WHERE id=#{id}
</delete>
然后,執行單元測試:
@Test
public void deleteUserById() {
// 加載Spring配置文件,獲取Spring容器
AbstractApplicationContext ac
= new ClassPathXmlApplicationContext(
"spring.xml");
// 從Spring容器中獲取對象
// bean-id與接口名一致,首字母為小寫
UserMapper userMapper
= ac.getBean("userMapper", UserMapper.class);
// 測試功能
Integer id = 3;
Integer rows = userMapper.deleteUserById(id);
System.out.println("rows=" + rows);
// 釋放資源
ac.close();
}
-------------------------------