字節(jié)跳動(dòng)飛書(shū)內(nèi)推厕怜!
北京衩匣、杭州蕾总、武漢、廣州琅捏、深圳生百、上海,六大城市等你來(lái)投午绳。
感興趣的朋友可以私我咨詢&內(nèi)推置侍,也可以通過(guò)鏈接直接投遞!
海量HC拦焚,極速響應(yīng)蜡坊,快來(lái)和我成為同事吧。
今日頭條赎败、抖音丛肢、Tik Tok也可以內(nèi)推~
點(diǎn)擊進(jìn)入我的博客
MyBatis詳解1.概述
MyBatis詳解2.MyBatis使用入門(mén)
MyBatis詳解3.MyBatis配置詳解
MyBatis詳解4.映射器Mapper
MyBatis詳解5.動(dòng)態(tài)SQL
MyBatis詳解6.MyBatis技術(shù)內(nèi)幕
MyBatis詳解7.插件
MyBatis詳解8.集成Spring
1 MyBatis的結(jié)構(gòu)
- SqlSessionFactoryBuilder(構(gòu)造器):它會(huì)根據(jù)配置信息或者代碼來(lái)生成SqISessionFactory。
- SqISessionFactory(工廠接口):依靠工廠來(lái)生成SqlSession
- SqlSession(會(huì)話):是一個(gè)既可以發(fā)送SQL去執(zhí)行并返回結(jié)果纠屋,也可以獲取 Mapper的接口岖圈。
- SQL Mapper:它是MyBatis新設(shè)計(jì)的組件,它是由一個(gè)Java接口和XML文件(或注解)構(gòu)成的搞糕,需要給出對(duì)應(yīng)的SQL和映射規(guī)則勇吊。它負(fù)責(zé)發(fā)送SQL去執(zhí)行,并返回結(jié)果窍仰。
2 構(gòu)建SqISessionFactory
每個(gè)MyBatis應(yīng)用都是以SqlSessionFactory的實(shí)例為中心的汉规。 SqlSessionFactory的實(shí)例可以通過(guò)SqlSessionFactoryBuilder獲得。MyBatis提供了兩種模式去創(chuàng)建SqlSessionFactory:基于XML配置的方式和基于代碼的方式驹吮。
Configuration類
Configuration類對(duì)象保存著我們配置在MyBatis的信息针史,這個(gè)對(duì)象將存在于整個(gè)MyBatis應(yīng)用的生命期中,以便重復(fù)讀取和運(yùn)用碟狞。我們可以解析一次配置的XML文件保存到Configuration類對(duì)象中啄枕,方便我們從這個(gè)對(duì)象中讀取配置信息。
兩個(gè)SqlSessionFactory的實(shí)現(xiàn)類
在MyBatis中提供了兩個(gè)SqlSessionFactory的實(shí)現(xiàn)類族沃,DefaultSqlSessionFactory和SqlSessionManager频祝。不過(guò)SqlSessionManager目前還沒(méi)有使用,MyBatis中目前使用的是DefaultSqlSessionFactory脆淹。
2.1 通過(guò)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>
<!-- 配置每個(gè)DO的別名 -->
<typeAliases>
<typeAlias type="com.ankeetc.spring.domain.UserDomain" alias="user"/>
</typeAliases>
<!-- 配置環(huán)境內(nèi)容 -->
<environments default="dev">
<environment id="dev">
<!-- 采用JDBC的事務(wù)管理模式 -->
<transactionManager type="JDBC"/>
<!-- 數(shù)據(jù)庫(kù)的連接信息 -->=
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 配置映射器 -->
<mappers>
<mapper resource="mappers/TbNameMapper.xml"/>
</mappers>
</configuration>
public SqlSessionFactory getSqlSessionFactory() throws Exception {
// 獲取config源文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 通過(guò)SqlSessionFactoryBuilder構(gòu)造
return new SqlSessionFactoryBuilder().build(is);
}
2.2 通過(guò)編碼方式
public SqlSessionFactory getSqlSessionFactory() throws Exception {
// 構(gòu)建數(shù)據(jù)庫(kù)連接池
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
// 構(gòu)建數(shù)據(jù)庫(kù)事務(wù)模式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
// 創(chuàng)建數(shù)據(jù)庫(kù)運(yùn)行環(huán)境
Environment environment = new Environment("dev", transactionFactory, dataSource);
// 創(chuàng)建 Configuration 對(duì)象
Configuration configuration = new Configuration(environment);
// 配置MyBatis上下文別名
configuration.getTypeAliasRegistry().registerAlias("user", UserDomain.class);
// 配置映射器
configuration.addMapper(TbNameMapper.class);
// 使用SqlSessionFactoryBuilderg構(gòu)建SqlSessionFactory
return new SqlSessionFactoryBuilder().build(configuration);
}
3 創(chuàng)建SqlSession
SqlSession是一個(gè)接口類智润,扮演著門(mén)面的作用,而真正干活的是Executor接口未辆。只需要SqlSession參數(shù)信息和執(zhí)行的方法窟绷,然后等待返回的結(jié)果,而不需要關(guān)心Executor是怎么工作的咐柜。
SqlSession的兩個(gè)實(shí)現(xiàn)類
- DefaultSqlSession
- SqlSession
SqlSession的用法
SqlSession接口類似于一個(gè)JDBC中的Connection接囗對(duì)象兼蜈,我們需要保證每次用完正常關(guān)閉它攘残。正確的做法是把關(guān)閉SqlSession接口的代碼寫(xiě)在finally句中保證每次都會(huì)
關(guān)閉SqlSession,讓連接資源歸還給數(shù)據(jù)庫(kù)为狸。
public void func(SqlSessionFactory sqlSessionFactory) {
// 打開(kāi)SqlSession會(huì)話
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
// doSomething()
sqlSession.commit();
} catch (Exception e) {
// handle Exception
}
}
SqlSession的用途
- 獲取映射器歼郭,讓映射器通過(guò)命名空間和方法名稱找到對(duì)應(yīng)的SQL,發(fā)送給數(shù)據(jù)庫(kù)執(zhí)行后返回結(jié)果辐棒。
- 直接通過(guò)命名信息去執(zhí)行SQL返回結(jié)果病曾,這是 iBatis版本留下的方式。在SqlSession層我們可以通過(guò)update漾根、insert泰涂、select、delete等方法辐怕,帶上SQL的id來(lái)操作在XML中配置好的SQL逼蒙,從而完成我們的工作;與此同時(shí)它也支持事務(wù)寄疏,通過(guò) commit是牢、rollback方法提交或者回滾事務(wù)。
4 映射器
映射器的作用
映射器是由Java接口和XML文件(或注解)共同組成的陕截,作用如下:
- 定義參數(shù)類型驳棱。
- 描述緩存。
- 描述SQL語(yǔ)句农曲。
- 定義查詢結(jié)果和POJO的映射關(guān)系
映射器的兩種實(shí)現(xiàn)方式有兩種
- 通過(guò)XML文件方式實(shí)現(xiàn)蹈胡,
- 通過(guò)代碼方式實(shí)現(xiàn),在Configuration里面注冊(cè)Mapper接口
4.1 XML方式實(shí)現(xiàn)Mapper
- 定義了一個(gè)XML Mapper文件朋蔫,而且在配置文件mybatis-config.xml中配置了的該文件,所以 MyBatis會(huì)讀取這個(gè)配置文件却汉,生成映射器驯妄。
- 定義了一個(gè)命名空間為 com.ankeetc.spring.mapper.TbNameMapper 的SQL Mapper,這個(gè)命名空間和我們定義的接口的全限定名是一致的合砂。
- 定義了一個(gè)select元素青扔,id和接口方法名
UserDomain select(Long id)
是一致的,parameterType則表示我們傳遞給這條SQL的是一個(gè)Long型參數(shù)翩伪,resultType則定義我們需要返回的數(shù)據(jù)類型微猖。
<?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.ankeetc.spring.mapper.TbNameMapper">
<select id="select" resultType="com.ankeetc.spring.domain.UserDomain" parameterType="java.lang.Long">
SELECT * FROM tb_name WHERE id = #{id}
</select>
</mapper>
public interface TbNameMapper {
UserDomain select(Long id);
}
public static void func(SqlSessionFactory sqlSessionFactory) {
// 打開(kāi)SqlSession會(huì)話
try (SqlSession sqlSession = sqlSessionFactory.openSession()){
// 獲取映射器Mapper
TbNameMapper tbNameMapper = sqlSession.getMapper(TbNameMapper.class);
// 執(zhí)行查詢
UserDomain userDomain = tbNameMapper.select(18L);
System.out.println(userDomain.getName());
sqlSession.commit();
} catch (Exception e) {
// handle Exception
}
}
4.2 注解方式實(shí)現(xiàn)Mapper
public interface TbNameMapper2 {
@Select("SELECT * FROM tb_name WHERE id = #{id}")
UserDomain select(Long id);
}
在使用注解時(shí),要向SqlSessionFactory中手動(dòng)添加Mapper
public SqlSessionFactory getSqlSessionFactory() throws Exception {
// 在使用注解時(shí)缘屹,要向SqlSessionFactory中手動(dòng)添加Mapper
configuration.addMapper(TbNameMapper.class);
//
}
4.3 Mapper實(shí)現(xiàn)方式簡(jiǎn)述
我們使用的僅僅是Java接口和一個(gè)XML文件(或者注解)去實(shí)現(xiàn) Mapper凛剥,一個(gè)沒(méi)有實(shí)現(xiàn)類的接口怎么能夠運(yùn)行呢?這里其實(shí)是運(yùn)用到Java語(yǔ)言的動(dòng)態(tài)代理去實(shí)現(xiàn)轻姿,而實(shí)現(xiàn)Java語(yǔ)言的動(dòng)態(tài)代理的方式有多種犁珠。這里我們還是集中于它的用法逻炊,所以可以這樣理解:我們會(huì)在 MyBatis 上下文中描述這個(gè)接口,而MyBatis會(huì)為這個(gè)接口生成代理類對(duì)象犁享,代理對(duì)象會(huì)根據(jù)“接口全路徑+方法名”去匹配,找到對(duì)應(yīng)的XML文件(或注解)去完成它所需要的任務(wù)余素,返回我們需要的結(jié)果。
5 生命周期
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是利用XML或者Java編碼獲得資源來(lái)構(gòu)建SqlSessionFactory的炊昆,一旦我們構(gòu)建了SqlSessionFactory桨吊,它的作用就已經(jīng)完結(jié),所以它的生命周期只存在于方法的局部凤巨。
SqlSessionFactory
SqlSessionFactory的作用是創(chuàng)建SqlSession视乐,而SqlSession就是一個(gè)會(huì)話,每次訪問(wèn)數(shù)據(jù)庫(kù)都需要通過(guò)SqlSessionFactory創(chuàng)建SqlSession磅甩,所以SqlSessionFactory應(yīng)該在 MyBatis應(yīng)用的整個(gè)生命周期中炊林。而且SqlSessionFactory我們只是用它來(lái)創(chuàng)建SqlSession,只需要一個(gè)示例卷要,所以需要用采用單例模式渣聚。
public synchronized SqlSessionFactory initSqlSessionFactory() {
try {
if (sqlSessionFactory == null) {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
}
return sqlSessionFactory;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
SqlSession
SqlSession是一個(gè)會(huì)話,它的生命周期應(yīng)該是在請(qǐng)求數(shù)據(jù)庫(kù)處理事務(wù)的過(guò)程中僧叉。它是一個(gè)線程不安全的對(duì)象奕枝,在涉及多線程的時(shí)候我們需要特別的當(dāng)心,操作數(shù)據(jù)庫(kù)需要注意其隔離級(jí)別瓶堕,數(shù)據(jù)庫(kù)鎖等高級(jí)特性隘道。每次創(chuàng)建的SqlSession都必須及時(shí)關(guān)閉它。
Mapper
Mapper是一個(gè)接口郎笆,它的作用是發(fā)送SQL然后返回我們需要的結(jié)果谭梗;或者執(zhí)行SQL從而修改數(shù)據(jù)庫(kù)的數(shù)據(jù)。因此它應(yīng)該在一個(gè)SqlSession事務(wù)方法之內(nèi)宛蚓,是一個(gè)方法級(jí)別的東西激捏。