Mybatis的核心組件
- SqlSessionFactoryBuild(構造器):它會根據配置或者代碼來生成SqlSessionFactory,採用的是分佈構建Builder模式。
這部分代碼返回一個 SqlSessionFactory對象 - SQLSessionFactory(工廠接口):依靠他來生成SqlSession,使用的是工廠模式。
- SqlSession(會話):一個既可以發送SQL執行返回結果,也可以獲取Mapper的接口。在現有的技術中,一般我們會讓其在業務邏輯代碼中“消失”,而使用的是Mybatis提供的SQL Mapper接口編程技術,它能提高代碼的可閱性和可維護性。
- SQL Mapper(映射器):Mybatis新設計存在的組件,它有一個Java接口和XML文件構成(還可以由註解完成,個人用的都是XML),需要給出對應的SQL和映射規則。它賦值發送SQL執行,並返回結果。
- 運行流程 SqlSessionFactoryBuild(構造器)—>(通過配置或者代碼)—>SqlSessionFactory(工廠接口)—>SqlSession(會話)---->(發送SQL語句)—>SQL Mapper(映射器)----->數據庫
這裏附上代碼,來自於書《Java EE互聯網輕量型級框架整合開發》
鏈接:https://pan.baidu.com/s/1X6-NlcybWaXTA0Gl0jVJlw
提取碼:zswh
SqlSessionFactory(工廠接口)
在Mybatis中,可以通過xml文件生成SqlSession,也可以通過Java代碼形式去生成SqlSessionFactory。
XMl構建SqlSessionFactory
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>
<typeAliases><!-- 別名 -->
<typeAlias alias="role" type="com.learn.ssm.chapter3.pojo.Role"/>
</typeAliases>
<!-- 數據庫環境 -->
<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/chapter3"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件 -->
<mappers>
<mapper resource="com/learn/ssm/chapter3/mapper/RoleMapper.xml"/>
<mapper class="com.learn.ssm.chapter3.mapper.RoleMapper2"/>
</mappers>
</configuration>
Mybatis基礎配置文件:
- < typeAlias>元素定義了一個別名role,它代表着com.learn.ssm.chapter3.pojo.Role這個類。定義完以後,可以在Mybatis的上下文使用別名去替代全限定名了。
- < environment>元素的定義,這裏描述的是數據庫。它裏面的元素是配置事務管理器.
dataSource元素配置數據庫,其中屬性type=“POOLED”代表採用Mybatis內部提供了連接池方式。最後定義了一些JDBC的屬性信息。 - < mapper> 元素代表引入的那些映射器
通過讀取配置文件mybatis-config.xml然後通過SqLSessionFactoryBuilder的Builder方法去創建SqlSessionFactory。在Mybatis中,採用Builder模式爲開發者隱藏了這部分細節,只需重點SqlSessionFactory被創建出來,就好了。
SqlSession
在使用XML配置免去了我們創建SQLSessionFactory,下一步我們去創建SqlSession。我們先去了解一下SqLSession
在Mybatis中,SqlSession是其中核心接口。在Mybatis中有兩個實現類,DefaultSqlSession和SqlSessionManager。DefaultSqlSession是單線程使用的,而SqlSessionManager在多線程環境下使用。SqlSession的作用類似於一個JDBC中的Connection對象,代表着一個連接資源的啓用,具體功能有3個:
- 獲取Mapper接口
- 發送SQL給數據庫
- 控制數據庫事務
映射器
映射器是Mybatis中最重要、最複雜的組件,它由一個接口對應的XML文件或註解組成。提供以下功能
- 描述映射規則
- 提供SQL語句,並可以配置SQL參數類型、返回類型、緩存刷新等信息
- 配置緩存
- 提供動態SQL
寫一個例子來實現,pojo類 Role
public class Role{
private Long id;
private String roleName;
private String note;
}
使用XML實現映射器
映射器接口:RoleMapper
public interface RoleMaper{
public int insertRole(Role role);
public int deleteRole(Long id);
public int updateRole(Role role);
public Role getRole(Long id);
public List<Role> findRoles(String roleName);
}
配置XML
<mapper resource="com.sx.Mapper.UserMapper.xml">
實現UserMapper接口,UserMapper.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="com.learn.ssm.chapter3.mapper.RoleMapper">
<insert id="insertRole" parameterType="role">
insert into t_role(role_name, note) values(#{roleName}, #{note})
</insert>
<delete id="deleteRole" parameterType="long">
delete from t_role where id= #{id}
</delete>
<update id="updateRole" parameterType="role">
update t_role set role_name = #{roleName}, note = #{note} where id= #{id}
</update>
<select id="getRole" parameterType="long" resultType="role">
select id,
role_name as roleName, note from t_role where id = #{id}
</select>
</mapper>
這樣就完成了一個映射器,先看XML屬性
- < mapper >元素中的屬性namespace所對應的是一個接口的全限定名,於是Mybatis上下文就可以通它找到相對應的接口。
- < select >元素表名這是一條查詢語句,而屬性id標識了這條SQL,屬性parameterType="long"說明傳遞給SQL的是一個long型參數,而resultType=“role”表示了返回的是Role類的對象。而role是之前配置文件mybatis-config.xml配置的別名。
- 這條SQL語句中的#{id}表示傳遞進去的參數。
Mybatis基於XML配置文件創建Configuration對象的過程
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourcesAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
SqlSession sqlSession = sqlSessionFactory.openSession();
1、在這段代碼中,SqlSessionFactoryBuild對象先是執行build()
2、根據配置信息創建一個XMLConfigBuilder對象
3、SqlSessionFactoryBuilder調用XMLConfigBuilder對象的parser()方法
4、XMLConfigBuilder對象返回一個Configuration對象
5、SqlSessionFactoryBuilder對象的build(Configuration config)方法返回一個DefaultSqlSessionFactory對象
SqlSessionFactoryBuild代碼:
public class SqlSessionFactoryBuilder {
public SqlSessionFactoryBuilder() {
}
public SqlSessionFactory build(Reader reader) {
return this.build((Reader)reader, (String)null, (Properties)null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return this.build((Reader)reader, environment, (Properties)null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return this.build((Reader)reader, (String)null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException var13) {
}
}
return var5;
}
public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return this.build((InputStream)inputStream, environment, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return this.build((InputStream)inputStream, (String)null, properties);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException var13) {
}
}
return var5;
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}