MyBatis学习-2

配置文件

Posted by lvyonghao on April 14, 2019

Mybaits学习-2

本节解决上一课的小问题,以及谈谈MyBatis的配置文件。

1.接口式编程

在上一节中我们简单的使用了Mybaits提供的基础方法实现了一个数据的查找,我们使用SqlSession实例的selectOne方法传递在Mapper中的sql语句以及对应的参数,并把返回的类交给Dao,这次我们来说一个更常用的方法,接口式的方法,首先们要在创建一个接口:

package com.snake_lvyonghao.MyBatis.Dao;

import com.snake_lvyonghao.MyBatis.bean.Employee;

public interface EmpioyeeMapper  {
    public Employee getEmpById(Integer id);
}

接口中的方法返回类型就是我们持久层的类,参数当然是根据操作的具体要求而定,比如在这里我想要根据ID去查询他的所有信息,我的参数就是Integer id。 再回到我们上一节中的Mapper配置文件,当初我们的namespace是随便写的,现在我们要把它改成我们接口的包路径,比如我的是com.snake_lvyonghao.MyBatis.Dao.EmpioyeeMapper,我的sql语句的id改成接口方法的名字,这样就可以了:

<?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.snake_lvyonghao.MyBatis.Dao.EmpioyeeMapper">

    <!--
    namespace名称空间指定为全类名
    id唯一标示,指定为接口的方法
    resultType,返回值类型
    #{id}从传递过来的参数中取出id值-->
    <select id="getEmpById" resultType="com.snake_lvyonghao.MyBatis.bean.Employee">
    select id,last_name  lastName,email,gender from tbl_employee where id = #{id}
  </select>
</mapper>

然后回到我们的MyBatistest中,我们在写一个Demo,创建sqlSessionFactory对象,创建SqlSession对象这些和以前都是一样的,首先我们要创建一个接口的实例,用Sqlsession对象的getMapper方法初始化,再创建持久层的对象用接口的对象的方法获得实例(方法的返回值是DaoImpl类还记得吗?)。在这里我们发现了一个严重的问题,明明我们在接口中的方法没有去写,为什么这样的操作能够成功呢?实际上SqlSession的getMapper方法传回来是一个代理对象,下面是具体的实现;

package com.snake_lvyonghao.MyBatis.test;

import com.snake_lvyonghao.MyBatis.Dao.EmpioyeeMapper;
import com.snake_lvyonghao.MyBatis.bean.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class MyBatistest {


    /**
     * 1.根据xml配置文件(全局配置文件)创建一个SqlSessionFactory对象
     *      有一些数据源运行信息
     * 2.sql映射文件;配置可每一个sql,以及sql的封装规则,
     * 3.将sql映射文件注册在全局配置文件当中
     * 4.写代码
     *      1)根据全局配置文件得到SqlSessionFactory
     *      2)使用sqlSession工厂,获取到sqlSession对象使用它来执行增删改查
     *      一个sqlSession就是代表和数据库的一次会话,用完关闭
     *      3)使用sql的唯一标示告诉MyBatis执行那个sql,sql都保存在映射文件当中
     * @throws IOException
     */
    @Test
    public void test() throws IOException {
        String resource = "Mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(inputStream);

        //获取sqlSession实例,能直接执行已经映射的sql语句
        SqlSession opensession = sqlSessionFactory.openSession();

        //两个参数,sql的唯一标示,执行sql的参数
        try {
            Employee e = opensession.selectOne("org.mybatis.EmployeeMapper.selectEmp",1);
            System.out.println(e);
        }finally {
            opensession.close();
        }
    }

    //获取一个SqlSessionFactory对象
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "Mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test1() throws IOException{
        //1.获取SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();

        //2.获取SqlSession对象,
        SqlSession openSession = sqlSessionFactory.openSession();

        //3.获取接口的实现类对象
        //会为接口创建UI个代理对象,代理对象去执行增删改查
        try {
            EmpioyeeMapper mapper = openSession.getMapper(EmpioyeeMapper.class);

            Employee employee = mapper.getEmpById(1);

            System.out.println(mapper.getClass());

            System.out.println(employee);
        } finally {
            openSession.close();
        }

    }
}

2.小总结

  1. 通过MyBatis我们把Dao和方法分开,以前是一个Dao对应一个DaoImpl,现在是一个Mapper对应一个xxMapper.xml
  2. SqlSession代表和数据库的一次会话,用完就得关闭
  3. SqlSesson和connction一样都是非线程安全,就不可以写成private SqlSession sqlsession每次使用都应该获取新的对象
  4. mapper接口没有实现类,但是myBatis会为这个接口生成一个代理对象(将接口和xml绑定)
  5. 两个重要配置文件:全局配置文件,sql映射文件。

3.MyBatis-全局配置文件

在MyBatis配置文件中我们能做很多事情,下面我就为大家介绍配置文件的使用,配置文件是XML格式,我们通过<>标签的形式对XML进行配置,如何能够按照MyBatis配置文件的格式配置呢?我们只要在XML文件的开头写上Mybatis的约束就好了,<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">.


properties(不常用)

properties它可以通过Properties file来完成对数据库链接信息的配置:

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>
-----------------------------
<dataSource type="POOLED">
  <property name="driver" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>

settings

在这个标签里面都是一些MyBatis的设置,通过name,value来配置类似这样的(官方文档里面找的):

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

在官方文档中有着对setting能配置的东西有完整介绍,太多了我就不放了,你问我官方文档在哪里?下载的MyBatis里面得PDF就是他的官方文档,其中的ConfigurationXML讲的就是咱的配置文件。


typeAliase

别名处理器,可以为我们经常用java类型的起一个别名,不区分大小写,type属性就是要起别名的的类型全类名,默认别名就是类名小写,或者使用alisa属性起一个新的别名。

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

你也可以批量起别名,他可以为某个包下的所有类起别名,name属性指定包名(默认方法)

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

为了防止包下的子包有着相同的类名导致别名冲突,我们可以采用给类加上@Alias(“”)注解的方式去起别名。

@Alias("author")
public class Author {
... }

typeHandlers

类型处理器,在做数据库类型和MyBatis类型的适配的时候,会使用typeHanlders来完成。在官方文档中有着很多的介绍,我会在后面给出更详细的解释,现在知道有这么一个东西就好。


pugins

插件等到学完MyBatis运行机制和运行原理后我们才用得上插件这个功能,先做一个简单的介绍,MyBatis可以拦截到sql的核心语句,这个功能就是通过插件来实现,插件就是拦截这四个对象:

  1. Executor 执行器(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  2. ParameterHandler 参数处理器(getParameterObject, setParameters(预编译设置参数))
  3. ResultSetHandler 结果集处理器(handleResultSets, handleOutputParameters)
  4. StatementHandler sql处理器(prepare, parameterize, batch, update, query)

学过JDBC的应该对以上的方法很眼熟,我们到时候再说。


enviroments

MyBatis的多种环境配置,根据不同的使用使用不同的环境,比如开发时的测试环境,和正式上线后的正式环境其中每一个enviroment配置一个具体的环境信息,我们看着代码来说吧:

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

先说说environment的id属性,如何切换不同的环境配置呢,当然是通过environments的default属性,default属性值就是你所要使用的环境id。 在每一个environment中都需要有transactionManager标签(事务管理器),type属性值填写事务管理器的名称JDBC/MANAGED,当然在后面我们会之用SPring的事务管理代替这个,dataSource(数据源)标签,type属性的值填写UNPOOLED|POOLED|JNDI,分别是不使用连接池,使用链接池,以及JNDI(同样会使用Spring去代替他)。


databaseldProvider

用来告诉MyBatis我们使用的是哪个厂商的数据库,让sql支持多数据库厂商。

<databaseIdProvider type="DB_VENDOR">
  <!--为不同的数据库厂商起别名-->
  <property name="SQL Server" value="sqlserver"/>
  <property name="MySQL" value="mysql"/>
  <property name="Oracle" value="oracle" />
</databaseIdProvider>

这些起好名字怎么去使用呢,我们在sql映射文件中sql语句标签中添加M就可以告诉MyBatis我们使用的是哪一家的数据库。


mappers

将sql映射文件注册到全局当中,在写Helloworld式我们就使用过他了,我们当时使用的是resource属性这个是类路径下的映射文件,当然你也可以使用url属性应用网络路径或者磁盘路径下的sql映射文件,还有一个class属性,他是引用(注册)接口,

  • 有sql映射文件,映射文件必须喝接口同名,病房在于接口同一目录下。
  • 没有sql映射文件,所有sql都是利用注释写在接口上的

批量注册:使用package标签,name属性写入包路径。

    <mappers>
        <mapper class="com.snake_lvyonghao.MyBatis.Dao.EmployeeMapperAnnotation"/>
        <mapper resource="EmployeeMapper.xml"/>
        <package name="com.snake_lvyonghao.MyBatis.Dao"/>        
    </mappers>

package com.snake_lvyonghao.MyBatis.Dao;

import com.snake_lvyonghao.MyBatis.bean.Employee;
import org.apache.ibatis.annotations.Select;

public interface EmployeeMapperAnnotation {

    @Select("select * from tbl_employee where id=#{id}")
    public Employee getEmpById(Integer id);
}

推荐:重要的,复杂的Dao接口我们来写sql映射文件,不重要简单的Dao接口为了开发快速我们使用注解的方式,因为sql映射文件不用去修改源代码。

4.PS

一个小的提示,我们所有的标签其实是有顺序的,必须按照官方文档的顺序填写,不然会报错。 SSM框架源码