花了差不多20天的時間把Spring和SpringMVC差不多入了個門,今天庸队,開始學(xué)持久化框架MyBatis积蜻,雖然之前也用過,但是沒能系統(tǒng)的學(xué)過彻消,從今天起竿拆,認真學(xué)習(xí),認真總結(jié)
一宾尚、什么是 MyBatis 丙笋?
官方博客是這么說的:MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL煌贴、存儲過程以及高級映射御板。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設(shè)置參數(shù)以及獲取結(jié)果集。MyBatis 可以使用簡單的 XML 或注解來配置和映射原生信息牛郑,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數(shù)據(jù)庫中的記錄怠肋。
簡單的來說,就是之前將數(shù)據(jù)庫表中的字段與 JavaBean 的屬性相映射淹朋,同時笙各,Sql 語句可以不用嵌在代碼中,而只需要寫在 XML 配置文件中
二础芍、如何使用 Mybatis 杈抢?
2.1 所需架包
- mybatis-3.4.6.jar
- mysql-connector-java-5.1.41.jar
- log4j-1.2.17.jar
2.2 配置文件
①. log4j.properties
配置 log4j 日志文件
# Global logging configuration
# developer-->DEBUG productor-->INFO or ERROR
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# 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
由于 MyBatis 需要依賴 log4j, 因此首先新建一個 log4j.properties
配置文件仑性,日志級別設(shè)置為 DEBUG
②. mybatis-config.xml
作為全局配置文件惶楼,包含獲取數(shù)據(jù)庫連接實例的數(shù)據(jù)源 DataSource
和決定事務(wù)作用域和控制方式的事務(wù)管理器 TransactionManager
,這些都可以在全局配置文件中設(shè)置虏缸。
當然鲫懒,我們同樣可以像之前配置 c3p0 那樣,把配置信息以鍵值對的方式儲存在類路徑下的配置文件中刽辙,這會在后面做演示
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?useSSL=false" />
<property name="username" value="root" />
<property name="password" value="lwh011305" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mymapper.xml" />
</mappers>
</configuration>
<mapper>
中引用 sql 映射文件窥岩,這在后面也會詳細講述
2.3 編寫代碼
首先得有一個 POJO 類,這里我定義的是 Employee.java
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
...
}
當然只列舉了部分
①. 從 XML 中構(gòu)建 SqlSessionFactory
這里我參照的是 MyBatis 官方文檔給出的代碼宰缤,我先寫一個獲取 SqlSessionFactory
對象的類颂翼,該類返回的是 SqlSessionFactory
的實例
private SqlSessionFactory getSqlSessionFactoty() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}
這里使用類路徑下的資源文件進行配置,該資源文件是全局配置慨灭。
②. 從 SqlSessionFactory 中獲取 SqlSession
SqlSession
包含了面向數(shù)據(jù)庫執(zhí)行 SQL 命令所需的所有方法朦乏,包括增、刪氧骤、改呻疹、查等等
selectOne(String statement, Object parameter)
statement
:sql 唯一標識, 即對應(yīng) mymapper.xml
中設(shè)置的 id 值
parameter
:執(zhí)行 sql 要使用的參數(shù),比如 id筹陵,name 等等
@Test
void test() throws IOException {
//1. 根據(jù) xml 配置文件(全局配置文件)創(chuàng)建一個 SqlSessionFactory
SqlSessionFactory sqlSessionFactory = getSqlSessionFactoty();
//2. 獲取 sqlSession 實例, 能直接執(zhí)行已經(jīng)映射的 sql 語句
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
Employee employee = sqlSession.selectOne("emp", 3);
System.out.println(employee);
} finally {
sqlSession.close();
}
}
可以看到刽锤,上面的 selectOne
方法的第一個參數(shù)已經(jīng)設(shè)定镊尺,這是因為我已經(jīng)配置好了 sql 映射文件 mymapper.xml
<?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">
<mapper namespace="ee">
<select id="emp" resultType="edu.just.mybatis.Employee">
select id, last_name lastName, email, gender from Employee where id = #{id}
</select>
</mapper>
介紹一下配置文件的參數(shù)(當然,這只是最基本的幾個參數(shù)并思,更加詳細的介紹會在之后文章)
namespace
:命名空間庐氮,這種方式可以隨意設(shè)置命名空間的值
id
:標識映射文件中的sql,SqlSession 的 selectOne
的第一個參數(shù)就是對應(yīng)的這個 id
#{id}
:從傳遞過來的參數(shù)中獲取 id 值宋彼,類似于 jdbc 中的 “?”
resultType
:指定輸出結(jié)果的類型弄砍,即查詢結(jié)果所映射的java對象,這里返回的對象是 Employee
以下是這段代碼的執(zhí)行流程:
- 根據(jù)全局配置文件(mybatis-config.xml), 創(chuàng)建一個 SqlSessionFactory 對象, 該配置文件包含數(shù)據(jù)源的配置信息
- sql 映射文件(mymapper.xml), 用來寫 sql 語句, 配置了每一個 sql, 以及 sql 的封裝規(guī)則
- 將 sql 映射文件注冊在全局配置文件中
- 1). 根據(jù)全局配置文件得到 SqlSessionFactory
2).使用 SqlSessionFactory, 獲取到 sqlSession 對象, 并使用該對象來執(zhí)行增刪改查操作输涕,一個 sqlSession 就是代表和數(shù)據(jù)庫的一次會話, 用完關(guān)閉
3).使用 sql 的唯一標志(配置文件的 id 屬性)來告訴 mybatis 執(zhí)行哪個 sql. 語句都是保存在 sql 映射文件中的
但是音婶,官方還給我們提供了另外一種方式,接口式編程莱坎。即在接口里面定義對數(shù)據(jù)庫的各種操作方式桃熄,然后將接口類名對應(yīng)到 sql 配置文件的命名空間中(namespace)
我們先寫一個接口類
public interface EmployeeMapper {
public Employee getEmployee(Integer id);
}
把接口類映射到 sql 配置文件的 namespace
中,id
即為接口中的方法名型奥,這里是 getEmployee,resultType
即運行語句返回的對象碉京,這里是 Employee
<?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">
<mapper namespace="edu.just.mybatis.dao.EmployeeMapper">
<select id="getEmployee" resultType="edu.just.mybatis.Employee">
select id, last_name lastName, email, gender from Employee where id = #{id}
</select>
</mapper>
接下來寫測試代碼
@Test
void test2() throws IOException {
//1. 獲取 sqlSessionFactory 對象
SqlSessionFactory sqlSessionFactory = getSqlSessionFactoty();
//2. 獲取 sqlSession 對象
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//3. 獲取接口的實現(xiàn)類對象, 會為接口自動創(chuàng)建一個代理對象, 代理對象去執(zhí)行增厢汹、刪、改谐宙、查
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = employeeMapper.getEmployee(1);
System.out.println(employee);
} finally {
sqlSession.close();
}
}
流程:
- 接口式編程
原生:Dao ====> DaoImpl
如今:Mapper ====> xxMapper.xml - SqlSession 代表和數(shù)據(jù)庫的一次會話, 用完必須關(guān)閉
- SqlSession 和 Connection 一樣, 都是非線程安全的, 每次使用都應(yīng)該去獲取新的對象烫葬,如
private SqlSession sqlSession
這種共享的對象, 不應(yīng)該使用 - mapper 接口沒有實現(xiàn)類, 但是 mybatis 會為這個接口生成一個代理對象(接口與 xml 進行綁定),即
sqlSession.getMapper(EmployeeMapper.class)
- 兩個重要的配置文件
mybatis-config.xml: mysql
:全局配置文件, 包含數(shù)據(jù)庫連接池信息, 事務(wù)管理器信息等
mymapper.xml: sql
:映射文件, 保存了每一個 sql 語句的映射信息. 將 sql 語句抽取出來