上一篇文章中主要介绍了Mybatis核心组件的构成以及用法,但仅学习其构成和用法,便是浅尝辄止,不能够更深入的理解Mybatis核心组件。为了在实际开发工作中能写出高效、安全的程序,更恰当的将Mybatis框架运用于我们的平台、系统,我们还需要进一步学习Mybatis核心组件的范围与生命周期。本文将通过一个简单的例子,一方面,为上文(Mybatis核心组件的构成及用法)作补充,另一方面,介绍Mybatis核心组件SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper的范围与生命周期。
(1) 创建一个maven项目,并引入mybatis(3.4.5)、连接池(dbcp)、junit依赖(4.11),目录结构如下图:
(2) 添加mybatis配置文件,首先加入db.properties和log4j.properties,然后,完成mybatis-config.xml配置文件(尚未添加映射器),详细内容如下:
<configuration>
<!-- 加载db.propertiies文件 -->
<properties resource="db.properties"></properties>
<!-- 环境 -->
<environments default="developement">
<environment id="developement">
<transactionManager type="jdbc"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
此时的目录结构如下:
配置完成之后,先测试一下是否能够创建SqlSessionFactory对象,ConfigTest类的代码如下:
public class ConfigTest {
private static SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException{
InputStream inputStream = Resources.getResourceAsStream("mybatis/mybatis-config.xml");
// SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = factoryBuilder.build(inputStream);
}
@Test
public void factoryTest() {
System.out.println(sqlSessionFactory);
}
}
到达这一步,我们来介绍一下SqlSessionFactoryBuilder和SqlSessionFactory的生命周期。
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder的作用是创建SqlSessionFactory,当SqlSessionFactory创建完成,SqlSessionFactoryBuilder的任务就完成了,没有存在的必要。因此,SqlSessionFactoryBuilder存在于方法内,当它的任务完成便可将其回收。
SqlSessionFactory
SqlSessionFactory用于创建SqlSession会话,只要运用程序与数据库进行交互,就需要SqlSessionFactory为我们创建会话。因此,SqlSessionFactory一直存在于Mybatis应用生命周期内。在整个运用中,我们需要多次使用SqlSessionFactory为我们创建会话,但是每创建SqlSessionFactory会获取更多数据库连接资源,这样很容易耗尽数据库连接资源,此外,SqlSessionFactory的任务只有创建SqlSession会话。因此,SqlSessionFactory适合使用单例模式。(此处作为测试我们就不实现SqlSessionFactory的单例模式了)
(3)依据数据库创建pojo,Dept实现系列化接口,有三个属性,添加get、set方法(此处不做代码的展示),目录结构如下图:
public class Dept implements Serializable{
private static final long serialVersionUID = 1L;
private Integer deptno;
private String dname;
private String loc;
}
(3)创建映射器,DeptMapper接口和DeptMapper.xml,在接口中定义方法,目录结构如下:
public interface DeptMapper {
/**
* description:依据部门编号查询部门信息.
*
* @param deptno
* @return
* @author
* @createtime 2018年10月28日下午5:35:33
*/
public Dept queryDeptByDeptno(Integer deptno);
}
(4)完成DeptMapper.xml文件(之后会写其他文章会详细介绍映射器的xml文件),内容如下:
<mapper namespace="cn.don.mapper.DeptMapper">
<select id="queryDeptByDeptno" resultType="cn.don.pojo.Dept">
SELECT
T.DEPTNO,
T.DNAME,
T.LOC
FROM DEPT T
WHERE T.DEPTNO = #{deptno}
</select>
</mapper>
(5)在mybatis配置文件中添加映射器,mybatis的例子就完成了。
<configuration>
<!-- 加载db.propertiies文件 -->
<properties resource="db.properties"></properties>
<!-- 环境 -->
<environments default="developement">
<environment id="developement">
<transactionManager type="jdbc"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<!-- 映射器 -->
<mappers>
<mapper class="cn.don.mapper.DeptMapper"/>
</mappers>
</configuration>
接下来我们便可以进行测试了,创建DeptMapperTest测试类进行测试:
public class DeptMapperTest {
private static SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException{
InputStream inputStream = Resources.getResourceAsStream("mybatis/mybatis-config.xml");
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = factoryBuilder.build(inputStream);
}
@Test
public void queryDeptByDeptnoTest() {
SqlSession sqlSession = sqlSessionFactory.openSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = deptMapper.queryDeptByDeptno(10);
System.out.println(dept);
sqlSession.close();
}
}
运行测试类发现并没有达到预期效果,因为没有找到Oracle数据库驱动,为此,我们添加Oracle数据库驱动,错误如下:
添加Oracle数据库驱动之后,测试通过,正确获取到dept的信息,完整目录如下图:
结果如下:
测试完成,我们来介绍SqlSession和Mapper的范围与生命周期。
SqlSession
SqlSession会话存在于一个请求或者方法内,在每次使用完成时候都需要将其关闭。SqlSession是线程不安全的。
Mapper
Mapper存在于一个方法内。