【精選】框架初探篇之——MyBatis入門必知【面試常問】
什么是MyBatis?

MyBatis是一個半自動的ORM框架,其本質(zhì)是對JDBC的封裝。使用MyBatis不需要寫JDBC代碼,但需要程序員編寫SQL語句。之前是apache的一個開源項目iBatis,2010年改名為MyBatis。
補充:
Hibernate也是一款持久層ORM框架,多年前的市場占有率很高,但近年來市場占有率越來越低。
MyBatis與Hibernate的比較:
- MyBatis是一個半自動的ORM框架,需要手寫SQL語句。
- Hibernate是一個全自動的ORM框架,不需要手寫SQL語句。
- 使用MyBatis的開發(fā)量要大于Hibernate。
為什么Hibernate市場占有率越來越低:
- 對于新手學習Hibernate時間成本比MyBatis大很多,MyBatis上手很快。
- Hibernate不需要寫SQL語句是因為框架來生成SQL語句。對于復雜查詢,開發(fā)者很難控制生成的SQL語句,這就導致SQL調(diào)優(yōu)很難進行。
- 之前的項目功能簡單,數(shù)據(jù)量小,所以使用Hibernate可以快速完成開發(fā)。而近年來項目的數(shù)據(jù)量越來越大,而互聯(lián)網(wǎng)項目對查詢速度要求也很高,這就要求我們一定要精細化的調(diào)整SQL語句。此時靈活性更強,手動編寫SQL語句的MyBatis慢慢代替了Hibernate使用。
- 在高并發(fā)、大數(shù)據(jù)、高性能、高響應的互聯(lián)網(wǎng)項目中,MyBatis是首選的持久框架。而對于對性能要求不高的比如內(nèi)部管理系統(tǒng)等可以使用Hibernate。
MyBatis入門
環(huán)境搭建
-
將SQL文件導入數(shù)據(jù)庫
-
創(chuàng)建maven工程,引入依賴
<dependencies> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- mysql驅動包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <!-- log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> </dependencies> -
創(chuàng)建mybatis核心配置文件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> <!-- 配置環(huán)境 --> <environments default="mysql"> <environment id="mysql"> <!-- 事務類型 --> <transactionManager type="JDBC"></transactionManager> <!-- 數(shù)據(jù)源 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///mybatis"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> </configuration> -
將log4j.properties文件放入resources中,讓控制臺打印SQL語句。
-
創(chuàng)建實體類
public class User { private int id; private String username; private String sex; private String address; // 省略getter/setter/構造方法/toString方法 }
創(chuàng)建持久層接口和映射文件
-
在java目錄創(chuàng)建持久層接口
public interface UserMapper { List<User> findAll(); } -
在resource目錄創(chuàng)建映射文件
<?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="com.java.mapper.UserMapper"> <select id="findAll" resultType="com.java.pojo.User"> select * from user </select> </mapper> -
將映射文件配置到mybatis核心配置文件中
<!-- 注冊映射文件 --> <mappers> <mapper resource="com/java/mapper/UserMapper.xml"> </mapper> </mappers>
映射文件注意事項:
映射文件要和接口名稱相同。
映射文件要和接口的目錄結構相同。
映射文件中
namespace屬性要寫接口的全名。映射文件中標簽的
id屬性是接口方法的方法名。映射文件中標簽的
resultType屬性是接口方法的返回值類型。映射文件中標簽的
parameterType屬性是接口方法的參數(shù)類型。映射文件中
resultType、parameterType屬性要寫全類名,如果是集合類型,則寫其泛型的全類名。
測試持久層接口方法
@Test
public void testFindAll() throws Exception {
// (1)讀取核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// (2)創(chuàng)建SqlSessionFactoryBuilder對象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// (3)SqlSessionFactoryBuilder對象獲取SqlSessionFactory對象
SqlSessionFactory factory = builder.build(is);
// (4)SqlSessionFactory對象獲取SqlSession對象
SqlSession session = factory.openSession();
// (5)SqlSession對象獲取代理對象
UserMapper userMapper = session.getMapper(UserMapper.class);
// (6)代理對象執(zhí)行方法
List<User> all = userMapper.findAll();
all.forEach(System.out::println);
// (7)釋放資源
session.close();
is.close();
}
MyBatis核心對象及工作流程

MyBatis核心對象
-
SqlSessionFactoryBuilder
SqlSession 工廠構建者對象,使用構造者模式創(chuàng)建SqlSession工廠對象。
-
SqlSessionFactory
SqlSession工廠,使用工廠模式創(chuàng)建SqlSession對象。
-
SqlSession
該對象可以操作數(shù)據(jù)庫,也可以使用動態(tài)代理模式創(chuàng)建持久層接口的代理對象操作數(shù)據(jù)庫。
-
Mapper
持久層接口的代理對象,他具體實現(xiàn)了持久層接口,用來操作數(shù)據(jù)庫。
MyBatis工作流程
- 創(chuàng)建SqlSessionFactoryBuilder對象
- SqlSessionFactoryBuilder對象構建了SqlSessionFactory對象:構造者模式
- SqlSessionFactory對象生產(chǎn)了SqlSession對象:工廠模式
- SqlSession對象創(chuàng)建了持久層接口的代理對象:動態(tài)代理模式
- 代理對象操作數(shù)據(jù)庫
使用SqlSession操作數(shù)據(jù)庫
除了代理對象能夠操作數(shù)據(jù)庫,SqlSession也能操作數(shù)據(jù)庫。只是這種方式在開發(fā)中使用的較少,接下來我們使用SqlSession操作數(shù)據(jù)庫:
@Test
public void testFindAll2() throws Exception {
// (1)讀取核心配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// (2)創(chuàng)建SqlSessionFactoryBuilder對象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// (3)SqlSessionFactoryBuilder對象獲取SqlSessionFactory對象
SqlSessionFactory factory = builder.build(is);
// (4)SqlSessionFactory對象獲取SqlSession對象
SqlSession session = factory.openSession();
// (5)SqlSession直接操作數(shù)據(jù)庫
List<User> users = session.selectList("com.java.mapper.UserMapper.findAll");
users.forEach(System.out::println);
// (6)關閉資源
session.close();
is.close();
}
Mapper動態(tài)代理原理
Mapper動態(tài)代理:
- SqlSession的getMapper方法,最終是調(diào)用的是JDK動態(tài)代理方法,生成一個代理對象,類型就是傳入的接口類型。
- MapperProxy對象通過調(diào)用MapperMethod的execute方法定義了代理方式,該方法的底層調(diào)用的是SqlSession的方法。

浙公網(wǎng)安備 33010602011771號