Mybatis的四个核心组件:
- SqlSessionFactoryBuilder(构造器):它会根据配置或者代码来生成SqlSessionFactory,采用的是分步构建的Builder模式。
- SqlSessionFactory(工厂接口):依靠它来生成SqlSession,使用的是工厂模式。
- SqlSession(会话):一个既可以发送SQL执行返回结果,也可以获取Mapper的接口。在现在的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是Mybatis提供的SQL Mapper接口编程技术,它能提高代码的可读性和可维护性。
- Sql Mapper(映射器):Mybatis新设计存在的组件,它由一个java接口和xml文件(或注解),需要给出对应的SQL和映射规则。它负责发送SQL去执行,并返回结果。
注:无论是映射器还是SqlSession都可以发送SQL到数据库执行。但是推荐使用映射器。
-
SqlSessionFactory(工厂接口):
mybatis使用配置或者代码去生产SqlSessionFactory,Mybatis提供了构造器SqlSessionFactoryBuilder。它提供了一个类 org.apache.ibatis.session.Configuration 作为引导,采用的是Builder模式。具体的分布则是在Configuration类中完成的。
每个基于Mybatis的应用都是以一个SqlSessionFactory的实例为中心的,而SqlSessionFactory唯一的作用就是生产Mybatis的核心接口对象SqlSession,所以他的责任是唯一的。我们往往采用单例模式处理它。
-
使用代码创建SqlSessionFactory
//配置数据库连接池
PooledDataSource dataSource=new PooledDataSource();
dataSource.setDriver("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword("lft123456");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");
//事务管理
TransactionFactory transactionFactory=new JdbcTransactionFactory();
Environment environment=new Environment("development",transactionFactory,dataSource);
//创建Configuration对象
Configuration configuration=new Configuration(environment);
//注册一个mybatis上下文别名
configuration.getTypeAliasRegistry().registerAlias("user", User.class);
//加入映射器
configuration.addMapper(UserDao.class);
//使用SqlSessionFactoryBuilder构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(configuration);
-
使用xml创建SqlSessionFactory
mybatis 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">
<!--mybatis主配置文件-->
<configuration>
<!--取别名-->
<typeAliases>
<typeAlias type="cdu.lft.bean.User" alias="user"></typeAlias>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置MySQL环境-->
<environment id="development">
<transactionManager type="JDBC">
</transactionManager>
<!--配置数据池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="lft123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="cdu/lft/dao/user.xml"></mapper>
</mappers>
</configuration>
Mybatis的基础配置文件:
- <typeAlias>元素定义了一个别名user,他代表着cdu.lft.bean.User 这个类。这样定以后,在Mybatis上下文中可以使用别名代替权限定名。
- <environments>元素作用是用来配置数据库信息,default属性表示使用下面的哪个开发环境。
- <environment>元素的定义,这里描述的是数据库。它里面的<transactionManager>元素是配置事务管理器,这里采用的是mybatis的JDBC管理方式。然后采用<dataSource>元素配置数据库,其中属性type=“POOLED”代表采用Mybatis内部提供的连接池方式,最后定义一些关于JDBC的属性信息。
- <mapper>元素代表引入的那些映射器。
使用代码创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory=null;
String resources="mybatis.xml";
InputStream inputStream;
try {
inputStream= Resources.getResourceAsStream(resources);
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}catch (IOException e){
e.printStackTrace();
}
首先读取mybatis.xml文件,通过SqlSessionFactoryBuilder的builder方法去创建SqlSessionFactory。
2、SqlSession
在Mybatis中,SqlSession是其核心接口。在Mybatis中有两个实现类,DefaultSqlSession和SqlSessionManager。DefaultSqlSession是单线程使用的,而SqlSessionManager在多线程环境下使用。SqlSession的作用类似于一个JDBC中的Connection对象,代表着一个连接资源的启用。
具体而言,它的三个作用:
- 获取Mapper接口
- 发送SQL给数据库
- 控制数据库事务
使用SqlSessionFactorty创建SqlSession
SqlSession sqlSession=sqlSessionFactory.openSession();
SqlSession只是一个门面接口,它还有很多方法,可以直接发送SQL。在Mybatis中真正干活的是Executor。
SqlSession事务控制伪代码
SqlSession sqlSession=null;
try {
//打开SqlSession会话
sqlSession=sqlSessionFactory.openSession();
//do something
//do something
//do something
sqlSession.commit();
}catch (Exception ex){
sqlSession.rollback();
}finally {
//在finally语句中确保资源被顺利关闭
if (sqlSession!=null){
sqlSession.close();
}
}
3、映射器
映射器是Mybatis中最重要、最复杂的组件,它由一个接口和对应的xml文件(或注解)组成。它可以配置以下内容:
- 描述映射规则
- 提供SQL语句,并可以配置SQL参数类型、返回类型、缓存刷新等信息
- 配置缓存
- 提供动态sql
映射器的主要作用就是将SQL查询到的结果映射为一个POJO,或者将POJO的数据插入到数据库中,并定义一些关于缓存的重要信息。
注意,开发只是一个接口,而不是一个实现类,接口不能直接运行。Mybatis运用运用了动态代理技术使得接口能够运行起来。
-
使用 xml实现映射器:
用XML定义映射器分为两个部分:接口和XML。先定义一个映射器接口,如下代码:
public interface UserDao {
User findById(int id);
}
在mybatis.xml文件中添加如下代码:
<mappers>
<mapper resource="mapper/user.xml"></mapper>
</mappers>
它的作用是引入一个xml文件。
用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="cdu.lft.dao.UserDao" >
<select id="findById" resultType="user" parameterType="int">
select * from user where id=#{id}
</select>
</mapper>
- <mapper>元素中的属性namespace所对应的是一个接口的权限定名,于是Mybatis上下文就可以通过它找到对应的接口。
- <select>元素表示这是一条查询语句,而属性id标识了这条SQL,属性paramenterType表示传入参数类型,属性resultType表示查询出的结果返回的类型。
- 这条SQL中的#{id}表示传递进去的参数。
注意:我们并没有配置SQL执行后和user的对应关系,其实这里采用的是一种被称为自动映射的功能,Mybatis在默认情况下提供自动映射,只要SQL返回的列名能与POJO对应起来即可。
-
使用注解实现映射器:
public interface UserDao {
@Select(" select * from user where id=#{id}")
User findById(int id);
}
此外,XML可以相
-
SqlSession发送SQL
有了映射器就可以通过发送SQL了。我们以findById这条SQL为例
sqlSession=sqlSessionFactory.openSession();
User user=(User)sqlSession.selectOne("cdu.lft.dao.UserDao.findById",1);
-
使用mapper接口发送SQL
SqlSession可以通过获去Mapper接口,通过Mapper接口发送SQL。
UserDao userDao=(UserDao) sqlSession.getMapper(UserDao.class);
User user = userDao.findById(1);
4、生命周期
-
SqlSessionFactoryBuilder:
SqlSessionFactoryBuilder的唯一作用是创建SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder就失去了作用,所以它只能存在于创建SqlSessionFactory的方法中,不能使其长期存在。
-
SqlSessionFactory:
SqlSessionFactory可以被认为是一个数据库连接池,它的作用是创建SqlSession接口对象。因为mybatis的本质就是对java数据库的操作,所以SqlSession的生命周期存在于整个Mybatis的应用中,所以一旦创建了SqlSessionFactory,就要长期保存它,所以可以认为SqlSessionFactory的生命周期就等同于Mybatis的应用周期。同时SqlSessionFactory是作为一个单例对象,让它在应用中被共享。
-
SqlSession:
如果说SqlSessionFactory相当于数据库连接池,那么SqlSession就相当于一个数据库连接(connection对象),你可以在一个事务中执行多个SQL,然后通过它的commit、rollback等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给SqlSessionFactory,否则数据库资源就很快被消耗完,系统就会瘫痪。
-
Mapper
Mapper是一个接口,它由SqlSession所创建,所以它的最大生命周期最多和SqlSession保持一致,尽管它很好用,但是由于SqlSession的关闭,它的数据库连接资源也会消失,所以它的生命周期应该小于等于SqlSession的生命周期。Mapper代表的是一个请求中的业务处理,所以它应该在一个请求中,一旦处理完了相关的事务,它就应该废弃它。