MyBatis 中的优化配置

将配置信息放置在properties文件中

  在之前说明如何初步配置MyBatis文件时我们都是将数据库配置信息写在xml文件下或者是代码块中,这样做有一定的安全隐患。因此我们可以将配置信息单独地放置在properties文件中,然后在config.xml文件下引入properties文件,具体做法如下:

  • 在resources目录下新建config.properties文件。
  • 在config.properties文件中写入数据库的基本配置信息。
  • 在config.xml文件中引入配置信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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="config.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>
<mappers>
<!--resource指向mapper映射器配置文件-->
<mapper resource="userMapping.xml"/>
<mapper class="com.mapping.UserMapper"/>
</mappers>
</configuration>

定义别名

简化映射语句的引用

  之前我们在映射文件中引用实体类时,需要写入实体类的全名,即包名+类名。这样如果有比较多的语句的话相对来说会很麻烦。比如这个语句:

1
2
3
4
<!-- 查询语句 -->
<select id="selectUser" parameterType="int" resultType="com.domain.User">
SELECT * FROM user WHERE id = #{id}
</select>

这里resultType=“com.domain.User”写的是实体类的全名,每次都写这么长的话,会比较麻烦,为此我们希望能够简写成如下样式:

1
2
3
4
<!-- 查询语句 -->
<select id="selectUser" parameterType="int" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>

即不写实体类的包名。这样的话就为com.domain.User类定义一个别名为User,简化开发。要达到这种效果的话只要在config.xml文件的<configuration></configuration>标签下添加如下配置:

1
2
3
<typeAliases>
<package name="com.domain"/>
</typeAliases>

这样做的目的是将整个com.domain包下的实体类定义了默认别名,让它们在引用的时候不需要写包名。但如果我们需要为某个实体类单独配置的话,需要这么写:

1
2
3
<typeAliases>
<typeAlias type="com.domain.User" alias="_user"/>
</typeAliases>

这样就为com.domain.User类单独配置了一个别名_user。

解决实体类名与数据表字段名不一致的冲突

  很多情况下我们表中的字段名与我们定义的实体类名不一致,这样我们在使用映射语句的时候就会出现诸如无法查询到数据等错误。因此,我们首先创建一个新的数据表以供测试:

新建测试数据表

1
2
3
4
5
6
7
CREATE TABLE test_user(
user_id INT(10) PRIMARY key,
user_name VARCHAR(20),
user_age INT(10)
);
INSERT INTO test_user(user_id,user_name,user_age) VALUES (1,"Tom",20);
INSERT INTO test_user(user_id,user_name,user_age) VALUES (2,"Mike",20);

实体类与上文一致。

编写测试代码

  创建一个testMapper.xml文件,内容如下:

1
2
3
4
5
6
7
8
<?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="domain.userMapper">
<!--不进行任何修改-->
<select id="selectUser" parameterType="int" resultType="_user">
SELECT * FROM test_user WHERE user_id = #{id}
</select>
</mapper>

发现无法查询到任何内容,因为我们实体类的名字与字段名不一致。修改SQL语句,如下:

1
2
3
4
5
6
7
8
<?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="domain.userMapper">
<!--手动对应实体类与数据表-->
<select id="selectUser" parameterType="int" resultType="_user">
SELECT user_id id,user_name name,user_age age FROM test_user WHERE user_id = #{id}
</select>
</mapper>

这样可以查询到结果,因为我们手动将实体类的名字与字段名对应起来了。但是这样做在写多条SQL时依旧很麻烦,因此我们可以为结果添加别名。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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="domain.userMapper">
<select id="selectUser" parameterType="int" resultType="_user" resultMap="resultMap">
SELECT * FROM test_user WHERE user_id = #{id}
</select>
<resultMap id="resultMap" type="com.domain.User">
<!-- 用id属性来映射主键字段 -->
<id property="id" column="user_id"/>
<!-- 用result属性来映射非主键字段 -->
<result property="name" column="user_name"/>
<result property="age" column="user_age"/>
</resultMap>
</mapper>

这样就能查询到我们想要的结果了。如果是使用接口语句呢,可以使用相同的操作。首先创建接口文件,

1
2
3
4
5
6
7
8
9
package com.mapping;
import com.domain.User;
import org.apache.ibatis.annotations.Select;

public interface TestUserMapper {
//不进行任何修改
@Select(value = "SELECT * FROM test_user WHERE user_id = #{id} ")
User selectUser(int id);
}

同样无法查询到任何结果,在SQL语句中为结果添加别名,如下:

1
2
3
4
5
public interface TestUserMapper {
//手动对应实体类与数据表
@Select(value = "SELECT user_id id,user_name name,user_age age FROM test_user WHERE user_id = #{id} ")
User selectUser(int id);
}

这样也可以查询到结果,因为我们手动将实体类的名字与字段名对应起来了。同样可以使用@Result修饰返回的结果集,关联实体类属性和数据库字段一一对应,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.mapping;
import com.domain.User;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

public interface TestUserMapper {
@Select(value = "SELECT * FROM test_user WHERE user_id = #{id} ")
@Results({
@Result(property = "id",column = "user_id"),
@Result(property = "name",column = "user_name"),
@Result(property = "age",column = "user_age")
})
User selectUser(int id);
}

使用添加注解的方式为结果集添加别名,这样也能查询到我们想要的结果。

总结

  使用优化配置后,对我们提升开发速度是有一定帮助的,但这些配置并没有全部介绍完,感兴趣的可以去阅读官方介绍