mybatis核心配置文件

environment

enviroment可以配置多个datasource环境,用于部署到不同的环境中,想要改变不同环境时只需要改变默认的enviroment的值即可。

<environments default="shoppingcart">
	<environment id="shoppingcart">
		<transactionManager type="MANAGED" />
		<dataSource type="JNDI">
			<property name="data_source" value="java:comp/jdbc/ ShoppingcartDS" />
		dataSource>
	environment>
	<environment id="reports">
		<transactionManager type="MANAGED" />
		<dataSource type="JNDI">
			<property name="data_source" value="java:comp/jdbc/ReportsDS" />
	dataSource>
	environment>
environments>

如果应用中想要使用多个数据库,那么将每一个数据库配置成独立的环境,并且为每一个数据库建立一个sqlSessionFactory即可。依然是上面的配置文件:

inputStream = Resources.getResourceAsStream("mybatis-config.xml");
defaultSqlSessionFactory = new SqlSessionFactoryBuilder().
build(inputStream);
cartSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, "shoppingcart");
reportSqlSessionFactory = new SqlSessionFactoryBuilder().
build(inputStream, "reports");

也就是build()方法的第二个参数(DataSource的id)是可以指定使用哪一个DataSource的。

数据源DataSource

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

DataSource的类型有三个值:

  • UNPOOLED:如果将类型设置为unpooled,mybatis会为每一个数据库操作创建一个新的连接,并关闭它,该方式适用于只有小规模数量并发用户的简单应用程序上。
  • POOLED:如果将类型设置为pooled,mybatis会创建一个数据库连接池,连接池中的一个连接将会被用作数据库操作,一旦数据库操作完成,mybatis会将此链接返回给连接池,一般在开发或测试环境中使用这个参数。
  • JNDI:类型设置为jndi,mybatis会从应用服务器向配置好的jndi数据源datasource获取数据库连接,一般是在生产环境中使用。

transactionManager事务管理器

<environment id="">
	<transactionManager type="JDBC" />
environment>

transactionManager是配置在environment标签的下面,mybatis支持两种类型的事务管理器

  • jdbcjdbc事务管理器被用作当应用程序负责管理数据库连接的生命周期(提交、回退等)的时候。当该属性配置为jdbc的时候,mybatis内部会将使用JdbcTransactionFactor类创建TransactionManager
  • managed:事务管理器是由应用服务器负责管理数据库连接生命周期的使用使用,当该属性配置为Manager时,mybatis内部使用ManagedTransactionFactor有类创建事务管理器TransactionManager。(使用manged时也就意味着应用本身不去管理事务,而是将事务管理交给应用所在在的服务器进行管理)

properties属性配置元素

可以直接在配置文件中使用properties配置元素,同时该元素也可以将配置值具体化到一个属性文件中,并且使用属性文件的key名作为占位符,比如现在将数据库连接信息放在一个application.properties文件中

application.properties:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatisdemo
jdbc.username=root
jdbc.password=admin

在mybatis核心配置文件的中的properties属性配置如下:

<properties resource="application.properties">
    <property name="jdbc.username" value="db_user" />
    <property name="jdbc.password" value="verysecurepwd" />
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>

对于usernamepassword两个属性在配置文件和属性文件都有,此时需要注意它们的加载顺序,加载顺序是先加载核心配置文件中的内容,然后再加载属性文件的内容,如果key相同,后面加载的内容会覆盖前面加载的内容。因此上面的例子中username的值最终为rootpassword的值最终为admin

typeAliases别名配置

配置文件取别名

在mapper配置文件中如果没有配置别名,那么parameterType(入参类型,传入参数的类型),resultType(返回参数的类型)都是需要完全限定的,当然如果入参是基本类型,比如说String那么是不用写java.lang.String,直接写String就可以了。但是如果是自己定义的类型,就需要带上包名,比如:

<select id="findStudentById" parameterType="int" resultType="com.mybatis3.domain.Student">
    SELECT STUD_ID AS ID, NAME, EMAIL, DOB  FROM STUDENTS WHERE STUD_ID=#{Id}
select>
<update id="updateStudent" parameterType="com.mybatis3.domain.Student">
    UPDATE STUDENTS SET NAME=#{name}, EMAIL=#{email}, DOB=#{dob}  WHERE STUD_ID=#{id}
update>

上面的resultType与parameterType都是写的全路径,这样是比较麻烦的,因此我们可以在mybatis核心配置文件中使用typeAliases标签来配置别名:

<typeAliases>
    <typeAlias alias="Student" type="com.mybatis3.domain.Student" />
    <package name="com.mybatis3.domain" />
typeAliases>

上面的映射文件就可以修改为:

<select id="findStudentById" parameterType="int" resultType="Student">
    SELECT STUD_ID AS ID, NAME, EMAIL, DOB
    FROM STUDENTS WHERE STUD_ID=#{id}
select>
<update id="updateStudent" parameterType="Student">
    UPDATE STUDENTS
    SET NAME=#{name}, EMAIL=#{email}, DOB=#{dob}
    WHERE STUD_ID=#{id}
update>

看一看到上面配置别名的时候使用了两种方式:

  • 这一种方式是只是为一个java类配置别名,也就是说只有出现com.mybatis3.domain.Student的地方可以使用Student代替。这种方式比较麻烦,可以使用第二种方式。
  • 这种方式相当于是批量配置别名,使用包的方式时name所对应的包下面的类会自动配置别名,比如上面配置了package name="com.mybatis3.domain"就相当于所有com.mybatis3.domain下面的类都配置了别名,别名就是类名

注解取别名

上面两种方式是在核心配置文件中修改的,当然也是可以通过注解的方式来配置别名。

@Alias("StudentAlias")
public class Student{}

上面使用注解也是将类Student配置了别名StudentAlias

类型处理器typeHandlers

基本类型

当我们将一个java对象作为一个输入参数执行insert语句时,它执行的步骤如下:

  • 创建一个PreparedStatement对象,并且使用setXXX()方法来设置参数。这里的xxx代表的是类型,可以是int,String,Date等java中已经含有的类型
<insert id="insertStudent" parameterType="Student">
insert into students(STUD_ID, name, email, dob) values(#{studId}, #{name}, #{email}, #{dob})
insert>
  • 创建带有占位符的PreparedStatement接口
PreparedStatement stmt = connection.prepareStatement(insert into students(?, ?, ?, ?) values(#{studId}, #{name}, #{email}, #{dob}));
  • 检查student类里面的属性,会判断属性的类型然后再使用和是的setXXX()方法,比如这里的nameString类型,那么就会使用setString(2, studnet.getName());这里可以根据对象的属性类型自动决定使用什么方法就是因为有了typeHandlers

自定义类型

上面的类型转换是java中的基本类型,但是如果想要使用自定义的对象类型,又该如何转换呢?

比如students表中有一个字段时phone,类型是varchar(15),对应的Student的javaBean有一个phoneNumber类来定义这个phonNumber属性。

public class PhoneNumber{
    private String countryCode;
    private String stateCode;
    private String number;
    public PhoneNumber(){};
    public PhoneNumber(String countryCode, String stateCode, String number){
        this.countryCode = countryCode;
        this.stateCode = stateCode;
        this.number = number;
    }
    public PhoneNumber(String string){
        if(string != null){
            String[] parts = string.split("-");
            if(parts.length > 0) this.countryCode = parts[0];
            if(parts.length > 1) this.countryCode = parts[1];
            if(parts.length > 2) this.countryCode = parts[2];
        }
    }
    
    public String getAsString(){
        return countryCode + "-" + stateCode + "-" + number;
    }
    //省略了set和get方法
}
public class Student{
    private Integer id;
    private String name;
    private String email;
    private PhoneNumber phone;
    //省略set和get方法
}

	insert into studnets(name, email, phone) values(#{name}, #{email}, #{phone})
insert>

上面的新增语句中phone参数是需要传递给#{phone},不过phone是自己定义的class,是phoneNumber类型的,此时mybatis是不能帮我们自动转换的,此时就需要我们创建一个自定义的类型处理器,mybatis提供了1抽象类BaseTypeHandler,我们只需要继承该类就可以自定义类型处理器。

packagecom.mybatis3.typehandlers;
importjava.sql.CallableStatement;
importjava.sql.PreparedStatement;
importjava.sql.ResultSet;
importjava.sql.SQLException;
importorg.apache.ibatis.type.BaseTypeHandler;
importorg.apache.ibatis.type.JdbcType;
importcom.mybatis3.domain.PhoneNumber;

public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber>{
   
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i,
        PhoneNumber parameter, JdbcType jdbcType) throws SQLException{
        ps.setString(i, parameter.getAsString());
    }
    
    @Override
    public PhoneNumber getNullableResult(ResultSet rs, String columnName)
        throws SQLException{
        return new PhoneNumber(rs.getString(columnName));
    }
   
    @Override
    public PhoneNumber getNullableResult(ResultSet rs, int columnIndex)
    throws SQLException {
    	return new PhoneNumber(rs.getString(columnIndex));
    }
    
    @Override
    public PhoneNumber getNullableResult(CallableStatement cs, int columnIndex)
    throws SQLException {
    	return new PhoneNumber(cs.getString(columnIndex));
    }
}

上面的例子中使用ps.setString()rs.getString()方法是因为phone列是varchar类型。

当我们实现了自定义的类型处理器,还需要在mybatis-config.xml中进行注册:



<configuration>
<properties resource="application.properties" />
    <typeHandlers>
    	<typeHandler handler="com.mybatis3.typehandlers.PhoneTypeHandler" />
    typeHandlers>
configuration>

进行注册之后就可以将phone类型的对象存储到varchar类型的列上。

全局参数设置

mybatis的默认的全局参数可以通过setting标签来覆盖掉:

<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" />
settings>

sql映射文件

我们需要在mybatis核心配置文件中加载mapper映射文件,有几下几种方式:

<mappers>
    <mapper resource="com/mybatis3/mappers/StudentMapper.xml" />
    <mapper url="file:///D:/mybatisdemo/app/mappers/TutorMapper.xml" />
    <mapper class="com.mybatis3.mappers.TutorMapper" />
    <package name="com.mybatis3.mappers" />
mappers>
  • 方式一:resource属性可以用来指定classpath中的mapper文件
  • 方式二:url属性用来通过文件系统路径或者web url地址来指向mapper文件
  • 方式三:class属性用来指定一个mapper接口
  • 方式四:package属性用来指向可以找到mapper接口的包名(这是批量包含的方法)

你可能感兴趣的:(#,mybatis)