创建实体类Dept和Emp
package com.yc.mybatis.bean;
import java.util.List;
public class Dept implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private Integer deptno;
private String dname;
private String loc;
private Integer deptleader;
private String depthabby;
private Emp leader;
private List<Emp> empList;
public Dept()
{}
public Dept(Integer deptno,String dname,String loc)//批量插入 因为默认的无参数构造方法不会显示出来,但是如果自定义有参数构造,并且还要保留无参数构造就需要把雾草构造也写出来
{
super();
this.deptno=deptno;
this.dname=dname;
this.loc=loc;
}
public List<Emp> getEmpList() {
return empList;
}
public void setEmpList(List<Emp> empList) {
this.empList = empList;
}
public Emp getLeader() {
return leader;
}
public void setLeader(Emp leader) {
this.leader = leader;
}
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Integer getDeptleader() {
return deptleader;
}
public void setDeptleader(Integer deptleader) {
this.deptleader = deptleader;
}
public String getDepthabby() {
return depthabby;
}
public void setDepthabby(String depthabby) {
this.depthabby = depthabby;
}
@Override
public String toString() {
return "Dept [deptno=" + deptno + ", dname=" + dname + ", loc=" + loc + ", deptleader=" + deptleader
+ ", depthabby=" + depthabby + "]";
}
}
package com.yc.mybatis.bean;
import java.sql.Date;
public class Emp implements java.io.Serializable{
private static final long serialVersionUID = 1L;//序列化 mybatis会缓存
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Double sal;
private Double comm;//float对应double
private Integer deptno;
private String sex;
private String hobby;
private Dept dept;
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Integer getMgr() {
return mgr;
}
public void setMgr(Integer mgr) {
this.mgr = mgr;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
public Double getComm() {
return comm;
}
public void setComm(Double comm) {
this.comm = comm;
}
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
@Override
public String toString() {
return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate
+ ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + ", sex=" + sex + ", hobby=" + hobby + "]";
}
}
resultMap自定义映射:
当字段名dept_leader和实体属性名deptleader不同时,映射调用该属性值会报null指针异常,需要用到自定义映射
<resultMap type="com.yc.mybatis.bean.Dept" id="rmDept">//此处id需要自定义用于引用
<!-- 设置主键列提高性能 -->
<id column="deptno" property="deptno"/>
<!-- result标签中的column是需要针对的字段,property是修改字段后的映射 设置以后以property为准取操作-->
<result column="dept_leader" property="deptleader"/>
<result column="dept_habby" property="depthabby"/>
</resultMap>
一对一查询(即关联查询)方式一:
<–使用join连接的sql方式一次查询,前提是不需要多次查询,只需要一次性查询–>
<resultMap type="com.yc.mybatis.bean.Dept" id="rmDept_1">
<id column="deptno" property="deptno"/>
<result column="dept_leader" property="deptleader"/>
<result column="dept_habby" property="depthabby"/>
<!--一对一关联,property是指定保存到javaType对象的leader属性中,column表示利用该键去查 javaType表示存的是该类型 autoMapping是自动设置嵌套查询属性的开关,不打开无法将查询到的数据存入属性中,select是指的是需要执行的查询方法-->
<association property="leader" column="dept_leader" javaType="com.yc.mybatis.bean.Emp" select="com.yc.mybatis.dao.EmpMapper.selectByNo" autoMapping="true">
</association>
</resultMap>
方拾二:延迟加载
<!-- 关联一对一查询:存在多次查询-->
<!-- 方式二存在的问题:1+n查询 延迟加载 惰性加载 不加延迟加载步入方式一 -->
<resultMap type="com.yc.mybatis.bean.Dept" id="rmDept_2">
<id column="deptno" property="deptno"/>
<result column="dept_leader" property="deptleader"/>
<result column="dept_habby" property="depthabby"/>
<--fetchType是延迟加载的开关-->
<association property="leader" column="dept_leader" javaType="com.yc.mybatis.bean.Emp" select="com.yc.mybatis.dao.EmpMapper.selectByNo" fetchType="lazy">
</association>
<!-- 一对多关联查询 column定义为被外键引用的列也就是当前表的主键 关联查到的是多个数据 调用此方法-->
<collection property="empList" column="deptno" javaType="com.yc.mybatis.bean.Emp" select="com.yc.mybatis.dao.EmpMapper.selectByDeptno" fetchType="lazy">
</collection>
</resultMap>
此处DpetMapper.xml的==selectAll()==代码
<select id="selectAll" resultMap="rmDept_2">
select * from dept
</select>
对应的EmpMapper.xml中==selectByDeptno()==代码是
<select id="selectByDeptno" resultType="com.yc.mybatis.bean.Emp">
select *from emp where deptno=#{deptno}
</select>
此处既然用到了empList 和== leader==属性,这两个属性存放的是多个数据集合和一个数据,需要将这两个属性放在没有外键的那个实体类中
什么才算是1+n查询,就是第一次一对多或者一对一查询后,在利用查到的结果继续取查它的具体列值 如:
@Test
public void testRelaSelect2()
{
DeptMapper deptmapper=session.getMapper(DeptMapper.class);
List<Dept> list=deptmapper.selectAll();
Dept dept=list.get(0);
Assert.assertEquals("NEW YORK",dept.getLoc());
Assert.assertEquals("KING", dept.getLeader().getEname());//此处就是查第二此查数据库的列值,系统会自动再次连接数据库
Assert.assertEquals(4, dept.getEmpList().size());//同理,并验证dept.getEmpList()属性集合中是否有值
dept=list.get(1);
Assert.assertEquals(true, dept.getEmpList().size());//同理并验证dept.getEmpList()属性集合中是否有值
System.out.println("kkk");
}
通过一对一、一对多的方法可以将关联查询得到的数据保存到对象或者对象集合里,在进行调用如;
Assert.assertEquals("KING", dept.getLeader().getEname());//会自动查询,此方法会继续进行数据库连接验证
Assert.assertEquals(4, dept.getEmpList().size());
dept=list.get(1);
Assert.assertEquals(true, dept.getEmpList().size());
Assert.assertEquals("PRESIDENT",dept.getLeader().getJob());这是一个1+n查询到的操作,这段代码的意思是利用dept对象里leader属性
值再去查一下库,与“PRESIDENT”进行对比
注:外键一定要设置在一对多多的那一方
还有就是一对一、一对多的映射方法,sql语句不能再用join的连接查询,要用简易的where查询
延迟加载的意思是 只有手动调用属性去查询才会查询 不使用lazy系统会就会一次性多次查询进行到底