一、目标
- 了解MyBatis的三个基本要素
- 理解核心类和接口的作用域和生命周期
- 掌握SqlSession的两种使用方式
- 掌握核心配置文件结构
二、MyBatis基本要素
1. MyBatis的核心接口和类
- SqlSessionFactoryBuilder
- SqlSessionFactory
- SqlSession
2. mybatis-config.xml系统核心配置文件,默认名称为configuration.xml,文件结构和子元素节点的含义进行系统学习。
3. mapper.xml SQL映射文件
三、核心接口和类
SqlSessionFactory是整个MyBatis应用程序的中心,整个应用程序都是以SqlSessionFactory对象的实例为核心的。
首先创建得到SqlSessionFactory,如何创建得到SqlSessionFactory对象,需要SqlSessionFactoryBuilder,创建得到SqlSessionFactory对象。通过xml配置文件或者configuration类的实例去构造然后获取SqlSessionFactory对象。SqlSessionFactoryBuilder类的build()方法就可以获得到SqlSessionFactory。
使用SqlSessionFactory是为了得到SqlSession实例。SqlSession是跟数据库的一个会话,有了SqlSession,才能对数据库进行增删改查的操作。通过openSession()方法打开一个会话,得到一个SqlSession对象实例,有了SqlSession就可以进行数据库的操作,因为SqlSession对象包含了以数据库为背景,所有执行SQL操作的方法。
四、核心对象-SqlSessionFactoryBuilder
- 用过即丢,其生命周期只存在于方法体内
- 可重用其来创建多个SqlSessionFactory实例
- 负责构建SqlSessionFactory,并提供多个build方法的重载
一旦得到SqlSessionFactory,SqlSessionFactoryBuilder就没有用了,所以最佳的生命周期存在于方法体中。
五、核心对象-SqlSessionFactory
- SqlSessionFactory是每个MyBatis应用的核心
- 作用:创建SqlSession实例
- SqlSession session = sqlSessionFactory.openSession(boolean autoCommit); true关闭事务控制(默认),false开启事务控制。
- 作用域:Application
- 生命周期与应用的生命周期相同。
- 单例(程序运行期间有且仅有一个实例):存在于整个应用运行时,并且同时只存在一个对象实例。
六、获取SqlSessionFactory的代码是否可以进行优化?
静态代码块,以保证SqlSessionFactory只被创建一次。
先去创建一个工具类MyBatisUtil,用于创建SqlSessionFactory对象。
新建cn.smbms.utils包,写一个静态代码块
MyBatisUtil
package cn.smbms.utils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
private static String resource = "mybatis-config.xml";
private static SqlSessionFactory factory;
static {
try {
//首先获得输入流
InputStream is = Resources.getResourceAsStream(resource);
//得到SqlSessionFactory对象,通过SqlSessionFactoryBuilder的build方法
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static SqlSession createSqlSession() {
return factory.openSession(false);
}
public static void closeSqlSession(SqlSession sqlSession) {
if(null != sqlSession) {
sqlSession.close();
}
}
}
UserMapperTest
package cn.smbms.dao.user;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import org.junit.Test;
import cn.smbms.utils.MyBatisUtil;
public class UserMapperTest {
// 9.使用log4j打印日志
private Logger logger = Logger.getLogger(UserMapperTest.class);
@Test
public void newTest() {
int count = 0;
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtil.createSqlSession();
count = sqlSession.selectOne("cn.smbms.dao.user.UserMapper.count");
logger.debug("UserMapperTest ---> " + count);
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
}
}
最佳方案:使用依赖注入容器,Spring框架,进行继承,进行SqlSessionFactory的管理。
七、核心对象-SqlSession
- 包含了执行SQL所需的所有方法(SqlSession用于持久化操作,类似于jdbc的connection)(通过sqlSession实例对数据库增删改查,直接运行已经映射的SQL语句)
- 对应一次数据库会话,会话结束必须关闭
- 线程级别,不能共享
在do work中增删改查,调用sqlSession提供的执行SQL的方法进行相应的操作,不管成败,肯定要进入finally代码块,对SqlSession进行关闭。
需要注意:SqlSession对应一次数据库会话,会话不是永久的,会话结束要关闭,每次访问数据库时都要对SqlSession进行一次创建。
但是,在SqlSession里可以执行多次SQL语句,但一旦关闭了SqlSession就需要重新创建。
各个线程,各个用户之间的会话,不能共享,也不是线程安全的。最佳作用域的范围在request作用域内,一次请求作用域内,或者一个方法体。
- SqlSession的获取方式
- SqlSession的两种使用方式:一、通过SqlSession实例直接运行映射的SQL语句。二、基于Mapper接口方式操作数据。
八、sqlSession的两种使用方式
需求说明:使用sqlSession的两种方式实现用户表的查询操作
分析:
调用sqlSession.selectList()执行查询操作
调用sqlSession.getMapper(Mapper.class)执行DAO接口方法来实现对数据的查询操作
实现:
第一种方式:
UserMapper.xml
<!-- 查询用户列表 -->
<select id="getUserList" resultType="cn.smbms.pojo.User">
select * from smbms_user
</select>
UserMapperTest
@Test
public void testGetUserList() {
List<User> userList = null;
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.selectList("cn.smbms.dao.user.UserMapper.getUserList");
}finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
for(User user : userList) {
logger.debug("testGetUserlist userCode: " + user.getUserCode() + " username: " + user.getUserName());
}
}
第二种:基于mapper接口的方式继续操作数据
在cn.smbms.dao.user下创建于映射文件同名的interface,UserMapper。提供接口方法,接口方法中的名字必须与SQL语句的id一一对应,getUserList()。接口又称之为接口映射器。
package cn.smbms.dao.user;
import java.util.List;
import cn.smbms.pojo.User;
public interface UserMapper {
public List<User> getUserList();
}
在test方法中,userList=sqlSession.getMapper(UserMapper.class).getUserList()
@Test
public void testGetUserList2() {
List<User> userList = null;
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(UserMapper.class).getUserList();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
for(User user : userList) {
logger.debug("testGetUserlist userCode: " + user.getUserCode() + " username: " + user.getUserName());
}
}
九、小结
SqlSessionFactoryBuilder:用过即丢,推荐作用域在方法体内
SqlSessionFactory:最佳作用域范围:应用的全局作用域,生命周期与应用的声明周期相同
SqlSession:作用域为线程级,生命周期为一个request请求期间
十、掌握核心配置文件结构:configuration.xml改名为mybatis-config.xml![](https://i-blog.csdnimg.cn/blog_migrate/44676c9238d8afaeec83b19f73ee7d28.png)
configuration:根节点,整个xml配置文件的大管家,所有配置信息都是它的子节点元素并放在configuration里面,并且mybatis还提供了设置子节点的方法。
Properties:描述外部可替代的属性。比如读取数据库database.properties属性文件,通过properties进行指定和引入
settings:设置一些比较重要的配置项,比如通过settings元素设置mybatis的log实现为log4j,通过这种设置可以修改mybatis运行时的行为方式
typeAliases:类型别名,简称,简化操作
typeHandlers
objectFactory
plugins
environments:配置运行环境,可以有多套运行环境
environment:设置其中一套
tractionManager:事务管理器
dataSource:数据源
mappers:通过映射器,引入mapper映射文件,来执行数据库的SQL操作
注意:元素节点的顺序。
十一、配置properties元素
配置properties元素的两种方式:
一、通过外部指定的方式(database.properties),实现动态配置
通过properties元素的resource指定
二、直接配置为xml,实现动态配置
配置property的name和value
若两种方式同时都用了,那么哪种方式优先?
配置properties的resource指定
配置property的name和value
结论:resource属性值的优先级高于property子节点配置的值。
十二、settings元素
主要修改MyBatis运行时的行为方式
主要是MyBatis的一些全局配置属性的设置
其它到PDF官方手册查询。
十三、typeAliases元素
类型别名
仅仅只关联XML配置,简写冗长的Java类名
<typeAliases>
<typeAlias alias="user" type="cn.smbms.pojo.User"/>
</typeAliases>
<!-- 查询用户列表 -->
<select id="getUserList" resultType="user">
select * from smbms_user
</select>
package的name属性指定包名,所有的POJO都放在这个包下,mybatis自动扫描这个包下的所有类,将类名映射为别名。更加简洁。
mybatis为常见的java类型创建了映射类型,基础类型写int, Integer, String等,大小写不敏感。
十四、environments元素
表示配置mybatis的多套运行环境,将SQL映射到多个不同的数据库上。
子元素节点:environment,但是必须指定其中一个默认运行环境(通过default指定)。
每个SqlSessionFactory实例只能选择一个运行环境。
environments的default属性指定默认的运行环境ID。
environment的id属性指定运行环境ID。
transactionManager设置事务管理器
dataSource 数据源配置
transactionManager type有JDBC和MANAGED(托管)
dataSource:dataSource元素使用基本的JDBC数据源接口来配置JDBC连接对象的资源
dataSource有三种内建的数据源类型:UNPOOLED | POOLED | JNDI
POOLED主要利用池的概念,将JDBC连接对象组织起来,避免创建新的对象花费的认证和初始化时间,连接可以被复用,不必再每次请求的时候都创建一个新的连接。
十五、mappers元素
映射器,定义SQL映射语句
需要在配置中引用mapper配置文件
方式一:使用类资源路径获取资源
方式二:使用URL获取资源