MyBatis 提高

Abstract

MyBatis 应用程序主要都是使用SqlSessionFactory实例的,一个 SqlSessionFactory 实例可以通过SqlSessionFactoryBuilder 获得。
SqlSessionFactoryBuilder 可以从一个 mybatis-config.xml 配置文件或者一个预定义的配置类的实例获得。
mybatis-config.xml 就是用于生成 SqlSessionFactory 实例的配置文件。
MyBatis 核心配置文件 mybatis-config.xml 中,大标签 configuration 下子标签包括:

configuration 配置
|--- properties 属性
|--- settings 设置
|--- typeAliases 类型命名
|--- typeHandlers 类型处理器
|--- objectFactory 对象工厂
|--- plugins 插件
|--- environments 环境
|     |--- environment 环境变量
|           |--- transactionManager 事务管理器
|           |--- dataSource 数据源
|--- databaseIdProvider 数据库厂商标识
|--- mappers 映射器


实际中,当MyBatis和诸如Spring等框架一起使用时,一些配置写在别的框架配置文件中。
现介绍各个标签的使用。

properties

存放数据库连接信息可以直接书写,如下这种方式

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo"/>
                <property name="username" value="root"/>
                <property name="password" value=""/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

但是更常见的做法是,将数据库连接信息存放在properties资源文件中。

  • 创建资源文件jdbc.properties
jdbc.driverClassName=ocom.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://localhost:3306/mybatis_demo 
jdbc.username=root  
jdbc.password=
  • 在mybatis-config.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">

<configuration>
    <properties resource="jdbc.properties" />

    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

当然也可以在properties标签中定义属性

<properties resource="jdbc.properties">
    <property name="jdbc.driverClassName" value="com.mysql.jdbc.Driver"/>
</properties>
  • 使用properties文件里的属性
<dataSource type="POOLED">  
    <property name="driver" value="${jdbc.driverClassName}"/>  
    <property name="url" value="${jdbc.url}"/>  
    <property name="username" value="${jdbc.username}"/>  
    <property name="password" value="${jdbc.password}"/>   
</dataSource>

:配置的加载顺序为

  1. 在 properties 元素体内指定的属性首先被读取。
  2. 从类路径下资源或 properties 元素的 url 属性中加载的属性第二被读取,它会覆盖已经存在的完全一样的属性。
  3. 作为方法参数传递的属性最后被读取,它也会覆盖任一已经存在的完全一样的属性,这些属性可能是从 properties 元素体内和资源/url 属性中加载的。

因此,属性的优先级为:方法直接传递参数 > 通过resource、url引用的资源 > properties元素体内定义

settings

设置MyBatis运行时的参数。

<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="defaultExecutorType" value="SIMPLE"/>
    <setting name="defaultStatementTimeout" value="25"/>
    <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>

具体参数含义请查阅http://www.mybatis.org/mybatis-3/zh/configuration.html#settings

typeAliases

作用是给Java类型取一个别名,方便在核心配置、映射配置中来使用这个Java类型。
例如原先UserMapper.xml的写法是

<mapper namespace="UserMapper">
    <select id="queryUser" resultType="com.ggli.entity.User">
        SELECT * FROM t_user
    </select>
</mapper>

而用typeAliases来进行别名配置后的写法是

<typeAliases>
    <typeAlias type="com.ggli.entity.User" alias="User"/>
</typeAliases>

<mapper namespace="UserMapper">
    <select id="queryUser" resultType="User">
        SELECT * FROM t_user
    </select>
</mapper>

除此之外,MyBatis还有许多内建类型别名供用户使用,在此不一一举例。

typeHandlers

类型处理器的作用是

  • 获取数据库的值,以合适的方式转变为对应的Java类型
  • 将Java类型,以合适的方式转化为数据库的保存类型

MyBatis中默认的类型处理器请参阅http://www.mybatis.org/mybatis-3/zh/configuration.html#typeHandlers

可以自定义类型处理器来处理不支持的或非标准的类型。具体做法为:实现 org.apache.ibatis.type.TypeHandler接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler,然后可以选择性地将它映射到一个 JDBC 类型。

objectFactory

每次MyBatis 为结果对象创建一个新实例,都会用到对象工厂(ObjectFactory)。
如果你重写objectFactory的默认操作,你可以通过继承 org.apache.ibatis.reflection.factory.DefaultObjectFactory 创建自定义操作。
编写一个类实现 DefaultObjectFactory,覆盖3个方法。

public class MyObjectFactory extends DefaultObjectFactory {
    public Object create(Class type) {
        return super.create(type);
    }
    public Object create(Class type, List<Class> constructorArgTypes, 
                         List<Object> constructorArgs) {
        return super.create(type, constructorArgTypes, constructorArgs);
    }
    public void setProperties(Properties properties) {
        super.setProperties(properties);
    }
}

最后在mybatis-config.xml 中加上 objectFactory 标签。

<objectFactory type="com.ggli.factory.MyObjectFatory"> 
    <property name="prop" value="val"/> 
</objectFactory>

plugins

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

Executor(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler(getParameterObject, setParameters)
ResultSetHandler(handleResultSets, handleOutputParameters)
StatementHandler(prepare, parameterize, batch, update, query)

通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定了想要拦截的方法签名即可。

// MyPlugin.java
@Intercepts({@Signature(
    type = Executor.class,
    method = "update",
    args = {MappedStatement.class,Object.class})})
public class MyPlugin implements Interceptor {
    public Object intercept(Invocation invocation) throws Throwable {
        return invocation.proceed();
    }
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    public void setProperties(Properties properties) {
    }
}
<!-- mybatis-config.xml -->
<plugins>
    <plugin interceptor="com.ggli.plugins.MyPlugin">
        <property name="prop" value="100"/>
    </plugin>
</plugins>

上面的插件将会拦截在 Executor 实例中所有的 “update” 方法调用, 这里的 Executor 是负责执行低层映射语句的内部对象。

除了用插件来修改 MyBatis 核心行为之外,还可以通过完全覆盖配置类来达到目的。只需继承后覆盖其中的每个方法,再把它传递到 sqlSessionFactoryBuilder.build(myConfig) 方法即可。

environments

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。不过:尽管可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一
所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例。

每个数据库对应一个 SqlSessionFactory 实例
为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。可以接受环境配置的两个方法签名:

SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment, properties);

如果忽略了环境参数,那么默认环境将会被加载:

SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, properties);

环境元素定义了如何配置环境。

<environments default="production">
    <environment id="production">
        <transactionManager type="MANAGED">
            <property name="closeConnection" value="false"/>
        </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)
在 MyBatis 中有两种类型的事务管理器,即 type="[JDBC|MANAGED]"

如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器, 因为 Spring 模块会使用自带的管理器来覆盖前面的配置。

数据源(dataSource)
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。有三种内建的数据源类型,即 type="[UNPOOLED|POOLED|JNDI]"

  • UNPOOLED

这个数据源的实现只是每次被请求时打开和关闭连接,它对在及时可用连接方面没有性能要求的简单应用程序是一个很好的选择。它需要配置5中属性

driver – 这是 JDBC 驱动的 Java 类的完全限定名(并不是JDBC驱动中可能包含的数据源类)。
url – 这是数据库的 JDBC URL 地址。
username – 登录数据库的用户名。
password – 登录数据库的密码。
defaultTransactionIsolationLevel – 默认的连接事务隔离级别。

作为可选项,你也可以传递属性给数据库驱动。要这样做,属性的前缀为“driver.”,例如:

driver.encoding=UTF8

  • POOLED

这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
除了上述提到 UNPOOLED 下的属性外,会有更多属性用来配置 POOLED 的数据源:

poolMaximumActiveConnections
poolMaximumIdleConnections
poolMaximumCheckoutTime
poolTimeToWait
poolPingQuery
poolPingEnabled
poolPingConnectionsNotUsedFor

第三方数据源
需要实现接口 org.apache.ibatis.datasource.DataSourceFactory, 也可使用任何第三方数据源:

public interface DataSourceFactory {
    void setProperties(Properties props);
    DataSource getDataSource();
}

org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory 可被用作父类来构建新的数据源适配器,比如下面这段插入 C3P0 数据源所必需的代码:

import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0DataSourceFactory extends UnpooledDataSourceFactory {
    public C3P0DataSourceFactory() {
        this.dataSource = new ComboPooledDataSource();
    }
}

在配置中使用该数据源

<dataSource type="com.ggli.C3P0DataSourceFactory">
    <property name="driver" value="org.postgresql.Driver"/>
    <property name="url" value="jdbc:postgresql:mydb"/>
    <property name="username" value="postgres"/>
    <property name="password" value="root"/>
</dataSource>

databaseIdProvider

MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。

mappers

既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。 Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。例如:

  • 直接引用定义好的 xml 文件
<!-- Using classpath relative resources -->
<mappers>
    <mapper resource="mappers/UserMapper.xml"/>
    <mapper resource="com/ggli/builder/AuthorMapper.xml"/>
    <mapper resource="com/ggli/builder/PostMapper.xml"/>
</mappers>
  • 通过绝对路径引用,注意在绝对路径前加上:file:///
<!-- Using url fully qualified paths -->
<mappers>
    <mapper url="file:///C:/Users/John/IdeaProjects/mybatis-basic/src/main/resources/mappers/UserMapper.xml"/>
    <mapper url="file:///var/mappers/AuthorMapper.xml"/>
    <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
  • 引用mapper接口对象的方式
<!-- Using mapper interface classes -->
<mappers>
    <mapper class="com.ggli.mapper.UserMapper"/>
    <mapper class="com.ggli.builder.AuthorMapper"/>
    <mapper class="com.ggli.builder.PostMapper"/>
</mappers>
  • 引用mapper接口包的方式:
<!-- Register all interfaces in a package as mappers -->
<mappers>
    <package name="com.ggli.mapper"/>
    <package name="com.ggli.builder"/>
</mappers>

这些配置会告诉了 MyBatis 去哪里找映射文件,剩下的细节就应该是每个 SQL 映射文件了。

参考:
http://www.mybatis.org/mybatis-3/zh/index.html

根据原作 https://pan.quark.cn/s/459657bcfd45 的源码改编 Classic-ML-Methods-Algo 引言 建立这个项目,是为了梳理和总结传统机器学习(Machine Learning)方法(methods)或者算法(algo),和各位同仁相互学习交流. 现在的深度学习本质上来自于传统的神经网络模型,很大程度上是传统机器学习的延续,同时也在不少时候需要结合传统方法来实现. 任何机器学习方法基本的流程结构都是通用的;使用的评价方法也基本通用;使用的一些数学知识也是通用的. 本文在梳理传统机器学习方法算法的同时也会顺便补充这些流程,数学上的知识以供参考. 机器学习 机器学习是人工智能(Artificial Intelligence)的一个分支,也是实现人工智能最重要的手段.区别于传统的基于规则(rule-based)的算法,机器学习可以从数据中获取知识,从而实现规定的任务[Ian Goodfellow and Yoshua Bengio and Aaron Courville的Deep Learning].这些知识可以分为四种: 总结(summarization) 预测(prediction) 估计(estimation) 假想验证(hypothesis testing) 机器学习主要关心的是预测[Varian在Big Data : New Tricks for Econometrics],预测的可以是连续性的输出变量,分类,聚类或者物品之间的有趣关联. 机器学习分类 根据数据配置(setting,是否有标签,可以是连续的也可以是离散的)和任务目标,我们可以将机器学习方法分为四种: 无监督(unsupervised) 训练数据没有给定...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值