1.1 Mybatis核心组件概述
SqlSessionFactoryBuilder(构造器):它会根据 配置或者代码来生成SqlSessionFactory,采用的是分布式构件的Builder模式。
SqlSessionFactory(工厂接口):依靠它来生成SqlSession,使用的是工厂模式
SqlSession(会话):一个既可以发送SQL执行返回结果,也可以获取Mapper的接口,一般我们会让其在业务逻辑代码中“消失”,而使用的是Mybatis提供的SQL Mapper接口编程技术,他能提高代码的可读性和可维护性
SQL Mapper(映射器): Mybatis新设计存在的组件,它由一个Java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则,它负责发送SQL去执行,并返回结果。
1.2 SqlSessionFactory
SqlSessionFactory的构建
SqlSessionFactoryBuilder会根据配置或者代码来生成SqlSessionFactory,当有了配置或者代码后,Mybatis会读取配置文件,通过Configuration类对象构建整个Mybati的上下文。
SqlSessionFactory是一个接口,在Mybatis中他存在两个实现类:SqlSessionManager和DefaultSqlSessionFactory,一般是由DefaultSqlSessionFactory去实现,而SqlSessionManager使用在多线程的环境中,其具体实现也是依靠DefaultSqlSessionFactory的。
1.2.1使用XML构建SqlSessionFactory(配置的方式)
Mybatis中的XML文件分为两类:一类是基础配置文件,通常只有一个,主要是配置一些最基本的上下文参数和运行环境;另一类是映射文件,他可以配置映射关系、SQL、参数等信息。
Mybatis基础配置文件 "mybatis-config.xml"
<!--Mybatis基础配置文件-->
有了配置文件之后,生成SqlSessionFactory的代码
SqlSessionFactory SqlSessionFactory=null;
String resource = "mybatis-config.xml";
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
return null;
}
1.2.2 使用代码生成SqlSessionFactory
这种方式写起来繁琐,且不易维护,不推荐使用
//数据库连接池信息
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setUrl("jdbc:mysql://localhost:3306/chapter3");
dataSource.setDefaultAutoCommit(false);
//采用MyBatis的JDBC事务方式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
//创建Configuration对象
Configuration configuration = new Configuration(environment);
//注册一个MyBatis上下文别名
configuration.getTypeAliasRegistry().registerAlias("role", Role.class);
//加入一个映射器
configuration.addMapper(RoleMapper.class);
configuration.addMapper(RoleMapper2.class);
//使用SqlSessionFactoryBuilder构建SqlSessionFactory
sqlSessionFactory =
new SqlSessionFactoryBuilder().build(configuration);
return sqlSessionFactory;
1.3 SqlSession
在Mybatis中,SqlSession是其核心接口。在Mybatis中有两个实现类,DefaultSqlSession和SqlSessionManager。DefaultSqlSession是单线程使用的,SqlSessionManager是在多线程环境下使用的。SqlSession的作用类似于一个JDBC中的Connection对象,代表着一个连接资源的启用,SqlSession具有如下3个作用:
获取Mapper接口(参考1.4.4)
发送SQL给数据库(一般不用SqlSession发送SQL给数据库,而是通过Mapper接口发送SQL给数据库,参考1.4.3和1.4.4)
控制数据库事务
1.3.1创建SqlSession(需要先得到SqlSessionFactory对象)
SqlSession sqlSession = sqlSessionFactory.openSession();
1.3.2 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();
}
}
要确保sqlSession在finally语句中被关闭,因为SqlSession代表着一个数据库连接资源,如果不关闭,那么数据库的链接资源很快就会被耗光,整个系统就会陷入瘫痪。
1.4 映射器
映射器是Mybatis中最重要,最复杂的组件,它由一个接口和对应的XML文件(或注解)组成,它可以配置一下内容:
描述映射规则
提供SQL语句,并可以配置SQL参数类型、返回类型、缓存刷新等信息
配置缓存
提供动态SQL
映射器的主要作用就是将SQL查询到的结果映射为一个POJO,或者将POJO的内容插入到数据库中,并定义一些关于缓存的重要内容
1.4.1 用XML实现映射器
POJO类
package com.learn.ssm.chapter3.pojo;
?
public class Role {
?
private Long id;
private String roleName;
private String note;
?
/** setter and getter **/
public Long getId() {
return id;
}
?
public void setId(Long id) {
this.id = id;
}
?
public String getRoleName() {
return roleName;
}
?
public void setRoleName(String roleName) {
this.roleName = roleName;
}
?
public String getNote() {
return note;
}
?
public void setNote(String note) {
this.note = note;
}
?
}
映射器=接口+XML配置文件/注解
映射器接口
package com.learn.ssm.chapter3.mapper;
public interface RoleMapper {
public Role getRole(Long id);
}
XML配置文件
Mybatis会把SQL的查询结果自动映射为POJO
1.4.2 注解实现映射器
这种方式只需要一个接口就可以通过Mybatis的注解来注入SQL,这种方法的效果和4.1中配置XML的效果完全等同
package com.learn.ssm.chapter3.mapper; import org.apache.ibatis.annotations.Select; import com.learn.ssm.chapter3.pojo.Role; public interface RoleMapper2 { @Select("select id, role_name as roleName, note from t_role where id=#{id}") public Role getRole(Long id); }
在mybatis-config配置文件中加入通过注解方式实现的映射器:
<mapper class="com.learn.ssm.chapter3.mapper.RoleMapper2"/>
如果同时定义XML和注解,XML会覆盖注解,Mybatis官方推荐使用XML的方式实现映射器,因为在实际应用中,SQL语句会极其复杂,使用注解的方式实现映射器会降低代码的可读性,注解也会十分复杂,不利于日后的维护和修改。
1.4.3 SqlSession发送SQL
Role role=(Role)sqlSession.selectOne("com.learn.ssm.chapter3.mapper.RoleMapper.getRole",1L);
这种方法已经不推荐了
1.4.4 用Mapper接口发送SQL
//sqlSession的getMapper接受一个接口的class对象,返回一个该接口的实现类的实例,调用该实例的方法就会执行相应的SQL语句 RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class); Role role=roleMapper.getRole(1L);
1.5. 生命周期
SqlSessionFactoryBuilder的生命周期:SqlSessionFactoryBuilder的作用在于创建SqlSessionFactory,创建成果后就失去了作用,因此它只能存在于创建SqlSessionFactory的方法中,而不要让其长期存在
SqlSessionFactory的生命周期:SqlSessionFactory可以被认为是一个数据库连接池,其作用是创建SqlSession接口对象,所以SqlSessionFactory的生命周期在于整个Mybati应用中,可以认为SqlSessionFactory的生命走起就等同于Mybatis的应用周期 它占据着连接数据库的连接资源,如果创建多个SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库链接资源被消耗光,出现宕机的情况,因此在一般的应用中我们往往希望SqlSessionFactory作为一个单例。
SqlSession的生命周期:如果说SqlSessionFactory相当于数据库连接池,那么SqlSession就相当于一个数据库链接(Connection对象),它应该存活在一个业务请求中,处理完整个请求后,应关闭这条链接,让它归还给SqlSessionFactory,否则数据库资源很快被耗费光,系统就会瘫痪
Mapper(注意这里的Mapper是接口,而不是映射器)的生命周期:Mapper接口由SqlSession所创建(创建实现了Mapper接口的类的实例),所以