MyBatis-配置详解

36次阅读

共计 6649 个字符,预计需要花费 17 分钟才能阅读完成。

MyBatis 的全局配置文件

SqlMapConfig.xml 是 mybatis 的全局配置文件:

properties(属性)

settings(全局配置参数)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)

properties

将数据库连接参数单独配置在 db.properties 中,放在类路径下。这样只需要在 SqlMapConfig.xml 中加载 db.properties 的属性值。这样在 SqlMapConfig.xml 中就不需要对数据库连接参数硬编码。

将数据库连接参数只配置在 db.properties 中,原因:方便对参数进行统一管理,其它 xml 可以引用该 db.properties。

使用示例:

db.properties

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/mybatis

jdbc.username=root

jdbc.password=root

相应的 SqlMapConfig.xml

<properties resource=”db.properties”/>

<environments default=”development”>

<environment id=”development”>

<transactionManager type=”JDBC”/>

<dataSource type=”POOLED”>

<property name=”driver” value=”${jdbc.driver}”/>

<property name=”url” value=”${jdbc.url}”/>

<property name=”username” value=”${jdbc.username}”/>

<property name=”password” value=”${jdbc.password}”/>

</dataSource>

</environment>

</environments>

</properties>

注意:MyBatis 将按照下面的顺序来加载属性:

首先在 properties 标签中指定的属性文件首先被读取。

然后会读取 properties 元素中 resource 或 url 加载的属性,它会覆盖已读取的同名属性。

最后读取 parameterType 传递的属性,它会覆盖已读取的同名属性。

常用做法:

不要在 properties 元素体内添加任何属性值,只将属性值定义在外部 properties 文件中。

在 properties 文件中定义属性名要有一定的特殊性,如:xxx.xxx.xxx 的形式,就像 jdbc.driver。这样可以防止和 parameterType 传递的属性名冲突,从而被覆盖掉。

settings

mybatis 全局配置参数,全局参数将会影响 mybatis 的运行行为。比如:开启二级缓存、开启延迟加载。具体可配置情况如下:

配置示例:

<settings>

<setting name=”cacheEnabled” value=”true”/>

<setting name=”lazyLoadingEnabled” value=”true”/>

<setting name=”multipleResultSetsEnabled” value=”true”/>

</settings>

typeAliases

typeAliases 可以用来自定义别名。在 mapper.xml 中,定义很多的 statement,而 statement 需要 parameterType 指定输入参数的类型、需要 resultType 指定输出结果的映射类型。如果在指定类型时输入类型全路径,不方便进行开发,可以针对 parameterType 或 resultType 指定的类型定义一些别名,在 mapper.xml 中通过别名定义,方便开发。

例如:

<typeAliases>

<!– 单个别名定义 –>

<typeAlias alias=”user” type=”com.test.model.User”/>

<!– 批量别名定义,扫描整个包下的类,别名为类名(首字母大小写都可以)–>

<package name=”com.test.model”/>

<package name=” 其它包 ”/>

</typeAliases>

mapper.xml 的引用形式

<select id=”findUserById” parameterType=”int” resultType=”user”>

SELECT * FROM USER WHERE id=#{value}

</select>

typeHandlers

mybatis 中通过 typeHandlers 完成 jdbc 类型和 java 类型的转换。通常情况下,mybatis 提供的类型处理器满足日常需要,不需要自定义。

environments

MyBatis 可以配置多种环境,将 SQL 映射应用于多种数据库之中。一个很重要的问题:可以配置多种环境,但每个数据库对应一个 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=”development”>

<environment id=”development”>

<!– 使用 jdbc 事务管理,事务控制由 mybatis–>

<transactionManager type=”JDBC” />

<!– 数据库连接池,由 mybatis 管理 –>

<dataSource type=”POOLED”>

<property name=”driver” value=”${jdbc.driver}” />

<property name=”url” value=”${jdbc.url}” />

<property name=”username” value=”${jdbc.username}” />

<property name=”password” value=”${jdbc.password}” />

</dataSource>

</environment>

</environments>

注意:

默认的环境 ID(比如:default=”development”)。

每个 environment 元素定义的环境 ID(比如:id=”development”)。

事务管理器的配置(比如:type=”JDBC”)。

默认的环境和环境 ID 是自我解释的。可以使用喜欢的名称来命名,只要确定默认的要匹配其中之一。

mappers

Mapper 配置的几种方法:

第一种(常用)

<mapper resource=””/>

resource 指向的是相对于类路径下的目录

如:<mapper resource=”sqlmap/User.xml” />

第二种

<mapper url=””/>

使用完全限定路径

如:<mapper url=”file:///D:\workspace\mybatis\config\sqlmap\User.xml” />

第三种

<mapper class=””/>

使用 mapper 接口类路径

如:<mapper class=”com.test.mapper.UserMapper”/>

注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。

第四种(推荐)

<package name=””/>

注册指定包下的所有 mapper 接口

如:<package name=”com.test.mapper”/>

注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。

使用示例:

<mappers>

<mapper resource=”sqlmap/User.xml”/>

<package name=”com.test.mapper”/>

</mappers>

POJO 的映射文件

Mapper.xml 映射文件中定义了操作数据库的 sql,每个 sql 是一个 statement,映射文件是 mybatis 的核心。

parameterType(输入类型)

通过 parameterType 指定输入参数的类型,类型可以是简单类型、hashmap、pojo 的包装类型。

#{} 实现的是向 prepareStatement 中的预处理语句中设置参数值,sql 语句中 #{} 表示一个占位符即?。

例如:

<select id=”findUserById” parameterType=”int” resultType=”user”>

select * from user where id = #{id}

</select>

使用占位符 #{} 可以有效防止 sql 注入,在使用时不需要关心参数值的类型,mybatis 会自动进行 java 类型和 jdbc 类型的转换。#{} 可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,#{} 括号中可以是 value 或其它名称。

${} 和 #{} 不同,通过 ${} 可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换,${} 可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${} 括号中只能是 value。使用 ${} 不能防止 sql 注入,但是有时用 ${} 会非常方便,如下的例子:

<select id=”selectUserByName” parameterType=”string” resultType=”user”>

select * from user where username like ‘%${value}%’

</select>

使用 #{} 则传入的字符串中必须有 % 号,而 % 是人为拼接在参数中,显然有点麻烦,如果采用 ${} 在 sql 中拼接为 % 的方式则在调用 mapper 接口传递参数就方便很多。

如果使用 ${} 原始符号则必须人为在传参数中加 %。

List<User> list = userMapper.selectUserByName(“% 管理员 %”);

如果使用 %${value}% 则不用人为在参数中加 %。

List<User>list = userMapper.selectUserByName(“ 管理员 ”);

parameterType 也可以传递 pojo 对象。Mybatis 使用 ognl 表达式解析对象字段的值,如下例子:

<!—传递 pojo 对象综合查询用户信息 –>

<select id=”findUserByUser” parameterType=”user” resultType=”user”> select * from user where id=#{id} and username like ‘%${username}%’

</select>

上边 %${username}% 中的 username 就是 user 对象中对应的属性名称。

parameterType 还可以传递 pojo 包装对象(也就是将多个对象包装为一个对象)。开发中通过 pojo 传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

例如下面的包装对象:

public class QueryVo {

private User user;

private UserCustom userCustom;

}

在映射文件中的使用

<select id=”findUserByUser” parameterType=”queryVo” resultType=”user”>

select * from user where id=#{user.id} and username like ‘%${user.username}%’

</select>

可以看出通过使用类似 java 中对象访问属性的形式来进行参数传递。

parameterType 也可以传递 hashmap 类型的参数

在 xml 映射文件中使用形式如下:

<select id=”findUserByHashmap” parameterType=”hashmap” resultType=”user”>

select * from user where id=#{id} and username like ‘%${username}%’

</select>

在代码中的调用形式如下:

Public void findUserByHashmap() throws Exception {

// 获取 session

SqlSession session = sqlSessionFactory.openSession();

// 获限 mapper 接口实例

UserMapper userMapper = session.getMapper(UserMapper.class);

// 构造查询条件 Hashmap 对象

HashMap<String, Object> map = new HashMap<String, Object>();

map.put(“id”, 1);

map.put(“username”, “ 管理员 ”);

// 传递 Hashmap 对象查询用户列表

List<User>list = userMapper.findUserByHashmap(map);

// 关闭 session

session.close();

}

这样,可以把参数以 key-value 的形式传给 Mybatis。如果传递的 map 中的 key 和 xml 映射文件的 sql 语句中解析的 key 不一致,系统不会报错,但是通过 key 获取值为空。

resultType

使用 resultType 可以进行输出映射,只有查询出来的列名和 pojo 中的属性名一致,才可以映射成功。如果查询出来的列名和 pojo 中的属性名全部不一致,就不会创建 pojo 对象。但是只要查询出来的列名和 pojo 中的属性有一个一致,就会创建 pojo 对象。

resultType 可以输出简单类型。例如查询用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。

<select id=”findUserCount” parameterType=”user” resultType=”int”>

select count(*) from user

</select>

resultType 可以输出 pojo 对象和 pojo 列表。当使用动态代理时,输出 pojo 对象和输出 pojo 列表在 xml 映射文件中定义的 resultType 是一样的,而生成的动态代理对象中是根据 mapper 方法的返回值类型确定是调用 selectOne(返回单个对象调用) 还是 selectList(返回集合对象调用)。

resultMap

mybatis 中可以使用 resultMap 完成高级输出结果映射。如果查询出来的列名和定义的 pojo 属性名不一致,就可以通过定义一个 resultMap 对列名和 pojo 属性名之间作一个映射关系。然后使用 resultMap 作为 statement 的输出映射类型。resultMap 可以实现将查询结果映射为复杂类型的 pojo,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。

正文完
 0