本文目標
- 掌握MyBatis基礎組件及其使用台丛、MyBatis的使用方法
- 掌握基礎組件的生命周期及其實現(xiàn)方法
- 掌握入門實例
MyBatis優(yōu)點
- 不屏蔽SQL丰刊,可以對其進行優(yōu)化和改造
- 提供強大笋额、靈活的映射機制冯袍。提供動態(tài)SQL的功能
- 提供了使用Mapper的接口編程犬钢,只要一個接口和一個XML就能創(chuàng)建映射器
MyBatis的核心組件
- SqlSessionFactoryBuilder(構造器): 它會根據(jù)配置或者代碼來生成SqlSessionFactory苍鲜,采用的是分步構建的Builder模式
- SqlSessionFactory(工廠接口):依靠它來生成SqlSession,使用的是工廠模式
- SqlSession(會話):一個既可以發(fā)送SQL執(zhí)行返回結果玷犹,也可以獲取Mapper的接口
- SQL Mapper(映射器): 它由一個Java接口和XML文件(或注解)構成混滔。
SqlSessionFactory
在MyBatis中,即可以通過讀取配置的XML文件也可以通過Java代碼的形式去生成SqlSessionFactory歹颓。
XML構建SqlSessionFactory
<!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.whyalwaysmea.pojo.Role"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事務管理器 -->
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<!-- 配置數(shù)據(jù)庫 POOLED代表采用MyBatis內部提供的連接池方式 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件 -->
<mappers>
<mapper resource="com/whyalwaysmea/config/sqlxml/RoleMapper.xml"/>
</mappers>
</configuration>
生成SqlSessionFactory
String resource = "com/whyalwaysmea/config/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
Java代碼創(chuàng)建SqlSessionFactory
// 數(shù)據(jù)庫連接池信息
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
// 是否自動提交
dataSource.setDefaultAutoCommit(false);
JdbcTransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
// 創(chuàng)建Configuration對象
Configuration configuration = new Configuration(environment);
// 注冊一個MyBatis上下文別名
configuration.getTypeAliasRegistry().registerAlias("role", Role.class);
// 加入一個映射器
configuration.addMapper(RoleMapper.class);
// 使用SqlSessionFactoryBuilder構建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration)
通過比較兩種方式坯屿,可以發(fā)現(xiàn)使用Java代碼生成SqlSessionFactory的方式代碼冗長,如果發(fā)生修改巍扛,需要重新編譯代碼才能繼續(xù)领跛。
所以一般推薦使用XML的方式進行配置。
SqlSession
在MyBatis中有兩個實現(xiàn)類撤奸,DefaultSqlSession
和 SqlSessionManager
吠昭。DefaultSqlSession
是單線程使用的,而SqlSessionManager
在多線程環(huán)境下使用胧瓜。SqlSession的作用類似于一個JDBC的Connection對象矢棚,它的作用有3個:
- 獲取Mapper接口
- 發(fā)送SQL給數(shù)據(jù)庫
- 控制數(shù)據(jù)庫事務
基本使用:
// 定義SqlSession
SqlSession sqlSession = null;
try {
// 打開SqlSession會話
sqlSession = SqlSessionFactory.openSession();
// some code..
sqlSession.commit(); // 提交事務
} catch(Exception ex) {
sqlSession.rollback(); // 回滾事務
} finally {
// 在finally語句中確保資源被順利關閉
if(sqlSession != null) {
sqlSession.close();
}
}
映射器
映射器它由一個接口和對應的XML文件(或注解組成)。它可以配置以下內容:
- 描述映射規(guī)則
- 提供SQL語句贷痪,并可以配置SQL參數(shù)類型幻妓、返回類型、緩存刷新等
- 配置緩存
- 提供動態(tài)SQL
在進行具體的映射器實現(xiàn)之前,我們先建立一個POJO(Plain Ordinary Java Object)肉津。映射器的主要作用就是將SQL查詢到的結果映射成為一個POJO强胰,或者將POJO的數(shù)據(jù)插入到數(shù)據(jù)庫中,并定義一些關于緩存等的內容妹沙。
package com.whyalwaysmea.pojo;
public class Role {
private Long id;
private String roleName;
private String note;
/** setter and getter **/
}
用XML實現(xiàn)映射器
用xml定義映射器分為兩個部分:接口和xml偶洋。
// 映射器接口
public interface RoleMapper {
public Role getRole(Long id);
}
<?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">
<!-- namespace對應的是一個接口的全限定名,這便可以找到對應的接口 -->
<mapper namespace="com.learn.ssm.chapter3.mapper.RoleMapper">
<!--
select表明這是一條查詢語句
id標識了這條SQL
parameterType="long"說明傳遞給SQL的是一個long型參數(shù)
resultType="role"表明返回的是一個role類型的返回值距糖。而role就是在配置文件mybatis-config.xml中配置的別名玄窝、
#{id}表示傳遞進去的參數(shù)
-->
<select id="getRole" parameterType="long" resultType="role">
select id,
role_name as roleName, note from t_role where id = #{id}
</select>
</mapper>
這里需要注意的是,xml文件的路徑要與配置SqlSessionFactory時添加的映射文件路徑相對應悍引。
注解實現(xiàn)映射器
public interface RoleMapper2 {
@Select("select id, role_name as roleName, note from t_role where id=#{id}")
public Role getRole(Long id);
}
當然也需要在mybatis-config.xml文件中配置了
使用注解的方式也許會讓你覺得比XML方式要簡單得多恩脂。如果它和XML方式同時定義,XML方式將會覆蓋掉注解方式趣斤,所以MyBatis官方推薦使用的是XML方式俩块。
因為在平常的工作中,SQL的會比較復雜浓领,比如有一些動態(tài)條件玉凯,所以使用XML的方式會更靈活。
SqlSession發(fā)送SQL
有了映射器就可以通過SqlSession發(fā)送SQL了联贩。
SqlSession session = SqlSessionFactoryUtils.openSqlSession();
// selectOne表示查詢并且只返回一個對象漫仆,參數(shù)是一個String對象和一個Object對象
// String對象是由一個命名空間加上SQL id組合而成的。
// Role role = session.selectOne("com.whyalwaysmea.mapper.RoleMapper.getRole", 1L);
// 如果在MyBatis中只有一個id為getRole的SQL泪幌,那么可以簡寫
Role role = session.selectOne("getRole", 1L);
System.out.println(role.toString());
用Mapper接口發(fā)送SQL
SqlSession session = SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper = session.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1L)
對比兩種發(fā)送SQL方式
個人建議采用SqlSession獲取Mapper的方式:
- 使用Mapper接口編程可以消除SqlSession帶來的功能性代碼盲厌,提高可讀性,而SqlSession發(fā)送SQL祸泪,需要一個SQL id去匹配SQL狸眼。
- 使用Mapper.getRole(1L)的方式,IDE會提示錯誤和校驗
生命周期
所謂生命周期就是每一個對象應該存活的時間浴滴,比如一些對象一次用完后就要關閉,使它們被Java虛擬機銷毀岁钓,以避免繼續(xù)占用資源升略。
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder 的作用在于創(chuàng)建SqlSessionFactory,創(chuàng)建成功后屡限,SqlSessionFactoryBuilder 就失去了作用品嚣,所以它只能存在于創(chuàng)建SqlSessionFactoryBuilder 的方法中,而不要讓其長期存在
SqlSessionFactory
SqlSessionFactory可以被認為是一個數(shù)據(jù)庫連接池钧大,它的作用是創(chuàng)建SqlSession接口對象翰撑。因為MyBatis的本質就是Java對數(shù)據(jù)庫的操作,所以SqlSessionFactory的生命周期應該存在于整個MyBatis應用之中啊央。
由于SqlSessionFactory是一個對數(shù)據(jù)庫的連接池眶诈,所以它占據(jù)著數(shù)據(jù)庫的連接資源涨醋。如果創(chuàng)建多個SqlSessionFactory,那么就存在多個數(shù)據(jù)庫連接池逝撬,這樣不利于對數(shù)據(jù)庫資源的控制浴骂。因為在一般的應用中我們希望SqlSessionFactory作為一個單例
SqlSession
如果說SqlSessionFactory相當于數(shù)據(jù)庫連接池,那么SqlSession就相當于一個數(shù)據(jù)庫連接(Connection對象)宪潮。所以它應該存活在一個業(yè)務請求中溯警,處理完整個請求后,應該關閉這條連接狡相。
Mapper
Mapper是一個接口梯轻,它由SqlSession所創(chuàng)建,所以它的最大生命周期至多和SqlSession保持一致尽棕。
實例
在經(jīng)過了簡單的了解之后喳挑,我們完成一個對角色表的增拘央、刪描沟、改、查渴丸。 這里就直接給出代碼地址好了