Mybatis_总结_01_用_Mybatis配置文件

一、Mybatis简介

  MyBatis 是一款优秀的支持自定义SQL查询、存储过程和高级映射的持久层框架,消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索。 MyBatis 可以使用XML 或注解进行配置和映射。Mybatis通过将参数映射到配置的SQL形成最终执行的SQL语句,最后将执行SQL的结果映射成Java对象返回。

  与其他的ORM(对象关系映射)框架不同,Mybatis并没有将Java对象与数据表进行关联,而是将java方法与SQL语句关联,是一种“半自动化”的ORM实现。(Hibernate是全自动化ORM)。Mybatis允许用户充分利用数据库的各种功能,例如存储过程、视图、各种复杂的查询以及某数据库的专有特性。

 

二、MyBatis的配置文件结构

MyBatis的配置文件包含了影响MyBatis行为的信息,文档的结构如下:


顶层configuration配置

  • properties 属性
  • settings 设置
  • typeAliases 类型命名
  • typeHandlers 类型处理器
  • objectFactory 对象工厂
  • plugins 插件
  • environments 环境

    • environment 环境变量

      • transactionManager 事务管理器
      • dataSource 数据源
  • databaseIdProvider 数据库厂商标识
  • mappers 映射器

 

三、properties属性

properties是一个配置属性的元素,让我们能在配置文件的上下文中使用它。

 

1.加载顺序

如果属性在不止一个地方进行了配置,那么MyBatis按照下面的顺序来加载:

1.在properties元素体内指定的属性首先被读取

2.然后根据properties元素中的resource属性读取类路径下属性文件或者根据url属性指定的路径读取属性文件,并覆盖已读取的同名模块

3.最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。

 

因此优先级顺序:方法参数传递的属性  >  resource/url 属性中指定的配置文件 properties 属性中指定的属性

 

 

 

在MyBatis.xml的配置里面配置如下的属性

<dataSource type="pooled">
    <property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/springdatastudy?serverTimezone=UTC"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</dataSource>

 

2.properties配置文件

使用properties来配置属性,可以方便我们在多个配置文件重复使用,也可以随时修改及日后维护

(1)在resources文件夹下面创建datasource.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/springdatastudy?serverTimezone=UTC
username=root
password=root

 

(2)在MyBatis.xml配置文件的properties节点下引入properties文件

<properties resource="datasource.properties"/>

 

(3)其中的属性就可以在整个配置文件中使用来替换需要动态配置的属性值.

<!--数据源-->
<dataSource type="POOLED">
    <property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
</dataSource>

 

3.程序参数传值

实际工作中,数据库的用户名及密码可能是加密后的字符串。所以在SqlSessionFactoryBuilder处,需要将加密的字符串进行解密。

/**
 * 模拟字符串解密
 *
 * @param str
 * @return
 */
public static String decode(String str) {
    return str;
}

 

public static void main(String[] args) throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    Properties properties = new Properties();
    properties.load(Resources.getResourceAsStream("datasource.properties"));
    properties.setProperty("username",decode(properties.getProperty("username")));
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,properties);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    List<User> users = userDao.getUser();
    for (User u : users) {
        System.out.println(u.toString());
    }
}

 

四、settings设置

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。下表描述了设置中各项的意图、默认值等。

 

一个配置完整的 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>

 

1.cacheEnabled

boolean属性,默认是true。该配置影响的所有映射器中配置的缓存的全局开关。

 

2.lazyLoadingEnabled

boolean属性,默认值是false。延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。

 

3.aggressiveLazyLoading

boolean属性,jar版本3.4.1以下是true。3.4.1以上是false。当启用时,任何方法的调用都会加载该对象的所有属性。不开启,按需加载。

 

4.multipleResultSetsEnabled

boolean属性,默认值是true。是否允许单一语句返回多结果集合。(需要兼容驱动)

 

5.useColumnLabel

 boolean属性,默认值为true。使用列标签代替列名。

 

6.useGeneratedKeys

 boolean属性,默认值为false。允许JDBC支持自动生成主键。如果设置为true,则这个设置强制使用自动生成主键。(需要驱动兼容)

 

7.autoMappingBehavior

 枚举属性,三个可选值:None(表示取消自动映射)、Partial(表示只会自动映射没有定义嵌套结果集映射的结果集)、Full(表示会自动映射任意复杂的结果集),默认值为:Partial。

 

8.autoMappingUnknownColumnBehavior

枚举属性,三个可选值:None(不做任何反应)、WARNING(输出提醒日志,org.apache.ibatis.session.AutoMappingUnknownColumnBehavior日志等级必须设置为Warn)、FAILING(映射失败,抛出SqlSessionException)。默认值为None。

8.defaultExecutorType

枚举属性,三个可选值:SIMPLE(普通执行器)、REUSE(会重用预处理语句(prepared statements))、BATCH(重用语句并执行批量更新)

 

9.defaultExecutorType

枚举属性,三个可选值:SIMPLE(普通执行器)、REUSE(会重用预处理语句(prepared statements))、BATCH(重用语句并执行批量更新)

 

10.defaultStatmentTimeOut

 任意正整数,默认值没有设置。设置超时时间,它决定驱动等待数据库响应的秒数。

 

11.defaultFetchSize

任意正整数,默认值没有设置。为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数只可以在查询设置中被覆盖

 

12.safeRowBoundsEnabled

boolean属性,默认值为false。允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为false。

 

13.safeResultHandlerEnabled

boolean属性,默认值为true。允许在嵌套语句中使用分页(ResultHandler)。如果允许使用则设置为false。

 

14.mapUnderscoreToCamelCase

boolean属性,默认为false。是否开启自动驼峰命名规则(camelcase)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。

 

15.localCacheScope

枚举属性,两个枚举属性:SESSION(会缓存一个会话中执行的所有查询)、STATEMENT(本地会话仅用在语句执行上,对相同SqlSession的不同调用将不会共享数据。)。默认值为SESSION。

 

16.jdbcTypeForNull

JDBCType属性,常用的属性有:Null、Varchar、Other。当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。

 

17.lazyLoadTriggerMethods

指定哪个对象的方法触发一次延迟加载。

 

18.defaultScriptingLanguage

指定动态SQL生成的默认语言。

 

19.defaultEnumTypeHandler

Specifies the TypeHandler used by default for Enum. (Since: 3.4.5)

 

20. callSettersOnNulls

boolean属性,默认值为false。。指定当结果集中值为null的时候是否调用映射对象的 setter(map 对象时为put)方法,这对于有Map.keySet()依赖或null值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 null 的。

 

21.returnInstanceForEmptyRow

boolean属性,默认值为false。当返回行的所有列都是空时,MyBatis默认返回null。

 

22.logPrefix

String类型,指定 MyBatis 增加到日志名称的前缀。

 

23.logImpl

枚举值,指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING

 

24.proxyFactory

枚举值,指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。CGLIB | JAVASSIST。默认值:JAVASSIST (MyBatis 3.3 or above)

 

25.vfsImpl

指定VFS的实现。自定义VFS的实现的类全限定名,以逗号分隔。

 

26.useActualParamName

boolean属性,默认值为true。允许使用方法签名中的名称作为语句参数名称。为了使用该特性,你的工程必须采用Java8编译,并且加上-parameters选项。(从3.4.1开始)

 

27.configurationFactory

指定一个提供Configuration实例的类.这个被返回的Configuration实例是用来加载被反序列化对象的懒加载属性值. 这个类必须包含一个签名方法static Configuration getConfiguration(). (从 3.2.3 版本开始)

 

五、typeAliases(类型别名)

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

例如:

(1)MyBatis.xml里面设置别名

<typeAliases>
    <typeAlias type="model.User" alias="yuser"></typeAlias>
</typeAliases>

(2)Mapper.xml文件里面使用

<select id="getUser" resultType="yuser">
    select * FROM  user;
</select>

 

1.自动扫描包自定义别名

如果POJO过多的时候,配置也非常多。这时候,我们可以使用自动扫描包自定义别名的方式。

(1)MyBatis.xml里面的设置扫描包的名称

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

(2)POJO上设置别名

@Alias("sasUser")
public class User {
}

(3)Mapper.xml使用方法

<select id="getUser" resultType="sasUser">
    select * FROM  user;
</select>

 

2.系统定义别名

 

别名映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

 六、typeHandlers(类型处理器)


(1)无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。

(2)也就是将参数从Java类型(javaType)转换为jdbcType;或者从数据库取出结果把jdbcType转化为javaType。

(3)typeHandler和typeAliases(类型别名)一样,分为系统定义及用户自定义。

 

1.系统定义的typeHandler

 

类型处理器Java 类型JDBC 类型
BooleanTypeHandler java.lang.Boolean, boolean 数据库兼容的 BOOLEAN
ByteTypeHandler java.lang.Byte, byte 数据库兼容的 NUMERIC 或 BYTE
ShortTypeHandler java.lang.Short, short 数据库兼容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandler java.lang.Integer, int 数据库兼容的 NUMERIC 或 INTEGER
LongTypeHandler java.lang.Long, long 数据库兼容的 NUMERIC 或 LONG INTEGER
FloatTypeHandler java.lang.Float, float 数据库兼容的 NUMERIC 或 FLOAT
DoubleTypeHandler java.lang.Double, double 数据库兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandler java.math.BigDecimal 数据库兼容的 NUMERIC 或 DECIMAL
StringTypeHandler java.lang.String CHAR, VARCHAR
ClobReaderTypeHandler java.io.Reader -
ClobTypeHandler java.lang.String CLOB, LONGVARCHAR
NStringTypeHandler java.lang.String NVARCHAR, NCHAR
NClobTypeHandler java.lang.String NCLOB
BlobInputStreamTypeHandler java.io.InputStream -
ByteArrayTypeHandler byte[] 数据库兼容的字节流类型
BlobTypeHandler byte[] BLOB, LONGVARBINARY
DateTypeHandler java.util.Date TIMESTAMP
DateOnlyTypeHandler java.util.Date DATE
TimeOnlyTypeHandler java.util.Date TIME
SqlTimestampTypeHandler java.sql.Timestamp TIMESTAMP
SqlDateTypeHandler java.sql.Date DATE
SqlTimeTypeHandler java.sql.Time TIME
ObjectTypeHandler Any OTHER 或未指定类型
EnumTypeHandler Enumeration Type VARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引)
EnumOrdinalTypeHandler Enumeration Type 任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称)。

(1)时间精度

数据精确到天的使用DateOnlyTypeHandler即可,需要精确到秒的用SqlTimestampHandler。也就是Java类型使用java.sql.Timestamp。数据库类型设置为Timestamp或者datetime。

(2)DateTime与Timestamp区别
  • 时间范围不一样。DateTime时间范围:''1000-01-01 00:00:00''到''9999-12-31 23:59:59''。而Timestamp时间范围:在1970~2037年之间。

  • timestamp与时区有关,而datetime与时区无关。

  • timestamp存储是4个字节存储的,而datetime存储是8个字节存储的。

2.自定义TypeHanlder

一般情况下,MyBatis系统定义的typeHandler已经应付了大部分场景,但是有时候我们需要特殊处理一些Java类型与JDBC对应的类型,该如何定义。

(1)实现接口TypeHandler或者继承BaseTypeHandler

@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class ExampleTypeHandler extends BaseTypeHandler<String> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        System.out.println("example setNonNullParameter");
        ps.setString(i,parameter);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        System.out.println("example getNullableResult");
        return rs.getString(columnName);
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        System.out.println("example getNullableResult");
        return rs.getString(columnIndex);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        System.out.println("example getNullableResult");
        return cs.getString(columnIndex);
    }
}
View Code

 

使用@MappedTypes注释,来指定与其关联的Java类型列表。

使用@MappedJdbcTypes注释,来指定与其关联的JDBC类型列表

(2)在MyBatis-config.xml里面配置typeHandler(类型处理器)
<!--类型处理器-->
<typeHandlers>
    <typeHandler javaType="string" jdbcType="VARCHAR" handler="utils.ExampleTypeHandler"/>
</typeHandlers>

 

(3)在mapper.xml文件中指定typeHandler进行转换。

尽管上面我们自定义了类型处理器类,并在MyBatis全局xml里面配置了类型处理器。但是MyBatis还是不会自动启用你定义的typeHandler进行转换结果。需要人为的去指定哪些参数哪些结果类型去用自定义类型处理器。

需要人为配置jdbcType和javaType。或者直接用typeHandler属性指定。

 

定义jdbcType和javaType

<resultMap id="AllColumnMap" type="model.DateDemo">
    <result column="name" property="name" javaType="string" jdbcType="VARCHAR"/>
    <result column="createdOn" property="createOn"/>
</resultMap>

 

直接使用typeHandler

<resultMap id="AllColumnMap" type="model.DateDemo">
    <result column="name" property="name" javaType="string" jdbcType="VARCHAR" typeHandler="utils.ExampleTypeHandler"/>
    <result column="createdOn" property="createOn"/>
</resultMap>

 

select语句

<select id="getUser" resultType="model.DateDemo" resultMap="AllColumnMap">
    select * from datedemo;
</select>

 

 

3.枚举类型的typeHandler

虽然MyBatis提供了两个转化枚举的typeHandler给我们使用,但是对应枚举却有自己的特殊转换要求

  • org.apache.ibatis.type.EnumTypeHandler

  • org.apache.ibatis.type.EnumOrdinalTypeHandler

定义一个枚举类型类

@Data
public enum Sex {
    MALE(1, "男"),
    FEMALE(2, "女");

    private int id;
    private String name;

    private Sex(int id, String name) {
        this.id = id;
        this.name = name;
    }

 

当只有类用到字段属性Sex时候,才用到枚举类型处理器。一般实际项目中,都是使用int作为枚举类型。这边就跳过介绍。

 

七、ObjectFactory对象工厂

当MyBatis在构建一个结果返回的时候,都会使用ObjectFactory去构建POJO,在MyBatis中可以定制自己的对象工厂。一般而言使用默认的DefaultObjectFactory。这里不在赘述。

 

八、environments配置环境

配置环境可以注册多个数据源(dataSource),每一个数据源分为两大部分,一个是数据库源的配置,另一个是数据库事务(transactionManager)的配置。

<!--配置环境-->
<environments default="default">
    <!--环境变量-->
    <environment id="default">
        <!--事务管理器-->
        <transactionManager type="JDBC"></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>

 

transactionManager配置的是数据库事务。其中type属性有三种配置方式:

  • JDBC,采用JDBC方式管理事务
  • Managed,采用容器方式管理事务,在JNDI数据源中常用
  • 自定义。

注: 如果开发使用Spring+MyBatis,则没有必要配置事务管理器,因为Spring模块会使用自带的管理器来覆盖前面的配置.

 

dataSource,是配置数据源连接的信息。type属性有4种:

  • UNPOOLED:非连接池数据库。这个数据源的实现只是每次被请求时打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。不同的数据库在这方面表现也是不一样的。
  • POOLED:连接池数据库。这种数据源的实现利用“池”的概念将JDBC连接对想组织起来,避免了创建新的连接实例时所必需的初始化时间和认证时间。这是一种使得并发Web应用快速响应请求的流行处理方式,除了上述提到的UNPOOLED的5中属性外,还可以使用更多的属性来配置POOLED的数据源:

    • poolMaximumActiveConnections:在任意时间可以存在的活动(也就是正在使用)连接数量,默认值是10.
    • poolMaximumIdleConnections:任意时间可能存在的空闲连接数.
    • poolMaximunCheckoutTime:在被强制返回之前,池中连接被检出时间,默认值为20000毫秒(即20秒).
    • poolTimeToWait:这是一个底层设置,如果获取连接花费相当长的时间,它会给连接池打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直安静地失败),默认值为20000毫秒(20秒).
    • poolPingQuery:发送到数据库的侦测查询,用来检验连接是否处于正在工作秩序中并准备接受请求.默认是"NO PING QUERY SET",这会导致多数数据库驱动失败时带有一个恰当的错误消息.
    • poolPingEnabled:是否启用侦测查询.若开启,也必须使用一个可执行的sql语句设置poolPingQuery属性(最好是一个非常快的sql),默认值为false.
    • poolPingConnectionsNotUsedFor:配置poolPingQuery的使用频度.这可以被设置成匹配具体的数据库连接超时时间,来避免不必要的侦测,默认值为0(即所有连接每一时刻都被侦测,当然仅当poolPingEnabled为true时适用).
  • JNDI:JNDI数据源。这个数据源的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用.这种数据源配置只需要两个属性

 

8.1 数据库事务

数据库事务是由SqlSession去控制的,可以通过SqlSession提交(commit)或者回滚(rollback)。如果成功就提交,如果失败就回滚。

try {
    sqlSession.commit();
} catch (Exception ex) {
    ex.printStackTrace();
    sqlSession.rollback();
}

 

九、mappers(映射器)

上述的一些是MyBatis的一些行为属性配置。那么我们现在要定义SQL映射语句了。但是首先我们需要告诉MyBatis到哪里去找到这些语句。

可以使用类路径的资源引用,或者完全限定的资源定位符(包括:file:///的URL),或者类名和包名。

 

1.文件路径引入

<mappers>
    <mapper resource="mapper/DateDemoDao.xml"></mapper>
</mappers>

 

2.包名引入

<!-- Register all interfaces in a package as mappers -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

 

3.使用类注册

<!-- Using mapper interface classes -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

 

4.使用url注册

<!-- Using url fully qualified paths -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>

 

 

 

 

十、参考资料

1.MyBatis XML配置-w3cschool

2.深入MyBatis配置文件

3.详解MyBatis的配置文件

 

posted @ 2018-09-02 23:02  shirayner  阅读(312)  评论(0)    收藏  举报