Mybatis学习笔记02——配置文件、生命周期及作用域解析

1.Mybatis核心配置文件

  • MyBatis 核心配置文件推荐命名为: mybatis-config.xml
  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息
  • MyBatis 核心配置文件能配置的内容如下所示:

configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
注意元素节点的顺序!顺序不对会报错

1.1 environments节点

environments节点内容如下例所示:

<environments default="development">
 <environment id="development">
   <transactionManager type="JDBC">
     <property name="..." value="..."/>
   </transactionManager>
   <dataSource type="POOLED">
     <property name="driver" value="${driver}"/>
     <property name="url" value="${url}"/>
     <property name="username" value="${username}"/>
     <property name="password" value="${password}"/>
   </dataSource>
 </environment>
</environments>
  • 在environments元素中可配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,必须指定其中一个为默认运行环境(通过default指定)

  • environment子节点代表其中某一套运行环境,其节点下面主要有dataSource节点以及transactionManager 节点

  • dataSource 节点使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源,并且有3中数据源类型,分别是UNPOOLED、POOLED、JNDIUNPOOLED代表这个数据源的实现只是每次被请求时打开和关闭连接。POOLED代表这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。JNDI代表这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。

  • transactionManager为事务管理器,主要的类型用JDBCMANAGED ,目前一般都使用JDBC。

1.2 mappers节点

mappers节点的内容如下例所示:

 <!--每一个Mapper配置文件都需要在mybatis核心配置文件中定义-->
    <mappers>
        <mapper resource="UserMapper.xml"></mapper>
    </mappers>
  • mappers节点可作为映射器 :,来定义映射SQL语句文件
  • 既然 MyBatis 的行为其他元素已经配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。映射器是MyBatis中最核心的组件之一,在MyBatis 3之前,只支持xml映射器,即:所有的SQL语句都必须在xml文件中配置。而从MyBatis 3开始,还支持接口映射器,这种映射器方式允许以Java代码的方式注解定义SQL语句,非常简洁

1.3 Properties节点

数据库这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 节点的子元素来传递。所以我们可以在外部创建一个properties 文件并引入该properties 文件便能动态的获取属性值。
如在外面创建db.properties 文件,文件内容如下:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://xxxxxxxxxx:3306/mybaits_stuudy?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8
username=root
password=***********.

随后在Mybatis核心配置文件中的properties 节点引入该外部文件,并在dataSource节点中获取这些值,主要内容如下:

 <!--导入properties文件-->
    <!--properties内也可定义属性,但当属性名与外部文件冲突时,优先使用外部文件的属性-->
    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </properties>

在dataSource 节点中使用properties文件定义的属性

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

1.4 typeAliases节点

typeAliases即类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。

第一种使用方法:为某个实体类指定一个别名,那么在其他地方就可以通过别名来代表对应的实体类。
例如:在Mybatis核心配置文件中写上设置别名

 <typeAliases>
        <typeAlias type="pojo.User" alias="User"/>
    </typeAliases>

那么,在Mapper配置文件中就可以使用User来代替pojo.User

<?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">
<!--该配置文件的作用相当于是UserMapper接口的实现类,通过标签可以对应实现具体的方法-->
<!--namespace指定关联的Mapper接口-->
<mapper namespace="dao.UserMapper">
    <!--id用来关联Mapper接口下对应的方法,resultType则是指定返回结果集对应的实体类-->
    <select id="selectUser" resultType="User">
        select * from user
    </select>

    <select id="getUserById" resultType="User" parameterType="int">
        select * from user where id = #{id}
    </select>

    <!--对象传递参数,要与对象中的属性名对照-->
    <insert id="addUser" parameterType="User">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>

    <update id="updateUser" parameterType="User">
        update user set name = #{name},pwd = #{pwd} where id = #{id}
    </update>

    <delete id="deleteUser" parameterType="User">
        delete from user where id = #{id}
    </delete>
</mapper>

第二种使用方法:指定一个包名,那么MyBatis 就会在包名下面搜索需要的 Java Bean,在所指定包中的每一个实体类,在没有注解的情况下,会使用该实体类的的首字母小写的类名来作为它的别名。
例如:在Mybatis核心配置文件中写上设置别名

    <typeAliases>
        <package name="pojo"/>
    </typeAliases>

那么,在Mapper配置文件中就可以使用user来代替pojo.User

<?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">
<!--该配置文件的作用相当于是UserMapper接口的实现类,通过标签可以对应实现具体的方法-->
<!--namespace指定关联的Mapper接口-->
<mapper namespace="dao.UserMapper">
    <!--id用来关联Mapper接口下对应的方法,resultType则是指定返回结果集对应的实体类-->
    <select id="selectUser" resultType="user">
        select * from user
    </select>

    <select id="getUserById" resultType="user" parameterType="int">
        select * from user where id = #{id}
    </select>

    <!--对象传递参数,要与对象中的属性名对照-->
    <insert id="addUser" parameterType="user">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>

    <update id="updateUser" parameterType="user">
        update user set name = #{name},pwd = #{pwd} where id = #{id}
    </update>

    <delete id="deleteUser" parameterType="user">
        delete from user where id = #{id}
    </delete>
</mapper>

如果指定的包中的实体类有@Alias注解,那么该实体类的别名就为注解的值。如在pojo.User类上方加上注解@Alias(user11),那么该类的别名就为user11。

1.5 setting节点

一个配置完整的 settings 元素的示例如下:

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

其中比较重要的为:

在这里插入图片描述
在这里插入图片描述
具体设置可参阅官网文档:mybatis3官方文档

1.6其他配置

  • 类型处理器
    MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型
  • 对象工厂
    每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。 如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现

2.Mapper配置文件

<?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">
<!--该配置文件的作用相当于是UserMapper接口的实现类,通过标签可以对应实现具体的方法-->
<!--namespace指定关联的Mapper接口-->
<mapper namespace="dao.UserMapper">
    <!--id用来关联Mapper接口下对应的方法,resultType则是指定返回结果集对应的实体类-->
    <select id="selectUser" resultType="pojo.User">
        select * from user
    </select>

    <select id="getUserById" resultType="pojo.User" parameterType="int">
        select * from user where id = #{id}
    </select>

    <!--对象传递参数,要与对象中的属性名对照-->
    <insert id="addUser" parameterType="pojo.User">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>

    <update id="updateUser" parameterType="pojo.User">
        update user set name = #{name},pwd = #{pwd} where id = #{id}
    </update>

    <delete id="deleteUser" parameterType="pojo.User">
        delete from user where id = #{id}
    </delete>
</mapper>

namespace中文意思:命名空间,作用如下:
1.namespace的命名必须跟某个mapper接口同名
2.mapper接口中的方法与映射文件中sql语句id应该一一对应
3.namespace和子元素的id联合保证唯一 , 区别不同的mapper
4.绑定DAO接口
5.namespace命名规则 : 包名+类名

Mapper配置文件其实可以理解为对应Mapper接口的实现类,而在使用过程中,也是通过该配置文件来构造出Mapper接口的实现类的对象,从而才能进行数据库的CRUD。

3.生命周期和作用域

mybatis的运行流程如下图所示:
在这里插入图片描述

  • SqlSessionFactoryBuilder
    这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。换句话说,SqlSessionFactoryBuilder 对象在方法调用完毕之后就应该在内存中撤销掉。
    你可以重用SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。
  • SqlSessionFactory
    SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。此外,SqlSessionFactory 最主要的作用其实就是创建SqlSession对象
  • SqlSession
    每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。换句话说,SqlSession对象在方法调用完毕之后就应该在内存中撤销掉。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xulidanga

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值