resultMap元素是mybatis中最重要最强大的元素,它的作用是告诉mybatis将从结果集中取出的数据转换成开发者自定义的对象
一、简单查询
上篇博客说到,mybatis查询会将数据表中的字段名与java对象的属性名进行匹配,匹配成功就将结果集保存到对象中,那如果java对象中的属性名与数据库表的字段名不一致怎么办呢?可以用resultMap元素来解决
1、在数据库mybatis中新建user2表,表中的字段名都加了前缀user2_
create table user2(
-> user2_id int(11) not null primary key auto_increment,
-> user2_name char(11) not null,
-> user2_sex char(2),
-> user2_age int(3));
接下来插入几条测试数据
insert into user2 values(1,'aa','M',23);
insert into user2 values(2,'bb','F',21);
insert into user2 values(3,'cc','M',13);
insert into user2 values(4,'dd','F',18);
2、新建一个User.java对象
package pojo;
public class User {
private Integer id;
private String name;
private String sex;
private Integer age;
public User(){super();}
public User(String name,String sex,Integer age){
this.name = name;
this.sex = sex;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
3、修改映射文件UserMapper.xml,用resultMap元素指定User中属性名对应数据表中的字段名,如id对应user2_id。然后在查询元素select中增加一条属性resultMap指定刚才的resultMap的id,查询的时候直接查询user2表即可
<?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="pojo.UserMapper">
<resultMap type="pojo.User" id="user2Result">
<id property="id" column="user2_id"/>
<result property="name" column="user2_name"/>
<result property="sex" column="user2_sex"/>
<result property="age" column="user2_age"/>
</resultMap>
<select id="selectUser2" resultMap="user2Result">
SELECT * FROM USER2
</select>
</mapper>
4、编写测试类ResultMapTest.java
package test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import pojo.User;
public class ResultMapTest {
public static void main(String[] args) throws IOException{
//读取mybatis的配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取session
SqlSession session = new SqlSessionFactoryBuilder().build(is).openSession();
//查询全部,返回list集合
List<User> userlist = session.selectList("pojo.UserMapper.selectUser2");
for(User user:userlist){
System.out.println(user.getId()+"-"+user.getName()+"-"+user.getSex()+"-"+user.getAge());
}
//提交事务
session.commit();
//关闭session
session.close();
}
}
5、另外附上maybatis的配置文件mybatis-config.xml,位于src目录下即可
<?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>
<!-- 指定所有日志的具体实现 -->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 环境配置 -->
<environments default="mysql">
<environment id="mysql">
<!-- 指定事务管理类型 -->
<transactionManager type="JDBC" />
<!-- 配置数据源,POOLED是JDBC连接对象的数据源连接池的实现 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- mappers告诉mybatis找持久化类的映射文件 -->
<mappers>
<mapper resource="pojo/UserMapper.xml"/>
</mappers>
</configuration>
运行ResultMapTest.java类,可以看到输出
二、关联查询
在实际项目中我们需要用到多表查询,而不仅仅只是一个表。比如外键关联的两个表,查询其中一个时就需要把另一个也查询出来,这是就需要用resultMap来完成关联映射
1、首先创建两个表学生(student)和班级(clazz),一个学生对应一个班级,一个班级对应多个学生
create table clazz(
-> id int primary key auto_increment,
-> code char(12));
create table student(
-> id int primary key auto_increment,
-> name char(12),
-> age int,
-> clazz_id int,
-> foreign key(clazz_id) references clazz(id));
插入一些测试数据
insert into clazz values(1,'G18001');
insert into clazz values(2,'G18002');
insert into student values(1,'wang',20,1);
insert into student values(2,'li',19,1);
insert into student values(3,'song',20,2);
insert into student values(4,'zhang',18,2);
2、编写对象类,src/pojo/Student.java,src/pojo/Clazz.java
package pojo;
import java.util.List;
public class Clazz {
private int id;
private String code;
private List<Student> students;
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
package pojo;
public class Student {
private int id;
private String name;
private int age;
private Clazz clazz;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Clazz getClazz() {
return clazz;
}
public void setClazz(Clazz clazz) {
this.clazz = clazz;
}
}
3、编写映射文件ClazzMapper.xml和StudentMapper.xml,与java对象位于同一级目录pojo下。
ClazzMapper.xml:
<?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="pojo.ClazzMapper">
<resultMap type="pojo.Clazz" id="clazzMap">
<id property="id" column="id"/>
<result property="code" column="code"/>
<!-- 学生集合 -->
<collection property="students" javaType="ArrayList"
column="id" ofType="pojo.Student" select="selectStudent"/>
</resultMap>
<!-- 根据班级id查询学生 -->
<select id="selectStudent" resultType="pojo.Student">
SELECT*FROM STUDENT WHERE clazz_id=#{id}
</select>
<!-- 查询班级信息 -->
<select id="selectClazz" resultMap="clazzMap">
SELECT*FROM CLAZZ
</select>
</mapper>
StudentMapper.xml
<?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="pojo.StudentMapper">
<resultMap type="pojo.Student" id="studentMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<!-- 关系映射 -->
<association property="clazz" column="clazz_id" javaType="pojo.Clazz" select="selectClazz"/>
</resultMap>
<!-- 根据id查询班级 -->
<select id="selectClazz" resultType="pojo.Clazz">
SELECT*FROM CLAZZ WHERE id=#{id}
</select>
<!-- 查询所有学生信息 -->
<select id="selectStudent" resultMap="studentMap">
SELECT*FROM STUDENT
</select>
</mapper>
其中association和collection元素的属性详解如下:
property:对象类型的属性名,如Student.java中的clazz属性名
column:属性名在数据表中对应的字段名
javaType:该属性所对应的java类型,clazz对应是Clazz类类型,students对应的是集合类型
select:表示执行一条查询语句,其值对应下面的查询元素的id
ofType:表示集合ArrayList中的类型
4、在mybatis-config.xml配置文件中添加映射
<?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>
<!-- 指定所有日志的具体实现 -->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 环境配置 -->
<environments default="mysql">
<environment id="mysql">
<!-- 指定事务管理类型 -->
<transactionManager type="JDBC" />
<!-- 配置数据源,POOLED是JDBC连接对象的数据源连接池的实现 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- mappers告诉mybatis找持久化类的映射文件 -->
<mappers>
<mapper resource="pojo/UserMapper.xml"/>
<mapper resource="pojo/StudentMapper.xml"/>
<mapper resource="pojo/ClazzMapper.xml"/>
</mappers>
</configuration>
5、编写src/test/StudentTest.java测试类,测试查询学生的同时查询其对应的班级
package test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import pojo.Student;
public class StudentTest {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//读取映射文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取 session
SqlSession session = new SqlSessionFactoryBuilder().build(is).openSession();
//查询学生信息
List<Student> students = session.selectList("pojo.StudentMapper.selectStudent");
for(Student s:students){
System.out.println(s.getId()+"-"+s.getName()+"-"+s.getAge()+"-"+s.getClazz().getCode());
}
//提交事务
session.commit();
//关系session
session.close();
}
}
运行结果如下
6、编写src/test/ClazzTest.java测试类,测试查询班级的同时查询出班级内所有的学生信息
package test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import pojo.Clazz;
import pojo.Student;
public class ClazzTest {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//读取映射文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取 session
SqlSession session = new SqlSessionFactoryBuilder().build(is).openSession();
//查询班级信息
List<Clazz> clazzs = session.selectList("pojo.ClazzMapper.selectClazz");
for(Clazz clazz:clazzs){
System.out.println("班级:"+clazz.getCode());
//获取班级中的学生信息
List<Student> students = clazz.getStudents();
for(Student student:students){
System.out.println(student.getId()+"-"+student.getName()+"-"+student.getAge());
}
}
}
}
运行结果如下