傳統的JDBC來作DAO層,作了下面這幾件事:
- 加載驅動
- 獲取鏈接
- 執行SQL語句
- 獲取操做結果封裝信息
- 返回操做結果
而實際上DAO層最關心的是什麼呢,就是後面三點就完事,JDBC顯得太繁瑣:
- 執行SQL語句
- 獲取操做結果封裝信息
- 返回操做結果
因此說MyBatis做爲持久層框架的出現,必然是有一個核心對象來只作上面這些事情,這個對象叫作SqlSession,從命名來講也很貼切了。
那麼SqlSession到底有什麼做用:
- 向SQL語句傳入參數
- 執行SQL語句
- 獲取執行SQL語句的結果
- 事務的控制
那麼如何獲得SqlSession:
- 經過配置文件獲取數據庫鏈接相關信息
- 經過讀取到的配置信息構建SqlSessionFactory
- 經過SqlSessionFactory打開數據庫會話
<!--maven pom-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
public class Demo {
public static void main(String[] args) throws IOException {
//讀取配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//獲取工廠類
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//獲取SqlSession數據庫會話對象
SqlSession sqlSession = factory.openSession();
//...
}
}
這個配置文件 "mybatis-config.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>
<environments default="development">
<environment id="development">
<!-- 使用jdbc事務管理 -->
<transactionManager type="JDBC"/>
<!-- 數據庫鏈接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/dbgirl"/>
<property name="username" value="root"/>
<property name="password" value="dev"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="sqlmapper/GirlMapper.xml"/>
</mappers>
</configuration>
咱們說過,SqlSession能夠執行SQL語句,那麼這個SQL語句又是哪裏來?注意如上的配置文件中 <mapper resource="sqlmapper/GirlMapper.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="dulk.learn.mybatis.dao.GirlDao">
<select id="findById" parameterType="long" resultType="dulk.learn.mybatis.pojo.Girl">
SELECT * FROM girl WHERE id = #{id}
</select>
</mapper>
原來如此,SQL語句直接寫到xml文件中了,咱們經過讀取配置文件來獲取SqlSessionFactory時,數據庫鏈接信息和SQL語句就都是在配置文件裏。既然這兩樣都有了,是否是意味着咱們就能夠直接用了?因此接着以前的Demo咱們是這樣用的,來獲取一個對應數據庫表的Girl對象:
public class Demo {
public static void main(String[] args) throws IOException {
//讀取配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//獲取工廠類
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//獲取SqlSession數據庫會話對象
SqlSession sqlSession = factory.openSession();
//獲取一個對應數據庫表的Girl對象
Girl girl = sqlSession.selectOne("dulk.learn.mybatis.dao.GirlDao.findById", 1L);
}
}
咱們在配置Mapper時,其中<mapper>標籤的 "namespace" 屬性,是爲了限定和隔離不一樣的語句,避免重名。還有一點是, namespace 能夠綁定接口,這意味着假如你的 namespace 的值爲某個接口名(如上例中的 <mapper namespace="dulk.learn.mybatis.dao.GirlDao"> ),那麼你能夠直接經過MyBatis來獲取一個該接口的實例,並調用其方法:
public class Demo {
public static void main(String[] args) throws IOException {
//讀取配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//獲取工廠類
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//獲取SqlSession數據庫會話對象
SqlSession sqlSession = factory.openSession();
//獲取一個對應數據庫表的Girl對象
//Girl girl = sqlSession.selectOne("dulk.learn.mybatis.dao.GirlDao.findById", 1L);
GirlDao girlDao = sqlSession.getMapper(GirlDao.class);
Girl girl = girlDao.findById(1L);
}
}
到這裏,大概已經能看到一些MyBatis的優點了:
- 不須要重複處理註冊驅動,建立鏈接,設置參數等操做
- SQL語句在配置文件中,而不是硬編碼到代碼中
- 傳統JDBC從數據庫獲取數據轉爲對象須要咱們手動從ResultSet中get數據而後set到Java對象中,而MyBatis幫咱們自動進行了轉換
能夠看到,MyBatis是對JDBC數據庫的過程進行了封裝,執行咱們寫好的SQL並將結果映射成Java對象返回:
注:
一、MyBatis底層自定義了Executor執行器接口操做數據庫,Executor接口有兩個實現,一個是基本執行器、一個是緩存執行器
二、MappedStatement也是個底層封裝對象,它包裝了MyBatis配置信息及SQL映射信息等。mapper.xml文件中一個SQL對應一個MappedStatement對象,SQL的id便是MappedStatement的id
三、MappedStatement對SQL執行輸入參數進行定義,包括HashMap、基本類型、POJO,Executor經過MappedStatement在執行SQL前將輸入的Java對象映射至SQL中,輸入參數映射就是JDBC編程中對PreparedStatement設置參數
四、MappedStatement對SQL執行輸出結果進行定義,包括HashMap、基本類型、POJO,Executor經過MappedStatement在執行SQL後將輸出結果映射至Java對象中,輸出結果映射過程至關於JDBC編程中對結果的解析處理過程
參考連接: