mybatis

1. Mybatis核心组件

1.1 Mybatis核心组件概述

SqlSessionFactoryBuilder(构造器):它会根据 配置或者代码来生成SqlSessionFactory,采用的是分布式构件的Builder模式。

SqlSessionFactory(工厂接口):依靠它来生成SqlSession,使用的是工厂模式

SqlSession(会话):一个既可以发送SQL执行返回结果,也可以获取Mapper的接口,一般我们会让其在业务逻辑代码中“消失”,而使用的是Mybatis提供的SQL Mapper接口编程技术,他能提高代码的可读性和可维护性

SQL Mapper(映射器): Mybatis新设计存在的组件,它由一个Java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则,它负责发送SQL去执行,并返回结果。

 

无论是映射器还是SqlSession都可以发送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基础配置文件-->
<?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">
<configuration>
 <typeAliases><!-- 别名 ,定义别名之后,在Mybatis上下文中就可以使用别名去代替全限定名称了-->
     <typeAlias alias="role" type="com.learn.ssm.chapter3.pojo.Role"/>
 </typeAliases>
 <!-- 数据库环境 -->
 <environments default="development">
   <environment id="development">
   <!--配置事务管理器-->
     <transactionManager type="JDBC"/>
     <!--配置数据库,type="POOLED"代表采用Mybatis内部提供的连接池方式-->
     <dataSource type="POOLED">
       <!--JDBC的属性信息-->
       <property name="driver" value="com.mysql.jdbc.Driver"/>
       <property name="url" value="jdbc:mysql://localhost:3306/chapter3"/>
       <property name="username" value="root"/>
       <property name="password" value="123456"/>
     </dataSource>
   </environment>
 </environments>
 <!-- 映射文件 -->
 <mappers>
   <!--引入一个映射器,改映射器通过xml方式配置,这里只需要给出xml文件的路径,对应的接口文件可以再xml文件中的namespace属性中找到-->
   <mapper resource="com/learn/ssm/chapter3/mapper/RoleMapper.xml"/>
    <!--引入一个映射器,改映射器通过注解方式配置,因为注解就写在接口文件中,所以这里只需要给出接口的全限定名称即可-->
   <mapper class="com.learn.ssm.chapter3.mapper.RoleMapper2"/>
 </mappers>
</configuration>

 

有了配置文件之后,生成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配置文件

<?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对应的是接口的全限定名称,mybatis上下文可以通过它找到对应的接口-->
<mapper namespace="com.learn.ssm.chapter3.mapper.RoleMapper">

<!--select表明这是一条查询语句,id标识了这条SQL,parameterType表示传递给SQL的参数类型,resultType="role"表示返回类型是一个role类型,role是前面mybatis-config.xml文件中配置的别名,指代com.learn.ssm.chapter3.pojo.Role-->
   <!-- #{id} 表示传入的参数,其类型对应parameterType的值-->
<select id="getRole" parameterType="long" resultType="role">
select id,
role_name as roleName, note from t_role where id = #{id}
</select>
?
</mapper>

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接口的类的实例),所以其最大生命周期至多和SqlSession保持一致。

mybatis

上一篇:机器视觉——必备知识


下一篇:RabbitMQ知识(2)