MyBatis02

MyBatis查询结果封装

resultType结果类型

  • resultType属性介绍

    • resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。
  • resultType属性的使用

    • 基本类型
    • 实体类型

resultMap自定义结果类型

  • resultMap标签介绍

    • resultMap标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系,从而实现封装,在select标签中使用resultMap属性指定引用即可。
    • resultMap可以实现将查询结果映射为复杂类型的pojo,在查询结果映射对象中包括pojo和list实现一对一和一对多查询
  • resultMap标签使用

    <!--
        从新定义一种数据字段和表的映射关系
        resultMap:针对查询结果定义新的映射关系
        id:标签主键字段和类中主键属性
        result:普通字段和普通属性的对应关系
     -->
        <resultMap id="newUser" type="user">
            <id property="id" column="id"></id>
            <result property="uname" column="name"></result>
            <result property="gender" column="gender"></result>
            <result property="age" column="age"></result>
            <result property="birthday" column="birthday"></result>
        </resultMap>
    
        <sql id="columns">
            id,name,gender,age,birthday
        </sql>
    
    <!--  使用sql片段查询  -->
        <select id="showAllInfo" resultMap="newUser">
            <!--
                ResultSet rs
                ResultSetMetaData rm =  rs.getMetaData();
    
                Class clazz =  Class.forName("com.offcn.bean.User");
                Object obj = clazz.newInstences();
                只要我们能够获取查询字段名称,把字段名充当属性名称
                Field fileld = clazz.getField(name);
                fileld.set(value,obj);
             -->
            select <include refid="columns"></include> from user
        </select>
    

MyBatis自动返回主键值

返回主键值技术的业务应用场景

  • 对于自增主键在某些业务中保存一个对象后,需要使用到这个主键完成后续的业务逻辑
    比如:要保存订单后,还要保存订单项信息,订单项相信需要用到订单主键。
<!--    插入数据返回主键-->
<!--
 useGeneratedKeys:自动返回数据库生成主键值  true|false
 keyProperty:返回的主键值存放到保存对象的那个属性中
 keyColumn:表中的主键字段(可省略)
 -->
<!--    第一种方式-->
   <insert id="saveUser" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into user(id,name,gender,age,birthday) values (#{id},#{uname},#{gender},#{age},#{birthday})
    </insert>

<!--    第二种方式-->
    <insert id="saveUser">
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(<include refid="columns"></include>) values(#{id},#{uname},#{gender},#{age},#{birthday})
    </insert>

sql片段

sql配置文件中出现sql冗余

  • 在开发中,SQL的拼接很常见,有很多对拼接的sql具有重复性高的特点,有sql冗余,不仅不美观还导致映射文件配置臃肿,这时最好把重复的sql抽取出来,作为公用的sql片段,尤其在动态sql中应用中更加显著,提高可重用性。
  • sql配置文件中重复的书写一部分sql内容:
    抽离公共的部分,在需要的sql内容中调用我们的sql片段。

示例

<sql id="columns">
        id,name,gender,age,birthday
    </sql>

<!--  使用sql片段查询  -->
    <select id="showAllInfo" resultMap="newUser">
        select <include refid="columns"></include> from user
    </select>

动态sql语句

动态sql介绍

  • 动态sql概念

    • SQL 是动态拼接成的,根据传入的变量值进行逻辑操作并动态拼接,方便实现多条件下的数据库操作。在业务逻辑复杂,即简单 SQL 无法完成时,需要拼接时就要使用动态SQL.
  • 动态sql解决的问题

    • 动态sql主要解决根据条件判断附加条动态sql主要解决多条件变化查询,实现自动判断记录字段是否需要更新,根据条件判断附加条sql条件,实现批量添加数据、批量修改数据、批量修删除数据等,优化sql语句,提高执行效率。

where标签

  • where标签简介

    • where标签用于代替sql中的where关键字,可以根据条件判断是否附加where关键字。如果where标签中有条件成立就会附加where关键字,如果没有成立的条件就不会附加where关键字. 可以去掉离他最近一个无关的and 或or关键字.where标签的书写格式为添写附加条件
  • where标签使用

        <sql id="selectcolumn">
            select * from user
        </sql>
    <!--
        where:
            1、如果where标签包含成立内容,那么where标签被解析成where关键字拼接到sql中
            2、自动忽略成立条件最前面的关键字 and  or
    -->
    <!--
        if动态sql中判断标签  属性是test='boolean' 条件成立可以拼接if标签内包含的sql,否则不会拼接sql
                在判断的条件中可以使用 and  or 做多个条件组合判断,可以使用当前传入的参数类型的方法作为判断的
    -->
        <select id="getInfo" resultType="user">
            <include refid="selectcolumn"></include>
            <where>
                <if test="id!=null">
                    id=#{id}
                </if>
                <if test="name!=null and name.equals('admin')">
                    and name=#{name}
                </if>
            </where>
        </select>
    

if标签

  • if标签简介

    • if标签表示逻辑条件判断,如果条件成立就附加之间的sql语句,如果条件不成立就不附加之间的sql语句。书写格式为:sql语句
  • if标签使用

    <!--    sql片段-->
    <!--
        if动态sql中判断标签  属性是test='boolean' 条件成立可以拼接if标签内包含的sql,否则不会拼接sql
                在判断的条件中可以使用 and  or 做多个条件组合判断,可以使用当前传入的参数类型的方法作为判断的
    -->
        <sql id="allcolumns">
            <if test="name!=null">
                name = #{name},
            </if>
            <if test="gender!=null">
                gender=#{gender},
            </if>
            <if test="age!=null">
                age=#{age},
            </if>
            <if test="birthday!=null">
                birthday=#{birthday}
            </if>
        </sql>
    

set标签

  • set标签简介

    • set标签用于更新语句中,代替set关键字,可以有效对指定字段进行更新,提升sql的执行效率。,当set标签中有条件成立时就会附加set标签,set标签会去除无关的逗号。set标签中一般嵌套if标签进行使用其格式为


      name=#{name},


      age=#{age},

      ......
  • set标签使用

        <update id="updateInfo" parameterType="user">
            update user
           <!-- <set>
                <include refid="allcolumns"></include>
            </set>-->
           <trim prefix="set" suffixOverrides=",">
               <include refid="allcolumns"></include>
           </trim>
           <where>
                id=#{id}
           </where>
        </update>
    

trim标签

  • trim标签简介

    • trim标签为万能标签,可用于set或where等。prefix表示要附加的前缀关键字,suffix表示要附加的后缀关键字,prefixOverrides表示要忽略前置字符,suffixOverrides表示要忽略后置字符。
      格式:


      name=#{name}


      age=#{age}


      gender=#{gender}

  • trim标签使用

    <!--    trim标签-->
    <!--
        trim:拼接sql标签,对包含在标签内部的成立的内容进行sql拼接
        prefix  前缀 在包含的所有的sql的前面进行sql拼接
        suffix 后缀   在包含的所有的sql的后面进行sql拼接
        prefixOverrides 覆盖前缀  在包含所有的sql的最前面的东西如果需要处理那么就进行覆盖
        suffixOverrides 覆盖后缀  在包含的所有的sql最后面的东西如果需要处理那么就进行覆盖
    
    -->
        <select id="getInfo1" resultType="user">
            <trim prefix="select * from user where 1=1 and " prefixOverrides="and" suffix="and id=#{id}">
                <if test="name!=null">
                    and  name=#{name}
                </if>
                <if test="gender!=null">
                    or gender=#{gender}
                </if>
                <if test="age!=null">
                    and age=#{age}
                </if>
                <if test="birthday!=null">
                    and birthday=#{birthday}
                </if>
            </trim>
        </select>
    

choose标签

  • choose标签简介

    • choose标签作用条件判断来拼接指定的条件,它和if不太相同,choose似类于java中的switch语句用法,直要有条件成立,其它判断将得不到执行,如果所有条件都不成立则执行otherwise标签中的内容。
      格式:

        
          执行的代码;
        


          执行的代码;
        

        ......
        
         执行的代码;
        
        

  • choose标签使用

    <!--    choose when otherwise-->
        <select id="getInfo2" resultType="user">
            select *  from user
            <where>
                <choose>
                    <when test="name!=null">
                        name=#{name}
                    </when>
                    <when test="gender!=null">
                        gender=#{gender}
                    </when>
                    <otherwise>
                        1=1
                    </otherwise>
                </choose>
            </where>
        </select>
    
    

foreach标签

  • foreach标签简介

    • foreach标签表示循环,对sql中有重复的部分可以使用此循环来动态拼接sql语句。可以实现批量添加、批量删除、批量更新操作。foreach标签中有很多的属性,请参考下面的Foreach标签属性表。
    • 子主题 2
  • foreach标签使用

    属性名称 含义
    collection 指定你要使用的集合类型
    item 集合中每个元素。
    open 在起始时,需要附加字符串,只附加一次。
    close 在结束时,需要附加字符,只附加一次。
    separator 在每个循环结时需要附加的字符串。
    index 每个循环的索引值。
    <!--foreach    -->
    
    <!--
        foreach标签(循环遍历标签)
        collection:集合的变量名称  默认名称([arg0, collection, list])
        item:每次循环迭代的对象名称
        separator:循环的元素之间的分隔符
    -->
        <insert id="batchAdd">
            insert into user(id,name,gender,age,birthday) values
            <foreach collection="mylist" item="user" separator=",">
                (#{user.id},#{user.name},#{user.gender},#{user.age},#{user.birthday})
            </foreach>
        </insert>
    
    <!--     collection: 遍历集合的名称默认[param1],可以使用@Param("名称")
                  open: 遍历的集合所有内容放入到指定的域中,域的开始符号
                  close:遍历的集合所有内容放入到指定的域中,域的关闭符号-->
        <delete id="batchDelete">
            delete from user where id in
            <foreach collection="ids" item="id" separator="," open="(" close=")">
                #{id}
            </foreach>
        </delete>
    
        <update id="batchUpdate">
            <foreach collection="mylist" item="user" separator=";" >
                update user
                <trim prefix="set" suffixOverrides=",">
                    <if test="user.name!=null">
                        name = #{user.name},
                    </if>
                    <if test="user.gender!=null">
                        gender=#{user.gender},
                    </if>
                    <if test="user.age!=null">
                        age=#{user.age},
                    </if>
                    <if test="user.birthday!=null">
                      birthday=#{user.birthday},
                    </if>
                </trim>
                <where>
                    id= #{user.id}
                </where>
            </foreach>
        </update>
    

多表联合查询

多表联合查询概述

  • 在开发过程中单表查询不能满足项目需求分析功能,对于复杂业务来讲,关联的表有几张,甚至几十张并且表与表之间的关系相当复杂。为了能够实业复杂功能业务,就必须进行多表查询,在mybatis中提供了多表查询的结果时映射标签,可以实现表之间的一对一、一对多、多对一、多对多关系映射。

jdbc中
class User{
Car car;
set get
}
pubic User getOneUser(Integer uid){
//逻辑业务操作
User user = ..
Car car = ...
user.setCar(car);
return user;
}

selrvet
doGet(){
User user = getOneUser(uid);
}
前台页面:
user

MyBatis多表查询之一对一

  • 方式一:嵌套结果方式

    实体类

    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/14 22:01
            */
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Person {
        // p_id --- pId
        private Integer p_id;
        private String p_name;
        private IdCard idCard;
    }
    
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/14 22:01
     */
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import lombok.NoArgsConstructor;
    
    import java.util.Date;
    
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class IdCard {
        private Integer c_id;
        private String c_cardno;
        private Date c_uselife;
    }
    

    映射文件

    <?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.offcn.mapper.PersonMapper">
    <!--    嵌套结果的方式完成一对一-->
        <resultMap id="newPerson" type="Person">
            <id property="p_id" column="p_id"></id>
            <result property="p_name" column="p_name"></result>
    
    <!--       association: mybatis 一对一查询结果封装的标签 -->
            <association property="idCard">
                <id property="c_id" column="c_id"></id>
                <result property="c_cardno" column="c_cardno"></result>
                <result property="c_userlife" column="c_userlife"></result>
            </association>
        </resultMap>
        <select id="getOnePersonById" resultMap="newPerson">
                    select p.p_id,p.p_name,c.c_id,c.c_cardno,c.c_uselife  from  person p,idcard c where p.p_id=c.c_id  and p.p_id=#{id}
        </select>
    

    测试类

    package com.offcn.test;
    
    import com.offcn.bean.Person;
    import com.offcn.mapper.PersonMapper;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;
    
    import java.io.InputStream;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/14 22:07
     */
    public class MybatisTest {
        @Test
        public void test1()throws  Exception {
            /*
             * 1: 读取我们的主配置文件 mybatis-config.xml
             * 2: SqlSessionFactory  mybatis 提供工具类
             * 3:SqlSession  操作sql配置
             * 4:sqlsession调用我们sql语句及进行通信
             * */
            String path = "mybatis-config.xml";
            InputStream resourceAsStream = Resources.getResourceAsStream(path);
            //构建工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            //创建Sqlsession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
    		Person person = mapper.getOnePersonById(1);
            
            System.out.println(person.getP_name());
    
        }
    }
    
  • 方式二:嵌套查询方式

    IdCardMpper.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.offcn.mapper.IdCardMapper">
        <select id="getOneCardById" resultType="IdCard">
            select * from idcard where c_id=#{cid}
        </select>
    </mapper>
    

    PersonMapper.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.offcn.mapper.PersonMapper">
    <!--    嵌套查询方式完成一对一-->
        <resultMap id="newPerson1" type="Person">
            <id property="p_id" column="p_id"></id>
            <result property="p_name" column="p_name"></result>
    
            <!--
                 jdbc:
                 pubic  User  getOneUser(Integer uid){
                     //逻辑业务操作
                     User user = userDao.getUserByUid(uid);
                     Car car = carDao.getCarByUid(user.getUid());
                     user.setCar(car);
                     return user;
                 }
    
                 column="执行下一个查询的关联字段的名称"
                 select 我们调用的其他工作空间的下查询方法,这个方法需要使用关联字段值
              -->
            <association property="idCard" column="p_id"  select="com.offcn.mapper.IdCardMapper.getOneCardById"></association>
    
        </resultMap>
    
        <select id="getOnePersonById1" resultMap="newPerson1">
            select p.p_id,p.p_name from  person p where p.p_id=#{id}
        </select>
    
    </mapper>
    

    测试类

    package com.offcn.test;
    
    import com.offcn.bean.Person;
    import com.offcn.mapper.PersonMapper;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;
    
    import java.io.InputStream;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/14 22:07
     */
    public class MybatisTest {
        @Test
        public void test1()throws  Exception {
            /*
             * 1: 读取我们的主配置文件 mybatis-config.xml
             * 2: SqlSessionFactory  mybatis 提供工具类
             * 3:SqlSession  操作sql配置
             * 4:sqlsession调用我们sql语句及进行通信
             * */
            String path = "mybatis-config.xml";
            InputStream resourceAsStream = Resources.getResourceAsStream(path);
            //构建工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            //创建Sqlsession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
    		Person person = mapper.getOnePersonById1(1);
            
            System.out.println(person.getP_name());
    
        }
    }
    

MyBatis多表查询之一对多

  • 方式一:嵌套结果方式

    实体类

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/14 22:37
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Employee {
        private Integer id;
        private String name;
        private String gender;
        private Integer age;
    }
    
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.List;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/14 22:37
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Department {
        private Integer id;
        private String name;
        private List<Employee> emps;
    
    }
    
    

    接口类

    import com.offcn.bean.Department;
    import org.apache.ibatis.annotations.Param;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/14 22:38
     */
    public interface DepartmentMapper {
        public Department getDepartmentById(@Param("id") Integer id);
    
        public Department getDepartmentById1(@Param("id") Integer id);
    }
    
    

    映射文件

    <?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.offcn.mapper.DepartmentMapper">
    <resultMap id="BaseResultMap" type="Department">
        <id column="d_id" property="id"></id>
        <result column="d_name" property="name"></result>
    </resultMap>
    <!--    一对多-->
    <!--    方式一:嵌套结果的方式-->
        <resultMap id="DepartmentResultMap" type="Department" extends="BaseResultMap">
    <!--
    collection:获取当前对象关联查询多个附加对象
    property:当前类中声明的集合变量名称
    ofType:当前集合中对象类型(不加会出现空指针)
    -->
            <collection property="emps" ofType="Employee">
                <id column="e_id" property="id"></id>
                <result column="e_name" property="name"></result>
                <result column="e_gender" property="gender"></result>
                <result column="e_age" property="age"></result>
            </collection>
        </resultMap>
    
        <select id="getDepartmentById" resultMap="DepartmentResultMap">
            SELECT d.*,e.* FROM department d, employee e WHERE e.e_depart_id=d.d_id AND d.d_id=#{id}
        </select>
    </mapper>
    

    测试文件

    import com.offcn.bean.Department;
    import com.offcn.mapper.DepartmentMapper;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;
    
    import java.io.InputStream;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/9/14 22:44
     */
    public class MyBatisTest {
        @Test
        public void test1() throws  Exception {
            /*
             * 1: 读取我们的主配置文件 mybatis-config.xml
             * 2: SqlSessionFactory  mybatis 提供工具类
             * 3:SqlSession  操作sql配置
             * 4:sqlsession调用我们sql语句及进行通信
             * */
            String path = "mybatis-config.xml";
            InputStream resourceAsStream = Resources.getResourceAsStream(path);
            //构建工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            //创建Sqlsession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            DepartmentMapper mapper = sqlSession.getMapper(DepartmentMapper.class);
            Department department = mapper.getDepartmentById(1);
            System.out.println(department.getEmps());
    
        }
    }
    
  • 方式二:嵌套查询的方式

接口文件

import com.offcn.bean.Department;
import org.apache.ibatis.annotations.Param;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/14 22:38
 */
public interface DepartmentMapper {
    public Department getDepartmentById(@Param("id") Integer id);

    public Department getDepartmentById1(@Param("id") Integer id);
}



import com.offcn.bean.Employee;
        import org.apache.ibatis.annotations.Param;

        import java.util.List;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/14 22:37
 */
public interface EmployeeMapper {
    public List<Employee> getEmployeeByDepartId(@Param("id")Integer id);
}

映射文件

<?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.offcn.mapper.EmployeeMapper">
    <select id="getEmployeeByDepartId" resultType="Employee">
        <!--select * from employee where e_depart_id=#{id}-->
        select e_id id,e_name name,e_gender gender,e_age age from employee where e_depart_id=#{id}
    </select>
</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.offcn.mapper.DepartmentMapper">
<!--嵌套查询的方式-->
    <resultMap id="DepartmentResultMap1" type="Department" extends="BaseResultMap">
<!--        <id column="d_id" property="id"></id>-->
<!--        <result column="d_name" property="name"></result>-->
        <collection property="emps" ofType="Employee" column="d_id"
                    select="com.offcn.mapper.EmployeeMapper.getEmployeeByDepartId">
        </collection>
    </resultMap>

    <select id="getDepartmentById1" resultMap="DepartmentResultMap1">
            select * from department where d_id=#{id}
    </select>

</mapper>

pom配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.offcn</groupId>
    <artifactId>mybatis06</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
        </dependency>
    </dependencies>
</project>

MyBatis多表查询之一对多

  • 方式一:嵌套结果方式

创建数据模型department和employee

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/14 22:37
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {

private int id;
private String name;
public int getId() {
return id;
}

编写一对多的sql查询语句

SELECT d.*,e.* 
FROM 
department d, employee e 
WHERE
e.e_depart_id=d.d_id AND d.d_id=#{id}

Department类中加入List属性

private List<Employee> emps;
public List<Employee> getEmps() {
return emps;
}

public void setEmps(List<Employee> emps) {
this.emps = emps;
}

部门持久层DepartmentDao 接口中加入查询方法

import cn.offcn.entity.Department;

public interface DepartmentMapper {
public Department getDepartmentById(int id);
} 

部门持久层 DepartmentDao.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="cn.offcn.mapper.DepartmentDao">
<select id="getDepartmentById" resultMap="DepartemntResultMap2">
  SELECT d.*,e.* FROM department d, employee e WHERE
  e.e_depart_id=d.d_id AND d.d_id=#{id}
</select>
<resultMap id="DepartemntResultMap" type="Department">
 <id column="d_id" property="id"></id>
 <result column="d_name" property="name"></result>
 <collection property="emps" ofType="Employee">
      <id column="e_id" property="id"></id>
      <result column="e_name" property="name"></result>
      <result column="e_gender" property="gender"></result>
      <result column="e_age" property="age"></result>
 </collection>
</resultMap>
collection:当属性为集合时,使用collection标签进行映射。

测试方法

 @Test
 public void testGetDepartentById() throws  Exception{
     //获取SqlSession对象
     SqlSession session = MyBatisUtils.getSession();
     //调用SqlSession 创建 UserDao接口的代理对象
     DepartmentDao departmentDao = session.getMapper(DepartmentDao.class);
     Department dept=departmentDao.getDepartentById(1);
     //打印
     System.out.println(dept);
     //提交事务
     session.commit();
     //关闭连接
     MyBatisUtils.close(session);
 }
  • 方式二:嵌套查询方式

定义员工的持久层接口EmployeeDao

public interface EmployeeDao {
public List<Employee> getEmployeeByDepartId(int id);
}

定义 EmployeeDao.xml 文件中的查询配置信息

<select id="getEmployeeByDepartId" resultType="Employee">
 select e_id id,e_name name,e_gender gender,e_age age
 from employee where e_depart_id=#{id}
</select>

修改DepartmentDao.xml配置文件

<select id="getDepartmentById" resultMap="DepartemntResultMap">
 select * from department where d_id=#{id}
</select>
<resultMap id="DepartemntResultMap" type="Department">
  <id column="d_id" property="id"></id>
  <result column="d_name" property="name"></result>
  <collection property="emps" ofType="Employee" column="d_id"
           select="cn.offcn.mapper.EmployeeMapper.getEmployeeByDepartId">
  </collection>
</resultMap>

此处变为单表查询,使分表查询方式进行查询。

测试方法

@Test
public void testGetDepartentById() throws  Exception{
//获取SqlSession对象
SqlSession session = MyBatisUtils.getSession();
//调用SqlSession 创建 UserDao接口的代理对象
DepartmentDao departmentDao = session.getMapper(DepartmentDao.class);
Department dept=departmentDao.getDepartentById(1);
//打印
System.out.println(dept);
//提交事务
session.commit();
//关闭连接
MyBatisUtils.close(session);
}

MyBatis多表查询之一对多

创建数据库表:student(学生表),teacher(老师表)

CREATE TABLE student(
sid INT NOT NULL AUTO_INCREMENT,
sname VARCHAR(30),
PRIMARY KEY(sid)
);
CREATE TABLE teacher(
tid INT NOT NULL AUTO_INCREMENT,
tname VARCHAR(30),
PRIMARY KEY(tid)
);

CREATE TABLE student_teacher(
s_id INT NOT NULL,
t_id INT NOT NULL,
PRIMARY KEY(s_id,t_id),
FOREIGN KEY(s_id) REFERENCES student(sid),
FOREIGN KEY(t_id) REFERENCES teacher(tid)
);
INSERT INTO student(sname) VALUES('张三'),('李四');
INSERT INTO teacher (tname) VALUES('刘老师'),('李老师');
INSERT INTO student_teacher(s_id,t_id) 
VALUES(1,1),(1,2),(2,1)
  • 方式一:嵌套结果方式

创建数据模型:Student,Teacher,StudentTeacher

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author: ChengLong
 * @version: 11.0.2
 * @datetime: 2021/9/14 22:37
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

private int id;
private String name;
public int getId() {
  return id;
}

编写多对多的sql语句

SELECT s.*,ts.*,t.* 
FROM 
student s,student_teacher st,teacher t
WHERE 
s.sid=st.s_id AND st.t_id=t.tid AND s.sid=1

Student类中加入List属性

private List<StudentTeacher> studentTeacherList;
public List<StudentTeacher> getStudentTeacherList() {
  return studentTeacherList;
}
public void setStudentTeacherList(List<StudentTeacher> studentTeacherList) {
  this.studentTeacherList = studentTeacherList;
}

StudentTeacher中加入Teacher属性

private Teacher teacher;
public Student getStudent() {
  return student;
}
public void setStudent(Student student) {
  this.student = student;
}

学生持久层StudentDao接口中加入查询方法

import cn.offcn.entity.Student;
public interface StudentDao {
public Student getStudentById(int id);
}

学生持久层SudentDao.xml映射文件配置

<select id="getStudentById" resultMap="StudentResultMap">
  SELECT s.*,ts.*,t.* FROM student s,teacher_student ts,teacher t
  WHERE s.sid=ts.s_id AND ts.t_id=t.tid AND s.sid=#{id}
</select>
<resultMap id="StudentResultMap" type="Student">
   <id column="sid" property="id"></id>
   <result column="sname" property="name"/>
   <collection property="studentTeacherList" ofType="StudentTeacher">
        <result column="s_id" property="sid"></result>
        <result column="t_id" property="tid"></result>
        <association property="teacher" javaType="Teacher">
            <id column="tid" property="id"></id>
            <result column="tname" property="name"></result>
        </association>
   </collection>
</resultMap>

测试方法

@Test
public void testGetStudentById() throws  Exception{
//获取SqlSession对象
SqlSession session = MyBatisUtils.getSession();
//调用SqlSession 创建 StudentDao接口的代理对象
StudentDao studentDao = session.getMapper(StudentDao.class);
Student student= studentDao.getStudentById(1);
//打印
System.out.println(tudent);
//提交事务
session.commit();
//关闭连接
MyBatisUtils.close(session);
}
  • 方式二:嵌套查询方式

定义中间表的持久层接口StudentTeacherDao

public interface StudentTeacherDao {
 public List<StudentTeacher> getStudentTeacherBySid(int sid);
}

定义StudentTeacherDao.xml文件中的查询配置信息

<!DOCTYPE mapper
     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.offcn.dao.StudentTeacherDao">

 <select id="getStudentTeacherBySid" resultMap="StudentTeacherResultMap">
      select * from teacher_student where s_id=#{sid}
 </select>
 <resultMap id="StudentTeacherResultMap" type="StudentTeacher">
        <result column="s_id" property="sid"></result>
        <result column="t_id" property="tid"></result>
        <association property="teacher" javaType="Teacher"
          column="t_id" select="cn.offcn.dao.TeacherMapper.getTeacherByTid">              </association>
 </resultMap>
</mapper>

定义老师持久层的接口TeacherDao

public interface TeacherDao {

 public Teacher getTeacherByTid(int tid);
}

定义老师持久层TeacherDao.xml映射文件配置

<!DOCTYPE mapper
     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.offcn.dao.TeacherDao">
 <select id="getTeacherByTid" resultType="Teacher">
         select tid id,tname name from teacher where tid=#{tid}
 </select>
</mapper>

修改StudentDao持久层的方法

public interface StudentMapper {
 public Student getStudentById(int id);
}

修改StudentDao.xml的查询配置信息

<select id="getStudentById" resultMap="StudentResultMap">
       select * from student where sid=#{id}
 </select>
 <resultMap id="StudentResultMap" type="Student">
     <id column="sid" property="id"></id>
     <result column="sname" property="name"/>
     <collection property="studentTeacherList" ofType="StudentTeacher"
     column="sid"
     select="cn.offcn.mapper.StudentTeacherMapper.getStudentTeacherBySid">
     </collection>
 </resultMap>

测试方法

@Test
public void testGetStudentById() throws  Exception{
  //获取SqlSession对象
  SqlSession session = MyBatisUtils.getSession();
  //调用SqlSession 创建 StudentDao接口的代理对象
  StudentDao studentDao = session.getMapper(StudentDao.class);
  Student student= studentDao.getStudentById(1);
  //打印
  System.out.println(tudent);
  //提交事务
  session.commit();
  //关闭连接
  MyBatisUtils.close(session);
}
posted @ 2021-09-15 21:35  Lucky_龍  阅读(55)  评论(0)    收藏  举报