使用mybatis访问数据库,将数据库表与pojo对象映射的方式有两种:Auto Mapping特性自动映射和resultMap标签手动映射。
Auto Mapping特性
当数据库表列名与实体类的属性名一致时可以使用自动映射。
例如,数据库表结构为:
实体类设计为:
Sql映射文件:
<?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.test.mapper">
<select id="selectAll" resultType="com.test.pojo.People">
select * from people
</select>
</mapper>
因为数据库表列名和实体类属性名相同,只需要resultType指定返回值类型,不需要配置resultMap属性即可实现自动映射。
测试sql语句执行:
public class Test {
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
List<People> selectList = session.selectList("com.test.mapper.selectAll");
session.commit();
for (People people : selectList) {
System.out.println(people);
}
}
}
从结果可以看到,正确的执行了查询全部的sql语句,并且实体类的每一个属性值都成功映射到了。
下面我们修改一下实体类的name属性名,使之与数据库表的列名不同:
我们再看一下执行结果:
从结果看到,此时它依然能够正确的执行,并正确映射,与我们之前的前提“数据库表列名与实体类属性名相同”不相符。
在实体类中,除了属性声明外,我们还定义了属性的getter个setter方法,所以很有可能此时是通过setter方法进行的自动映射,为了验证,再把setName方法名改为setName1测试一下:
Sql语句能正常执行,但是查询结果中实体类对象的name属性值变成了null,说明此时name属性没有正确的映射。那么mybatis是通过实体类的属性名还是setter方法来进行自动映射的呢?
我们再将第一次执行的实体类的所有属性的setter方法删掉,测试一下是否能自动映射:
依然可以正确的执行自动映射,我们在此基础上修改name属性名:
从上结果可以看到,此时属性name就不能成功自动映射。
再试一下属性名可映射,setter方法无法映射的情况:
此时也可以进行映射。
那么我们就可以得出结论:
1、通过属性名映射和通过setter方法映射的方式是互补的。
2、当实体类中有setter方法(属性名无法映射)时,mybatis自动映射机制是通过setter方法执行的,setter方法名称正确(set+列名)即可正确映射;
3、当实体类中没有setter方法(setter方法无法映射)时,mybatis自动映射机制是通过属性名进行的,当属性名与列名相同即可完成映射。
4、mybatis自动映射不区分大小写;
5、可以在sql语句中给列名设置别名与实体类进行映射;
<select id="selectAll" resultType="com.test.pojo.People">
select id, name as name1, age from people
</select>
6、映射是通过反射技术实现的。
resultMap标签单表映射
除了使用mybatis的Auto Mapping特性自动映射外,还可以使用resultMap标签进行手动映射。
<?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.test.mapper">
<resultMap type="com.test.pojo.People" id="peoMap">
<id column="id" property="id"/>
<result column="name" property="name1"/>
<result column="age" property="age"/>
</resultMap>
<select id="selectAll" resultMap="peoMap">
select * from people
</select>
</mapper>
手动映射需要编写resultMap标签,select中需要使用resultMap属性声明使用到的resultMap标签的id属性,同时不再需要配置resultType属性。
resultMap标签中需要配置resultType属性声明映射的实体类,使用id属性标识此resultMap标签。同时映射的数据库表中主键字段需要使用id标签配置映射,其他字段使用result标签配置映射。
上述mapper文件映射的实体类如下:
从下面的执行结果看,可以正确的映射:
也可以两种映射方法混合使用,如下:
<?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.test.mapper">
<resultMap type="com.test.pojo.People" id="peoMap">
<result column="name" property="name1"/>
</resultMap>
<select