之前了解了Mybatis的基本用法,现在学习一下Mybatis框架中的核心对象以及映射文件和配置文件,来深入的了解这个框架。

1.Mybatis的核心对象

使用MyBatis框架时,主要涉及两个核心对象:SqlSessionFactory和SqlSession。

1.1.1 SqlSessionFactory

SqlSessionFactory是MyBatis框架中十分重要的对象,它是单个数据库映射关系经过编译后的内存镜像,其主要作用是创建SqlSession。

SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来构建,而SqlSessionFactoryBuilder则可以通过XML配置文件或一个预先定义好的Configuration实例构建出SqlSessionFactory的实例。

  • 通过XML配置文件构建出的SqlSessionFactory实例现代码如下:
InputStream inputStream = Resources.getResourceAsStream("配置文件位置");
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
  • SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用执行期间都会存在。如果我们多次的创建同一个数据库的SqlSessionFactory,那么此数据库的资源将很容易被耗尽。

    为此,通常每一个数据库都会只对应一个SqlSessionFactory,所以在构建SqlSessionFactory实例时,建议使用单列模式。

1.1.2 SqlSession

SqlSession是MyBatis框架中另一个重要的对象,它是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作。

每一个线程都应该有一个自己的SqlSession实例,并且该实例是不能被共享的。同时,SqlSession实例也是线程不安全的,因此其使用范围最好在一次请求或一个方法中,

绝不能将其放在一个类的静态字段、实例字段或任何类型的管理范围(如Servlet的HttpSession)中使用。

使用完SqlSession对象后要及时关闭,通常可以将其放在finally块中关闭。

    SqlSession sqlSession = sqlSessionFactory.openSession();
try {
// 此处执行持久化操作
} finally {
sqlSession.close();
}

SqlSession 中常用的方法

查询方法:

  • <T> T selectOne(String statement);参数statement是在配置文件中定义的<select> 元素的id。使用该方法会返回查询结果的一条泛型对象。

  • <T> T selectOne(String statement, Object parameter);参数statement是在配置文件中定义的<select> 元素的id,parameter是查询所需的参数。使用该方法会返回查询结果的一条泛型对象。

  • <E> List<E> selectList(String statement);参数statement是在配置文件中定义的<select> 元素的id。使用该方法,会返回查询结果的泛型对象的集合。

  • <E> List<E> selectList(String statement, Object parameter);参数statement是在配置文件中定义的<select> 元素的id,parameter是查询所需的参数。使用该方法,会返回查询结果的泛型对象的集合。

  • <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);参数statement是在配置文件中定义的<select> 元素的id,parameter是查询所需的参数,rowBounds是用于分页的参数对象。

    使用该方法,会返回查询结果的泛型对象的集合。

  • void select(String statement, Object parameter, ResultHandler handler);参数statement是在配置文件中定义的<select> 元素的id,parameter是查询所需的参数,ResultHandler 是用于处理查询返回的复杂结果集,通常用于多表查询。

插入、更新和删除方法:

  • int insert(String statement);参数statement是在配置文件中定义的 元素的id,返回SQL语句所影响的行数。

  • int insert(String statement, Object parameter);参数statement是在配置文件中定义的<insert> 元素的id,parameter是插入所需要参数。返回SQL语句所影响的行数。

  • int update(String statement);参数statement是在配置文件中定义的 元素的id,返回SQL语句所影响的行数。

  • int update(String statement, Object parameter);参数statement是在配置文件中定义的<update> 元素的id,parameter是更新所需要的参数。返回SQL语句所影响的行数。

  • int delete(String statement);参数statement是在配置文件中定义的<delete> 元素的id,返回SQL语句所影响的行数。

  • int delete(String statement, Object parameter);参数statement是在配置文件中定义的<delete> 元素的id,parameter是删除所需要的参数。返回SQL语句所影响的行数。

其他方法:

  • void commit(); 提交事务的方法。

  • void rollback(); 回滚事务的方法。

  • void close(); 关闭SqlSession对象。

  • <T> T getMapper(Class<T> type); 返回Mapper接口的代理对象。

  • Connection getConnection(); 获取JDBC数据库连接对象的方法。

2.配置文件

在MyBatis框架的核心配置文件中,<configuration>元素是配置文件的根元素,其他元素都要在<configuration>元素内配置。MyBatis配置文件中的主要元素如下图所示:

2.1.1 <properties>元素

<properties>是一个配置属性的元素,该元素通常用来将内部的配置外在化,即通过外部的配置来动态的替换内部定义的属性。

例如,数据库的连接等属性,就可以通过典型的Java属性文件中的配置来替换,具体方式如下:

1.编写db.properties

jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://1localhost:1433;DatabaseName=mybatis
jdbc.username=sa
jdbc.password=123456

2.配置<properties>属性

<properties resource="db.properties" />

3.修改配置文件中数据库连接的信息

<dataSource type="POOLED">
<!-- 数据库驱动 -->
<property name="driver" value="${jdbc.driver}" />
<!-- 连接数据库的url -->
<property name="url" value="${jdbc.url}" />
<!-- 连接数据库的用户名 -->
<property name="username" value="${jdbc.username}" />
<!-- 连接数据库的密码 -->
<property name="password" value="${jdbc.password}" />
</dataSource>

2.1.2 <settings>元素

<settings>元素主要用于改变MyBatis运行时的行为,例如开启二级缓存、开启延迟加载等。这些配置只需要了解,有很多就不列出来了。

2.1.3 <typeAliases>元素

<typeAliases>元素用于为配置文件中的Java类型设置一个简短的名字,即设置别名。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余。

  1. 使用<typeAliases>元素配置别名的方法如下:
     <typeAliases>
<typeAlias alias="user" type="com.itheima.po.User"/>
</typeAliases>
  1. 当POJO类过多时,可以通过自动扫描包的形式自定义别名,具体如下:
    <typeAliases>
<package name="com.itheima.po"/>
</typeAliases>

MyBatis框架默认为许多常见的Java类型提供了相应的类型别名,如下表所示。

2.1.4 <typeHandler>元素

typeHandler的作用就是将预处理语句中传入的参数从javaType(Java类型)转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。

<typeHandler>元素可以在配置文件中注册自定义的类型处理器,它的使用方式有两种。

1.注册一个类的类型处理器

     <typeHandlers>
<typeHandler handler="com.itheima.type.CustomtypeHandler" />
</typeHandlers>

2.注册一个包中所有的类型处理器

     <typeHandlers>
<package name="com.itheima.type" />
</typeHandlers>

2.1.5<objectFactory>元素

MyBatis中默认的ObjectFactory的作用是实例化目标类,它既可以通过默认构造方法实例化,也可以在参数映射存在的时候通过参数构造方法来实例化。通常使用默认的ObjectFactory即可。

大部分场景下都不用配置和修改默认的ObjectFactory ,如果想覆盖ObjectFactory的默认行为,可以通过自定义ObjectFactory来实现,具体如下:

1.自定义一个对象工厂

public class MyObjectFactory extends DefaultObjectFactory {
private static final long serialVersionUID = -4114845625429965832L;
public <T> T create(Class<T> type) {
return super.create(type);
}
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes,
List<Object> constructorArgs) {
return super.create(type, constructorArgTypes, constructorArgs);
}
public void setProperties(Properties properties) {
super.setProperties(properties);
}
public <T> boolean isCollection(Class<T> type) {
return Collection.class.isAssignableFrom(type);
}
}

2.在配置文件中使用<objectFactory>元素配置自定义的ObjectFactory

<objectFactory type="com.itheima.factory.MyObjectFactory">
<property name="name" value="MyObjectFactory"/>
</objectFactory>

注意:由于自定义ObjectFactory在实际开发时不经常使用,这里读者只需要了解即可。

2.1.6<plugins>元素

MyBatis允许在已映射语句执行过程中的某一点进行拦截调用,这种拦截调用是通过插件来实现的。元素的作用就是配置用户所开发的插件。

如果用户想要进行插件开发,必须要先了解其内部运行原理,因为在试图修改或重写已有方法的行为时,很可能会破坏MyBatis原有的核心模块。

只需了解元素的作用即可,有兴趣的读者可以查找官方文档等资料自行学习。

2.1.7 <environments>元素

<environments>元素用于对环境进行配置。MyBatis的环境配置实际上就是数据源的配置,我们可以通过元素配置多种数据源,即配置多种数据库。

使用<environments>元素进行环境配置的示例如下:

      <environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
...
</environments>

<transactionManager>元素用于配置事务管理,它的type属性用于指定事务管理的方式,即使用哪种事务管理器;<dataSource>元素用于配置数据源,它的type属性用于指定使用哪种数据源。

在MyBatis中,可以配置两种类型的事务管理器,分别是JDBC和MANAGED。关于这两个事务管理器的描述如下:

  • JDBC:此配置直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务的作用域。

  • MANAGED:此配置从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。默认情况下,它会关闭连接,但一些容器并不希望这样,为此可以将closeConnection属性设置为false来阻止它默认的关闭行为。

注意:如果项目中使用的是Spring+ MyBatis,则没有必要在MyBatis中配置事务管理器,因为实际开发中,会使用Spring自带的管理器来实现事务管理。

对于数据源的配置,MyBatis提供了UNPOOLED、POOLED、JNDI三种数据源类型。

  1. UNPOOLED

    配置此数据源类型后,在每次被请求时会打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。在使用时,需要配置5种属性。

2.POOLED

此数据源利用“池”的概念将JDBC连接对象组织起来,避免了在创建新的连接实例时所需要初始化和认证的时间。这种方式使得并发Web应用可以快速的响应请求,是当前流行的处理方式。在使用时,可以配置更多的属性。

3.JNDI

可以在EJB或应用服务器等容器中使用。容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。在使用时,需要配置2个属性。

2.1.9 <mappers>元素

<mappers>元素用于指定MyBatis映射文件的位置,一般可以使用以下4种方法引入映射器文件,具体如下。

1.使用类路径引入

<mappers>
<mapper resource="com/itheima/mapper/UserMapper.xml"/>
</mappers>

2.使用本地文件路径引入

<mappers>
<mapper url="file:///D:/com/itheima/mapper/UserMapper.xml"/>
</mappers>

3.使用接口类引入

<mappers>
<mapper class="com.itheima.mapper.UserMapper"/>
</mappers>

4.使用包名引入

<mappers>
<package name="com.itheima.mapper"/>
</mappers>

这几种方式,可以根据你的需要选取使用。

3.映射文件

3.1.1 主要元素

在映射文件中,<mapper>元素是映射文件的根元素,其他元素都是它的子元素。 如下图:

3.1.2 <select>元素

使用<select>元素执行查询操作非常简单,其示例如下:

<select id="findCustomerById" parameterType="Integer"
resultType="com.itheima.po.Customer">
select * from t_customer where id = #{id}
</select>

<select>元素的常用属性:

3.1.3 <insert>元素

<insert>元素用于映射插入语句,在执行完元素中定义的SQL语句后,会返回一个表示插入记录数的整数。

<insert>元素的配置示例如下:

<insert
id="addCustomer"
parameterType="com.itheima.po.Customer"
flushCache="true"
statementType="PREPARED"
keyProperty=""
keyColumn=""
useGeneratedKeys=""
timeout="20">

<insert>元素的属性:

<insert>元素的属性与<select>元素的属性大部分相同,但还包含了3个特有属性,这3个属性的描述如下所示。

执行插入操作后,很多时候需要返回插入成功的数据生成的主键值,此时就可以通过上面讲解的3个属性来实现。

1.对于支持主键自助增长的数据库(如MySQL),可以通过如下配置实现:

<insert id="addCustomer" parameterType="com.itheima.po.Customer"
keyProperty="id" useGeneratedKeys="true" >
insert into t_customer(username,jobs,phone)
values(#{username},#{jobs},#{phone})
</insert>

2.对于不支持主键自助增长的数据库(如Oracle),可以通过如下配置实现:

<insert id="insertCustomer" parameterType="com.itheima.po.Customer">
<selectKey keyProperty="id" resultType="Integer" order="BEFORE">
select if(max(id) is null, 1, max(id) +1) as newId from t_customer
</selectKey>
insert into t_customer(id,username,jobs,phone)
values(#{id},#{username},#{jobs},#{phone})
</insert>

3.1.4 <update>和<delete>元素

<update>和<delete>元素的使用比较简单,它们的属性配置也基本相同。

1.<update>和<delete>元素的常用属性如下:

<update
id="updateCustomer"
parameterType="com.itheima.po.Customer"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteCustomer"
parameterType="com.itheima.po.Customer"
flushCache="true"
statementType="PREPARED"
timeout="20">

2.<update>和<delete>元素的使用示例如下:

<update id="updateCustomer" parameterType="com.itheima.po.Customer">
update t_customer
set username=#{username},jobs=#{jobs},phone=#{phone}
where id=#{id}
</update> <delete id="deleteCustomer" parameterType="Integer">
delete from t_customer where id=#{id}
</delete>

3.1.5 <sql>元素

在一个映射文件中,通常需要定义多条SQL语句,这些SQL语句的组成可能有一部分是相同的(如多条select语句中都查询相同的id、username、jobs字段),

如果每一个SQL语句都重写一遍相同的部分,势必会增加代码量,导致映射文件过于臃肿。那么有没有什么办法将这些SQL语句中相同的组成部分抽取出来,然后在需要的地方引用呢?

<sql>元素的作用就是定义可重用的SQL代码片段,然后在其他语句中引用这一代码片段。就好像java中,把重复的代码封装起来,方便使用是一样的。

定义一个包含id、username、jobs和phone字段的代码片段如下:

<sql id="customerColumns">id,username,jobs,phone</sql>

上述代码片段可以包含在其他语句中使用,具体如下:

<select id="findCustomerById" parameterType="Integer"
resultType="com.itheima.po.Customer">
select <include refid="customerColumns"/>
from t_customer
where id = #{id}
</select>

定义sql片段,通过<include>元素的refid属性引用id为someinclude的代码片段,先加入from,再通过获取<property>元素的值来组成表名

<!--定义表的前缀名 -->
<sql id="tablename">
${prefix}customer
</sql>
<!--定义要查询的表 -->
<sql id="someinclude">
from
<include refid="${include_target}" />
</sql>
<!--定义查询列 -->
<sql id="customerColumns">
id,username,jobs,phone
</sql>
<select id="findCustomerById" parameterType="Integer"
resultType="com.itheima.po.Customer">
select
<include refid="customerColumns"/>
<include refid="someinclude">
<property name="prefix" value="t_" />
<property name="include_target" value="tablename" />
</include>
<!--加入where子句-->
where id = #{id}
</select>

3.1.6 <resultMap>元素

<resultMap>元素表示结果映射集,是MyBatis中最重要也是最强大的元素。它的主要作用是定义映射规则、级联的更新以及定义类型转化器等。

<resultMap>元素中包含了一些子元素,它的元素结构如下所示:

<resultMap type="" id="">
<constructor> <!-- 类在实例化时,用来注入结果到构造方法中-->
<idArg/> <!-- ID参数;标记结果作为ID-->
<arg/> <!-- 注入到构造方法的一个普通结果-->
</constructor>
<id/> <!-- 用于表示哪个列是主键-->
<result/> <!-- 注入到字段或JavaBean属性的普通结果-->
<association property="" /> <!-- 用于一对一关联 -->
<collection property="" /> <!-- 用于一对多关联 -->
<discriminator javaType=""> <!-- 使用结果值来决定使用哪个结果映射-->
<case value="" /> <!-- 基于某些值的结果映射 -->
</discriminator>
</resultMap>

<resultMap>元素使用案例:

1.新建数据表t_user,插入测试数据。

use mybatis
create table t_user(
t_id int identity(1,1) PRIMARY key,
t_name varchar(50),
t_age int
)
insert into t_user values ('lulu','23');
insert into t_user values ('lili','25');
insert into t_user values ('jiji','18');

2.新建持久化类User,并定义属性。


/**
* @author mz
* @version V1.0
* @Description: 用户实体类
* @create 2017-11-01 14:13
*/
public class User {
private Integer id;
private String name;
private Integer age;
//省略setter和getter方法
}

3.创建UserMapper.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="com.itheima.mapper.UserMapper"> <resultMap id="resultMap" type="com.itheima.po.User">
<!--<id>和<result>的property属性表示User类的属性名,column属性表示数据表t_user的列名。-->
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
<result property="age" column="t_age"/>
</resultMap>
<select id="findAllUser" resultMap="resultMap">
<!--<select>元素的resultMap属性表示引用上面定义的resultMap-->
select * from t_user
</select>
</mapper>

4.在配置文件mybatis-config中,引入UserMapper.xml,并编写测试方法

<!--配置mapper的位置-->
<mappers>
<mapper resource="com/itheima/mapper/CustomerMapper.xml"/>
<mapper resource="com/itheima/mapper/UserMapper.xml"/>
</mappers>
@Test
public void findAllUserTest() {
//获取SqlSession
SqlSession sqlSession = MybatisUtils.getSession();
//执行映射文件中定义的SQL,并返回结果
List<User> list = sqlSession.selectList("com.itheima.mapper.UserMapper.findAllUser");
for (User user : list) {
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}

运行结果如下图所示:

从结果可以看出,t_user表的列名和User对象的属性名完全不一样,但查询出的数据还是正常的封装到了User对象中。

总结

首先学习了MyBatis中的两个重要核心对象SqlSessionFactory和SqlSession;然后是配置文件中的元素及其使用;最后对映射文件中的几个主要元素进行了详细的了解。

以上内容是根据Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)做的一些笔记和总结。

Mybatis的核心配置的更多相关文章

  1. MyBatis的核心配置、动态sql、关联映射(快速总结)

    MyBatis的核心对象和配置 #1. SqlSessionFactory对象: 单个数据库映射关系经过编译的内存镜像: 作用:创建SQLSession对象. //读取配置文件 InputSteam ...

  2. MyBatis 核心配置综述之 ResultSetHandler

    目录 ResultSetHandler 简介 ResultSetHandler 创建 ResultSetHandler 处理结果映射 DefaultResultSetHandler 源码解析 我们之前 ...

  3. Mybatis学习——Mybatis核心配置

    MyBatis的核心配置 在使用MyBatis框架时,设计两个核心的d对象:SqlSessionFactory和SqlSession. SqlsessionFactory SqlSessionFact ...

  4. 1.2(Mybatis学习笔记)Mybatis核心配置

    一.Mybatis核心对象 1.1SqlSeesionFactory SqlSessionFactory主要作用是创建时SqlSession. SqlSessionFactory可通过SqlSessi ...

  5. MyBatis 核心配置综述之Executor

    目录 MyBatis四大组件之 Executor执行器 Executor的继承结构 Executor创建过程以及源码分析 Executor接口的主要方法 Executor 的现实抽象 上一篇我们对Sq ...

  6. MyBatis 核心配置综述之StatementHandler

    目录 MyBatis 核心配置综述之StatementHandler MyBatis 四大组件之StatementHandler StatementHandler 的基本构成 StatementHan ...

  7. MyBatis 核心配置综述之 ParameterHandler

    目录 ParameterHandler 简介 ParameterHandler 创建 ParameterHandler 中的参数从何而来 ParameterHandler 解析 MyBatis 四大核 ...

  8. mybatis的基本配置:实体类、配置文件、映射文件、工具类 、mapper接口

    搭建项目 一:lib(关于框架的jar包和数据库驱动的jar包) 1,第一步:先把mybatis的核心类库放进lib里

  9. Spring+MyBatis实践—工程配置

    初次实践:Spring+MyBatis技术搭建框架,采用Bootstrap前端开源框架. 简介: MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除 了几乎所 ...

随机推荐

  1. bzoj2006: [NOI2010]超级钢琴(堆+RMQ)

    和上一道题同类型...都是用堆求第k大 考虑对于每一个r,怎么求出一个最优的l.显然只需要求出前缀和,用RMQ查询前面最小的l的前缀和就好了.但是对于一个r,每个l只能选一次,选了一次之后,考虑怎么把 ...

  2. poj3469 Dual Core CPU

    Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 25576   Accepted: 11033 ...

  3. js 多个事件的绑定及移除(包括原生写法和 jquery 写法)

    需要打开控制台查看效果: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  4. centos7 配置 yum 安装的 jdk

    yum 安装的 java,jdk 路径默认是 /usr/lib/jvm/java-* 我们修改 .bash_profile 文件加上下面几行: export JAVA_HOME=/usr/lib/jv ...

  5. OpenCV---Canny边缘提取

    一:Canny算法介绍 Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是: 好的检测- 算法能够尽可能多地标识出图像中的实际边缘. 好的定位- 标识出的边缘要尽可能与实际图像中的实 ...

  6. 如何在WIndows电脑上安装 SVN Server 实现代码版本控制

    One 下载-安装 SVN SVNServer  先去官网下载服务器版本的svn server,下载地址 :https://www.visualsvn.com/server/download/   选 ...

  7. extjs6需要引入文件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 怎样在hibernate的HQL语句中使用mysql 的自定义函数?

    问题:怎样在hibernate中使用mysql的函数? 1.hibernate支持原生态的sql语句查询,使用session.createSQLQuery()创建查询对象: 2.怎样在hql中使用my ...

  9. dp+分类讨论 Gym 101128E

    题目链接:http://codeforces.com/gym/101128 感觉这个人写的不错的(我只看了题目大意):http://blog.csdn.net/v5zsq/article/detail ...

  10. [洛谷P4609] [FJOI2016]建筑师

    洛谷题目链接:[FJOI2016]建筑师 题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一 ...