需要用到的数据库数据:
--创建数据库mybatis2
create database mybatis2 charset=utf8;
use mybatis2;
--创建数据表users
create table emp(
e_no int(5) primary key auto_increment,
e_name varchar(20),
e_email varchar(50),
d_deptno int(5)
) charset=utf8;
--emp表的测试数据
insert into emp(e_name, e_email, d_deptno) values("张三", "zhangsan@qq.com", 1);
insert into emp(e_name, e_email, d_deptno) values("李四", "lisi@qq.com", 1);
insert into emp(e_name, e_email, d_deptno) values("王五", "wangwu@qq.com", 2);
insert into emp(e_name, e_email, d_deptno) values("马六", "maliu@qq.com", 2);
insert into emp(e_name, e_email, d_deptno) values("张三丰", "zhangsanfeng@qq.com", 3);
insert into emp(e_name, e_email, d_deptno) values("李四光", "lisiguang@qq.com", 3);
insert into emp(e_name, e_email, d_deptno) values("老王", "laowang@qq.com", 4);
insert into emp(e_name, e_email, d_deptno) values("赵六", "zhanliu@qq.com", 4);
create table dept(
d_deptno int(5) primary key auto_increment,
d_name varchar(20),
d_location varchar(10)
) charset=utf8;
--dept表的测试数据
insert into dept(d_name, d_location) values("开发部","一楼");
insert into dept(d_name, d_location) values("人事部","二楼");
insert into dept(d_name, d_location) values("运维中心","三楼");
insert into dept(d_name, d_location) values("账务部","四楼");
emp表中的d_deptno与dept表中的主键列进行关联。
在包com.qcc.entity下新建两个表对应的实体类:
emp表对应的实体类Emp(多方)
package com.qcc.entity;
public class Emp {
private int no;
private String name;
private String email;
private Dept dept;//在多方的实体类中将关联的字段修改为与之对应的实体对象属性,提供get/set方法。
// Getter 和 Setter 方法略
@Override
public String toString() {
return "Emp [no=" + no + ", name=" + name + ", email=" + email
+ ", dept=" + dept + "]";
}
dept表对应的实体类Dept(一方)
package com.qcc.entity;
import java.util.List;
public class Dept {
private int no;
private String name;
private String location;
private List<Emp> emps;//在一方的实体类中添加多方的对象的集合,提供get/set方法。
// Getter 和 Setter 方法略
@Override
public String toString() {
return "Dept [no=" + no + ", name=" + name + ", location=" + location + "]";
}
}
使用Mybatis进行数据库记录查询时,当表中的列名和类中的实体属性不一致时,需要对列名和实体属性进行映射:
常用的有两种方式:
1.对数据库中的每一列起个与实体属性一致的别名;
2.在实体类对应的mapper文件中,使用<resultMap>标签进行映射。
以查询dept信息为例:
在包com.qcc.mapping下新建deptMapper.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="com.qcc.mapping.deptMapper">
<!-- 将查询字段手动映射成实体类的属性,以便mybatis对查询结果集进行封装成对象。 -->
<select id="getAll" resultType="Dept">
select
d_deptno as no,
d_name as name,
d_location as location
from dept
</select>
<!--
使用<resultMap>标签将查询字段与实体类的属性进行映射,方便其它地方引用 。
表中主键字段使用<id />标签进行映射;
普通字段用<result />标签映射;
多方中关联一方对象的属性使用<association>标签映射;
一方中多方的集合属性用<collection>标签映射;
column指定表中的字段,property指定与字段相对应的类属性。
-->
<resultMap type="Dept" id="deptResultMap">
<id column="d_deptno" property="no"/>
<result column="d_name" property="name"/>
<result column="d_location" property="location"/>
</resultMap>
<select id="getAll2" resultMap="deptResultMap">
select * from dept
</select>
</mapper>
新建测试类TestDeptQuery.java
package com.qcc.test;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.qcc.entity.Dept;
import com.qcc.utils.MybatisUtils;
public class TestDeptQuery {
@Test
public void testGetAll1(){
SqlSession session = MybatisUtils.getSession(false);
List<Dept> deptList = session.selectList("com.qcc.mapping.deptMapper.getAll");
System.out.println("查询字段别名方式映射:");
for (Dept dept : deptList) {
System.out.println(dept);
}
}
@Test
public void testGetAll2(){
SqlSession session = MybatisUtils.getSession(false);
List<Dept> deptList = session.selectList("com.qcc.mapping.deptMapper.getAll2");
System.out.println("使用<resultMap>标签方式进行映射");
for (Dept dept : deptList) {
System.out.println(dept);
}
}
}
测试结果如下:
查询字段别名方式映射:
Dept [no=1, name=开发部, location=一楼]
Dept [no=2, name=人事部, location=二楼]
Dept [no=3, name=运维中心, location=三楼]
Dept [no=4, name=账务部, location=四楼]
使用<resultMap>标签方式进行映射
Dept [no=1, name=开发部, location=一楼]
Dept [no=2, name=人事部, location=二楼]
Dept [no=3, name=运维中心, location=三楼]
Dept [no=4, name=账务部, location=四楼]
以上两种方式都可以在表字段与类属性不一致的情况下,将查询出的结果集正确地映射并封装成与之对应的java对象。
当查询emp的信息时,想把与之对应的dept的信息一并查询出来,此时需要在Emp类中添加关联的对象属性private Dept dept
,同时在empMapper.xml文件中进行配置关联属性<association>
标签。
empMapper.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="com.qcc.mapping.empMapper">
<resultMap type="Emp" id="empResultMap">
<id column="e_no" property="no"/>
<result column="e_name" property="name"/>
<result column="e_email" property="email"/>
<!--
关联的对象需使用association标签进行配置,两种方式:
① property的值对应实体属性,使用javaType=“Dept”来指定实体属性对应的java类型,
然后在association标签体内逐个配置关联对象dept的属性与数据库表的映射信息,如下:
<association property="dept" javaType="Dept">
<id column="d_deptno" property="no"/>
<result column="d_name" property="name"/>
<result column="d_location" property="location"/>
</association>
-->
<!--
② property的值对应实体属性,resultMap对应结果集的类型,此处结果集的类型指定为:
com.qcc.mapping.deptMapper这个命名空间下id值为deptResultMap的类型。
-->
<association property="dept" resultMap="com.qcc.mapping.deptMapper.deptResultMap"></association>
</resultMap>
<sql id="columns">e_no, e_name, e_email, d_deptno, d_name, d_location</sql>
<select id="getAll" resultMap="empResultMap">
select * from emp e inner join dept d on e.d_deptno=d.d_deptno
</select>
</mapper>
关联映射测试代码:
@Test
public void test() {
SqlSession session = MybatisUtils.getSession(false);
List<Emp> empList = session.selectList("com.qcc.mapping.empMapper.getAll");
for (Emp emp : empList) {
System.out.println(emp);
}
}
测试结果:
Emp [no=1, name=张三, email=zhangsan@qq.com, dept=Dept [no=1, name=开发部, location=一楼]]
Emp [no=2, name=李四, email=lisi@qq.com, dept=Dept [no=1, name=开发部, location=一楼]]
Emp [no=3, name=王五, email=wangwu@qq.com, dept=Dept [no=2, name=人事部, location=二楼]]
Emp [no=4, name=马六, email=maliu@qq.com, dept=Dept [no=2, name=人事部, location=二楼]]
Emp [no=5, name=张三丰, email=zhangsanfeng@qq.com, dept=Dept [no=3, name=运维中心, location=三楼]]
Emp [no=6, name=李四光, email=lisiguang@qq.com, dept=Dept [no=3, name=运维中心, location=三楼]]
Emp [no=7, name=老王, email=laowang@qq.com, dept=Dept [no=4, name=账务部, location=四楼]]
Emp [no=8, name=赵六, email=zhanliu@qq.com, dept=Dept [no=4, name=账务部, location=四楼]]
查询emp信息的同时,dept的相关联的信息也被查询出来了。
查询dept信息的时候,把dept下对应的所有员工信息查询出来,此时需要在Dept类中添加Emp对象的集合属性List<Emp> emps
,同时在deptMapper.xml文件中进行配置关联属性标签。
<resultMap type="Dept" id="deptResultMap2">
<id column="d_deptno" property="no"/>
<result column="d_name" property="name"/>
<result column="d_location" property="location"/>
<!--
一方的集合属性要配置对应的collection标签,使用ofType属性来指定集合中的数据类型。
-->
<collection property="emps" ofType="Emp" resultMap="com.qcc.mapping.empMapper.empResultMap">
</collection>
</resultMap>
sql字符串的映射标签如下:
<select id="getAll3" resultMap="deptResultMap2">
select * from dept inner join emp on dept.d_deptno = emp.d_deptno
</select>
测试dept关联emp信息的代码:
@Test
public void testGetAll3(){
SqlSession session = MybatisUtils.getSession(false);
List<Dept> deptList = session.selectList("com.qcc.mapping.deptMapper.getAll3");
System.out.println("使用<resultMap>标签方式进行映射,查询关联的emp集合信息");
for (Dept dept : deptList) {
System.out.println(dept);
List<Emp> emps = dept.getEmps();
for (Emp emp : emps) {
System.out.println("\t---->" + emp);
}
}
}
测试结果:
使用<resultMap>标签方式进行映射,查询关联的emp集合信息
Dept [no=1, name=开发部, location=一楼]
---->Emp [no=1, name=张三, email=zhangsan@qq.com, dept=Dept [no=1, name=开发部, location=一楼]]
---->Emp [no=2, name=李四, email=lisi@qq.com, dept=Dept [no=1, name=开发部, location=一楼]]
Dept [no=2, name=人事部, location=二楼]
---->Emp [no=3, name=王五, email=wangwu@qq.com, dept=Dept [no=2, name=人事部, location=二楼]]
---->Emp [no=4, name=马六, email=maliu@qq.com, dept=Dept [no=2, name=人事部, location=二楼]]
Dept [no=3, name=运维中心, location=三楼]
---->Emp [no=5, name=张三丰, email=zhangsanfeng@qq.com, dept=Dept [no=3, name=运维中心, location=三楼]]
---->Emp [no=6, name=李四光, email=lisiguang@qq.com, dept=Dept [no=3, name=运维中心, location=三楼]]
Dept [no=4, name=账务部, location=四楼]
---->Emp [no=7, name=老王, email=laowang@qq.com, dept=Dept [no=4, name=账务部, location=四楼]]
---->Emp [no=8, name=赵六, email=zhanliu@qq.com, dept=Dept [no=4, name=账务部, location=四楼]]
关联信息已经查询出来。