mybatis多表关联查询

Posted zs-book1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis多表关联查询相关的知识,希望对你有一定的参考价值。

在以往的项目中,多表关联查询使用外键进行关联,在实体类中写的属性也是外键,在使用mybatis时,需要进行调整。需要用到的数据库如下:

技术图片
-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `did` int(11) NOT NULL AUTO_INCREMENT,
  `dname` varchar(50) NOT NULL,
  PRIMARY KEY (`did`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES (1, 人事部);
INSERT INTO `dept` VALUES (2, 销售部);

-- ----------------------------
-- Table structure for emp
-- ----------------------------
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (
  `eid` int(11) NOT NULL AUTO_INCREMENT,
  `ename` varchar(50) NOT NULL,
  `did` int(11) DEFAULT NULL,
  PRIMARY KEY (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of emp
-- ----------------------------
INSERT INTO `emp` VALUES (1, zhangsan, 1);
INSERT INTO `emp` VALUES (2, lisi, 1);
INSERT INTO `emp` VALUES (3, wanger, 2);

-- ----------------------------
-- Table structure for login
-- ----------------------------
DROP TABLE IF EXISTS `login`;
CREATE TABLE `login` (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of login
-- ----------------------------
INSERT INTO `login` VALUES (1, zhaoshuai, 123456);
INSERT INTO `login` VALUES (3, xiaoming, 456789);
View Code

新建员工与部门的实体类:

技术图片
package com.zs.entity;

public class Emp 
    private int eid;
    private String ename;
    private Dept dept;

    public Emp()  

    public Emp(int eid, String ename, Dept dept) 
        this.eid = eid;
        this.ename = ename;
        this.dept = dept;
    

    public int getEid() 
        return eid;
    

    public void setEid(int eid) 
        this.eid = eid;
    

    public String getEname() 
        return ename;
    

    public void setEname(String ename) 
        this.ename = ename;
    

    public Dept getDept() 
        return dept;
    

    public void setDept(Dept dept) 
        this.dept = dept;
    

    @Override
    public String toString() 
        return "Emp" +
                "eid=" + eid +
                ", ename=‘" + ename + ‘\\‘‘ +
                ", dept=" + dept +
                ‘‘;
    
View Code
技术图片
package com.zs.entity;

import java.util.List;

public class Dept 
    private int did;
    private String dname;
    private List<Emp> emps;

    public Dept() 
        
    

    public Dept(int did, String dname, List<Emp> emps) 
        this.did = did;
        this.dname = dname;
        this.emps = emps;
    

    public int getDid() 
        return did;
    

    public void setDid(int did) 
        this.did = did;
    

    public String getDname() 
        return dname;
    

    public void setDname(String dname) 
        this.dname = dname;
    

    public List<Emp> getEmps() 
        return emps;
    

    public void setEmps(List<Emp> emps) 
        this.emps = emps;
    

    @Override
    public String toString() 
        return "Dept" +
                "did=" + did +
                ", dname=‘" + dname + ‘\\‘‘ +
                ", emps=" + emps +
                ‘‘;
    
View Code

在上面的实体类中可以看到,员工属于部门,这是多对一的关系,在多的一方的实体中,创建一的对象,然后再一的一方,创建多的一方的list集合,这样就产生了关系。

在项目中创建dao层,进行数据库的操作,dao层如下:

技术图片
package com.zs.dao;

import com.zs.entity.Emp;

import java.util.List;

/**
 * 员工信息持久化层接口
 */
public interface EmpDao 
    /**
     * 查询所有员工
     */
    List<Emp> listemps();

    /**
     * 添加员工
     */
    int addEmp(Emp emp);

    /**
     * 修改员工信息
     */
    int updEmp(Emp emp);

    /**
     * 删除员工根据id
     */
    int delById(int id);
View Code
技术图片
package com.zs.dao;

import com.zs.entity.Dept;

import java.util.List;

/**
 * 部门信息持久化层
 */
public interface DeptDao 
    /**
     * 查询所有部门信息
     */
    List<Dept> listDept();
View Code

然后创建mybatis配置文件,以及mapper文件,并将mapper文件添加到mybatis配置文件中使用动态代理。代码如下:

技术图片
<?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>
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <!--配置mybatis连接数据库的连接池信息-->
            <dataSource type="POOLED">
                <!--配置数据库基本信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/zs_base?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--使用动态代理的方法-->
    <mappers>
        <mapper resource="mapper/login.xml"/>
        <mapper resource="mapper/emp.xml"/>
        <mapper resource="mapper/dept.xml"/>
    </mappers>
</configuration>
mybatis-config.xml
技术图片
<!DOCTYPE mapper PUBLIC "-//mybatis.org// Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zs.dao.EmpDao">
    <!--创建resultMap-->
    <resultMap id="emp" type="com.zs.entity.Emp">
        <id column="eid" property="eid"/>
        <result column="ename" property="ename"/>
        <!--配置多对一的关系,使用association在多的一方
        property值为在一的实体类中,多的一方的属性名称
        -->
        <association property="dept" javaType="com.zs.entity.Dept">
            <id column="did" property="did"/>
            <result column="dname" property="dname"/>
        </association>
    </resultMap>
    <!--查询所有员工信息-->
    <select id="listemps" resultMap="emp">
        select * from emp e inner join dept d on e.did=d.did;
    </select>
    <!--添加员工-->
    <insert id="addEmp" parameterType="com.zs.entity.Emp">
        insert into emp (ename,did) value(#ename,#did);
    </insert>
    <!--修改员工-->
    <update id="updEmp" parameterType="com.zs.entity.Emp">
        update emp set ename=#ename,did=#did where eid=#eid;
    </update>
    <!--删除员工-->
    <delete id="delById" parameterType="Integer">
        delete from emp where eid=#eid;
    </delete>
</mapper>
emp.xml
技术图片
<!DOCTYPE mapper PUBLIC "-//mybatis.org// Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zs.dao.DeptDao">
    <resultMap id="dept" type="com.zs.entity.Dept">
        <id column="did" property="did"/>
        <result column="dname" property="dname"/>
        <!--创建一对多的关系,使用collection来标记,prompty值为一的一方实体类内多的一方的属性名称
        (即dept实体类中,emp的属性名称)在多的一方使用oftype来设置对象类型,
        当列别名与列名一致时,可以使用autoMapping来简化,值为true表示,列别名与列名一致-->
        <collection property="emps" ofType="com.zs.entity.Emp" autoMapping="true" >
            <!--使用autoMapping与下面代码效果一样-->
            <!--<id column="eid" property="eid"/>-->
            <!--<result column="ename" property="ename"/>-->
        </collection>
    </resultMap>

    <select id="listDept" resultMap="dept">
        --当列名与列别名一致时(即column值与property值一样时,可以使用*,否则使用列别名column)
        select * from dept d inner join emp e on d.did=e.did;
    </select>
</mapper>
dept.xml

下面进行测试:

技术图片
import com.zs.dao.DeptDao;
import com.zs.dao.EmpDao;
import com.zs.entity.Dept;
import com.zs.entity.Emp;
import com.zs.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class empTest 
    @Test
    public void test1() 
        SqlSession session = SqlSessionUtil.getSession();
        EmpDao mapper = session.getMapper(EmpDao.class);
        List<Emp> list = mapper.listemps();
        for (Emp emp : list) 
            System.out.println(emp);
        
    
    @Test
    public void test2() 
        SqlSession session = SqlSessionUtil.getSession();
        DeptDao mapper = session.getMapper(DeptDao.class);
        List<Dept> depts = mapper.listDept();
        for (Dept dept : depts) 
            System.out.println(dept);
        
    

View Code

结果如图:

技术图片

技术图片

 

以上是关于mybatis多表关联查询的主要内容,如果未能解决你的问题,请参考以下文章

Java--Mybatis关联查询,多表同名字段导致SQL报错

MyBatis--多表关联查询

MyBatis笔记----多表关联查询

mybatis 关联(多表)查询

MyBatis关联查询,表字段相同,resultMap映射问题的解决办法

MyBatis学习总结——多表关联查询与动态SQL