Mybatis配置文件如何进行配置呢?

Mybatis配置文件配置的方式

  • properties
  • settings
  • typeAliases
  • typeHandlers
  • objectFactory
  • plugins
  • environments
  • transactionManager
  • dataSource
  • mappers

案例实操

1. properties

这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。例如:

<property name="driver" value="com.mysql.jdbc.Driver" />            
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />             
<property name="username" value="root" />             
<property name="password" value="root" />

其中的属性就可以在整个配置文件中使用来替换需要动态配置的属性值。比如:

<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>

如何配?

在config.xml 文件中<configuration>引入子标签

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

并修改原有数据源连接相关配置如下:

<environments default="development">    
    <environment id="development">   
        <transactionManager type="JDBC" />    
        <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>

即可完成。

2. settings(了解)

这是MyBatis 修改操作运行过程细节的重要的步骤。下方这个表格描述了这些设置项、含义和默认值。一般我们用默认即可(详细解释见官网文档)

对应xml配置如下(开发中一般采用默认配置即可):

<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>

3.typeAliases

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

Configuration 标签下添加

<typeAliases>   
    <typeAlias alias="customer" type="com.xxx.pojo.Customer" />
</typeAliases>

修改CustomerMapper.xml 文件

 <!-- 查询客户-->
<select id="queryCustomerById" parameterType="int" resultType="customer">
    SELECT id,user_name 'userName' FROM  yg_customer WHERE  id=#{id}
</select>

也可以指定一个包名(大家最喜欢的方式),MyBatis 会在包名下面搜索需要的 Java Bean,比如:

<typeAliases>    
    <!-- <typeAlias alias="customer" type="com.xxx.pojo" /> -->    
    <package name="com.xxx.pojo"/>
</typeAliases>

每一个在包com.xxx.pojo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如com.xxx.pojo.Customer 的别名为customer ;

若有注解,则别名为其注解值。 注解名@Alias(value=“user”)

同样mybatis已经为我们构建了相应的类型别名,它们都是大小写不敏感的,需要注意的是由基本类型名称重复导致的特殊处理。

别名 映射的类型
_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

4.typeHandlers 类型处理器(面试有可能会问)

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

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 类型,存储枚举的索引(而不是名称)。

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

5. 对象工厂(objectFactory)(了解)

MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。默认情况下,我们不需要配置,mybatis会调用默认实现的objectFactory。从这个类的外部看,这个类的主要作用就是根据一个类的类型得到该类的一个实体对象,比如,我们给他一个User的type,他将会给我们一个Tiger的实体对象,我们给他一个java.lang.List对象,他将会给我们一个List的实体对象。类似于spring 工厂实例化bean

6. plugins 插件

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

· Executor (sql执行时, update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)

· ParameterHandler (参数的处理, getParameterObject, setParameters)

· ResultSetHandler (结果集的处理, handleResultSets, handleOutputParameters)

· StatementHandler (申明语句的处理, prepare, parameterize, batch, update, query)

这些类中方法的细节可以通过查看每个方法的签名来发现,或者直接查看 MyBatis 的发行包中的源代码。 假设你想做的不仅仅是监控方法的调用,那么你应该很好的了解正在重写的方法的行为。 因为如果在试图修改或重写已有方法的行为的时候,你很可能在破坏 MyBatis 的核心模块。 这些都是更低层的类和方法,所以使用插件的时候要特别当心。

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

总配置添加

 <!-- 插件 -->   
<plugins>   
    <plugin interceptor="com.xxx.plugins.ExamplePlugin">          
        <property name="someProperty" value="100" />   
    </plugin>
</plugins>

插件demo:

@Intercepts({   
    @Signature(      
        type=Executor.class,       
        /**         
        * 拦截所有方法    
        */     
        method="query",       
        /**          
        * 参数定义     
        */          
        args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class}            )
}) 
public class ExamplePlugin implements Interceptor {   
    /**    
    * 每个插件必须实现以下三个方法   
    */    
    /**    
    * Object intercept(Invocation invocation)是实现拦截逻辑的地方,  
    * 内部要通过invocation.proceed()显式地推进责任链前进,也就是调用下一个拦截器拦截目标方法。 
    */   
    public Object intercept(Invocation invocation) throws Throwable {                            System.out.println("intercept");     
         return invocation.proceed();  
      }      
    /**    
    * Object plugin(Object target) 就是用当前这个拦截器生成对目标target的代理,   
    * 实际是通过Plugin.wrap(target,this) 来完成的,把目标target和拦截器this传给了包装函数。   
    */   
    public Object plugin(Object target) {    
        return Plugin.wrap(target, this);   
    }       
    /**    
    * setProperties(Properties properties)用于设置额外的参数,参数配置在拦截器的Properties节点里。   
    */   
    public void setProperties(Properties properties) {                                          System.out.println(properties.get("hello"));  
    }
}

7. 配置环境(environments)(熟悉 配多个数据源)

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。许多类似的用例。

不过要记住:尽管可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一。

所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推,记起来很简单:

· 每个数据库对应一个 SqlSessionFactory 实例

<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC" />
        <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>

    <environment id="test">
        <transactionManager type="JDBC" />
        <dataSource type="POOLED">
            <property name="driver" value="${driver2}" />
            <property name="url" value="${url2}" />
            <property name="username" value="${username2}" />
            <property name="password" value="${password2}" />
        </dataSource>
    </environment>
</environments>

## development
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8
username=root
password=root

## test
driver2=com.mysql.jdbc.Driver
url2=jdbc:mysql://127.0.0.1:3306/mybatis2?useUnicode=true&amp;characterEncoding=utf8
username2=root
password2=root

测试sqlSessionFactory

public void test02() {   
    InputStream in;   
    try {        
        in = Resources.getResourceAsStream(this.getClass().getClassLoader()
                , "config.xml");      
         // 默认开发库     
         //SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in);          // 测试库       
         SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in,"test");       
         UserDao userDao=new UserDaoImpl(sqlSessionFactory);      
         User user= userDao.queryUserById(1);     
         System.out.println(user); 
        } catch (IOException e) {    
        e.printStackTrace();    
    }
}

8. 事务管理器(transactionManager)(了解)

在 MyBatis 中有两种类型的事务管理器(也就type=”[JDBC|MANAGED]”):

  • JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围。
  • MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。例如:
<transactionManager type="MANAGED">  
    <property name="closeConnection" value="false"/>
</transactionManager>

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

9.dataSource 数据源(了解)

dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。

数据源类型有三种:UNPOOLED,POOLED,JNDI

UNPOOLED

这个数据源的实现只是每次被请求时打开和关闭连接。虽然有一点慢,它对在及时可用连接方面没有性能要求的简单应用程序是一个很好的选择。 不同的数据库在这方面表现也是不一样的,所以对某些数据库来说使用连接池并不重要,这个配置也是理想的。

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

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

  • driver.encoding=UTF8

这将通过DriverManager.getConnection(url,driverProperties)方法传递值为 UTF8 的 encoding 属性给数据库驱动。

POOLED

​ 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。(一般选用这种)

  • poolMaximumActiveConnections – 在任意时间可以存在的活动(也就是正在使用)连接数量,默认值:10

  • poolMaximumIdleConnections – 任意时间可能存在的空闲连接数。

  • poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)

  • poolTimeToWait – 这是一个底层设置,如果获取连接花费的相当长的时间,它会给连接池打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直安静的失败),默认值:20000 毫秒(即 20 秒)。

  • poolPingQuery – 发送到数据库的侦测查询,用来检验连接是否处在正常工作秩序中并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动失败时带有一个恰当的错误消息。

  • poolPingEnabled – 是否启用侦测查询。若开启,也必须使用一个可执行的 SQL 语句设置 poolPingQuery 属性(最好是一个非常快的 SQL),默认值:false。

  • poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的使用频度。这可以被设置成匹配具体的数据库连接超时时间,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。

JNDI

​ 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。

  • initial_context – 这个属性用来在 InitialContext 中寻找上下文(即initialContext.lookup(initial_context))。这是个可选属性,如果忽略,那么 data_source 属性将会直接从 InitialContext 中寻找。
  • data_source – 这是引用数据源实例位置的上下文的路径。提供了 initial_context 配置时会在其返回的上下文中进行查找,没有提供时则直接在 InitialContext 中查找。和其他数据源配置类似,可以通过添加前缀“env.”直接把属性传递给初始上下文。比如:
  • env.encoding=UTF8

这就会在初始上下文(InitialContext)实例化时往它的构造方法传递值为 UTF8 的 encoding 属性。

10.mappers 映射器(四种配置)(熟悉)

这里是告诉mybatis去哪寻找映射SQL 的语句。可以使用类路径中的资源引用,或者使用字符,输入确切的URL 引用。

!— sqlmapper配置文件路径 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

<!—url绝对路径形式-->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>

<!—接口 列表配置形式  注解sql-->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

<!—映射包下所有接口-->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

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

扩展

封装Dao

1新建接口CustomerDao

接口定义:

public interface CustomerDao {
    Customer queryCustomerByName(String userName);
}

2 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.xxx.dao.CustomerDao">
    <!-- 查询客户-->
    <select id="queryCustomerByName" parameterType="string" resultType="com.xxx.pojo.Customer">
      SELECT id,user_name 'userName',user_balance 'userBalance' FROM  yg_customer WHERE  user_name=#{userName}
    </select>
</mapper>

3 mappers映射器配置

<mappers>
       <!-- <mapper resource="com/xxx/mapper/CustomerDao.xml" />-->
        <package name="com.xxx.dao"/>
</mappers>

4 测试

public class App 
{
    public static void main( String[] args ) throws IOException {
        //1 加载配置文件
        InputStream is = Resources.getResourceAsStream("mybatis.xml");
        //2 创建sqlsessionfactor工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //3 构建数据库会话
        SqlSession session = factory.openSession();
       /* Customer customer = session.selectOne("com.xxx.mapper.customerMapper.queryCustomerById", 2);
        System.out.println(customer);*/
        CustomerDao customerDao = session.getMapper(CustomerDao.class);
        Customer customer = customerDao.queryCustomerByName("zhaoliying");
        System.out.println(customer);
        session.close();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345