美文网首页
MyBatis级联查询

MyBatis级联查询

作者: Doooook | 来源:发表于2020-07-19 16:36 被阅读0次

    一对一级联

    首先我们看两个实体,国家城市

    import org.apache.ibatis.type.Alias;
    
    import java.util.Date;
    
    // 当使用包扫描的方式时,使用该注解修改默认(类名第一个字母小写)的别名,可以避免别名重复的情况,建议使用包名+类名
    // <package name="com.pengjs.kkb.mybatis.model"/>
    @Alias(value = "country")
    public class Country {
        private Integer id;
    
        private String country;
    
        private Byte status;
    
        private Date created;
    
        private Date modified;
    
        // getter and setter
    }
    
    @Alias(value = "city")
    public class City {
        private Integer id;
    
        private Integer countryId;
    
        private String city;
    
        private Byte status;
    
        private Date created;
    
        private Date modified;
    
        // getter and setter
    }
    

    一个城市对应一个国家,是一对一的关系,一对一关系查询使用association标签。
    现在我们要实现查询城市的同时也查询对应的国家,我们封装了这么一个类,CityPlus继承City,并且有一个属性Country:

    /**
     * @author: Doooook
     * @date: 2020-06-21 10:08
     */
    @EqualsAndHashCode(callSuper = true)
    @Data
    public class CityPlus extends City implements Serializable {
    
        private Country country;
    
    }
    

    一对一级联一步查询

    看看xml,使用association标签,property="country"需要跟CityPlus对象的country属性对应:

    CityMapper.xml

      <resultMap id="cityPlusResultMap" type="com.pengjs.kkb.mybatis.api.bean.CityPlus" extends="BaseResultMap">
        <association property="country" javaType="com.pengjs.kkb.mybatis.model.Country">
          <id column="country_id" property="id"/>
          <result column="country" property="country"/>
          <result column="country_status" property="status"/>
          <result column="country_created" property="created"/>
          <result column="country_modified" property="modified"/>
        </association>
      </resultMap>
    
      <select id="getCityCountry" resultMap="cityPlusResultMap" parameterType="java.lang.Integer">
        select A.id as id,
           A.city as city,
           A.country_id as country_id,
           A.status as status,
           A.created as created,
           A.modified as modified,
           B.id as country_id,
           B.country as country,
           B.status as country_status,
           B.created as country_created,
           B.modified as country_modified
        from city as A, country as B
        where A.country_id = B.id and A.id = #{id,jdbcType=INTEGER}
      </select>
    

    测试查询:


    image.png

    一对一级联分步查询(单个入参)

    看看xml,使用传参的方式,select配置的是CountryMapper的selectByPrimaryKey方法,入参column为country_id,需要与selectCityPlusByIdUnderStep方法的出参country_id一致:

    CityMapper.xml

      <resultMap id="cityPlusResultMapStep" type="com.pengjs.kkb.mybatis.api.bean.CityPlus" extends="BaseResultMap">
        <association property="country"
                     select="com.pengjs.kkb.mybatis.mapper.CountryMapper.selectByPrimaryKey"
                     column="country_id">
        </association>
      </resultMap>
    
      <select id="selectCityPlusByIdUnderStep" resultMap="cityPlusResultMapStep" parameterType="java.lang.Integer">
        select
            id,
            country_id,
            city,
            status,
            created,
            modified
        from city
            where id = #{id,jdbcType=INTEGER}
      </select>
    

    CountryMapper.xml

      <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
        select
        <include refid="Base_Column_List" />
        from country
        where id = #{id,jdbcType=INTEGER}
      </select>
    

    测试:


    image.png

    一对一级联分步查询(多个入参)

    看看xml:

    CityMapper.xml

      <!-- 级联查询传递多个参数 -->
      <resultMap id="cityPlusResultMapStepMultiParams" type="com.pengjs.kkb.mybatis.api.bean.CityPlus" extends="BaseResultMap">
        <association property="country"
                     select="com.pengjs.kkb.mybatis.mapper.CountryMapper.selectCountryByIdAndName"
                     column="{id=country_id,country=country}">
        </association>
      </resultMap>
    
      <select id="selectCityPlusByIdUnderStepMultiParams" parameterType="java.lang.Integer" resultMap="cityPlusResultMapStepMultiParams">
        select
            id,
            country_id,
            city,
            status,
            created,
            modified,
            "China" as country
        from city
            where id = #{id,jdbcType=INTEGER}
      </select>
    

    CountryMapper.xml

      <select id="selectCountryByIdAndName" resultMap="BaseResultMap">
        select * from country
            where id = #{id} and country=#{country}
      </select>
    

    测试:


    image.png

    一对多级联查询

    CountryPlus.java

    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.pengjs.kkb.mybatis.model.City;
    import com.pengjs.kkb.mybatis.model.Country;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    
    import java.io.Serializable;
    import java.util.List;
    
    /**
     * @author: Jason
     * @date: 2020-06-21 10:08
     */
    @EqualsAndHashCode(callSuper = true)
    @Data
    @JsonIgnoreProperties(value = {"handler"})
    public class CountryPlus extends Country implements Serializable {
    
        private List<City> cityList;
    
    }
    

    一对多单步查询(单个对象)

    看看CountrMapper.xml,一对多使用collection标签:

      <resultMap id="countryCityResultMap" type="com.pengjs.kkb.mybatis.api.bean.CountryPlus" extends="BaseResultMap">
        <collection property="cityList" ofType="com.pengjs.kkb.mybatis.model.City">
          <id column="city_id" property="id"/>
          <result column="city" property="city"/>
          <result column="country_id" property="countryId"/>
          <result column="city_status" property="status"/>
          <result column="city_created" property="created"/>
          <result column="city_modified" property="modified"/>
        </collection>
      </resultMap>
    
      <select id="getCountryCity" resultMap="countryCityResultMap" parameterType="java.lang.Integer">
        select
           A.id as id,
           A.country as country,
           A.status as status,
           A.created as created,
           A.modified as modified,
           B.id as city_id,
           B.city as city,
           B.country_id as country_id,
           B.status as city_status,
           B.created as city_created,
           B.modified as city_modified
        from country as A left join city as B on A.id = B.country_id
            where A.id = #{id,jdbcType=INTEGER}
      </select>
    

    测试:


    image.png

    一对多单步查询(多个对象)

    看看CountryMapper.xml

      <select id="getCountryCityList" resultMap="countryCityResultMap">
        select
           A.id as id,
           A.country as country,
           A.status as status,
           A.created as created,
           A.modified as modified,
           B.id as city_id,
           B.city as city,
           B.country_id as country_id,
           B.status as city_status,
           B.created as city_created,
           B.modified as city_modified
        from country as A left join city as B on A.id = B.country_id
      </select>
    
      <resultMap id="countryCityResultMap" type="com.pengjs.kkb.mybatis.api.bean.CountryPlus" extends="BaseResultMap">
        <collection property="cityList" ofType="com.pengjs.kkb.mybatis.model.City">
          <id column="city_id" property="id"/>
          <result column="city" property="city"/>
          <result column="country_id" property="countryId"/>
          <result column="city_status" property="status"/>
          <result column="city_created" property="created"/>
          <result column="city_modified" property="modified"/>
        </collection>
      </resultMap>
    

    测试:


    image.png

    一对多分步查询

    看看CountryMapper.xml:

      <select id="getCountryCityMultiSteps" resultMap="countryPlusResultMapStep" parameterType="java.lang.Integer">
        select
           A.id as id,
           A.country,
           A.status,
           A.created,
           A.modified
        from country A
            where A.id = #{id,jdbcType=INTEGER}
      </select>
    
      <resultMap id="countryPlusResultMapStep" type="com.pengjs.kkb.mybatis.api.bean.CountryPlus" extends="BaseResultMap">
        <!--- fetchType="lazy"使用懒加载 ->
        <collection property="cityList" fetchType="lazy"
                    select="com.pengjs.kkb.mybatis.mapper.CityMapper.selectCityByCountryId"
                    column="id">
        </collection>
      </resultMap>
    
    image.png

    复杂关联关系查询

    一对一、一对多混合查询

    StudentMapper.xml

      <resultMap id="StudentLectureResultMap" type="com.pengjs.kkb.mybatis.api.bean.StudentLectureScoreBean" extends="BaseResultMap">
        <!-- 使用传参的方式查询另一个SQL -->
        <!-- 一个学生对应一张学生卡 -->
        <association property="studentSelfCard" fetchType="eager" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentSelfCardMapper.findStudentSelfcardByStudentId"/>
    <!--    <association property="studentSelfCard" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentSelfCardMapper.findStudentSelfcardByStudentId"/>-->
          <!-- 一个学生对应多条课程记录,一个课程对应一个课程分数 -->
        <collection property="studentLectureBeanList" fetchType="lazy" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentLectureMapper.findStudentLectureByStudentId"/>
    <!--    <collection property="studentLectureBeanList" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentLectureMapper.findStudentLectureByStudentId"/>-->
      </resultMap>
      <select id="getStudentLecture" parameterType="int" resultMap="StudentLectureResultMap">
        select * from t_student where id = #{id}
      </select>
    

    鉴别器

    <resultMap id="StudentHealthResultMap" type="com.pengjs.kkb.mybatis.api.bean.StudentLectureScoreHealthBean" extends="BaseResultMap">
        <!-- 鉴别器,它是一种可以选择具体实现类(子类)的级联,根据性别返回 -->
        <discriminator javaType="int" column="sex">
          <case value="1" resultMap="maleStudentMap"/>
          <case value="2" resultMap="femaleStudentMap"/>
        </discriminator>
      </resultMap>
    
      <resultMap id="maleStudentMap" type="com.pengjs.kkb.mybatis.api.bean.MaleStudentBean" extends="BaseResultMap">
        <!-- 使用传参的方式查询另一个SQL -->
        <!-- 一个学生对应一张学生卡 -->
        <association property="studentSelfCard" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentSelfCardMapper.findStudentSelfcardByStudentId"/>
        <!-- 一个学生对应多条课程记录,一个课程对应一个课程分数 -->
        <collection property="studentLectureBeanList" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentLectureMapper.findStudentLectureByStudentId"/>
        <collection property="studentHealthMaleList" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentHealthMaleMapper.findStudentHealthMaleByStuId"/>
      </resultMap>
    
      <resultMap id="femaleStudentMap" type="com.pengjs.kkb.mybatis.api.bean.FemaleStudentBean" extends="BaseResultMap">
        <!-- 使用传参的方式查询另一个SQL -->
        <!-- 一个学生对应一张学生卡 -->
        <association property="studentSelfCard" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentSelfCardMapper.findStudentSelfcardByStudentId"/>
        <!-- 一个学生对应多条课程记录,一个课程对应一个课程分数 -->
        <collection property="studentLectureBeanList" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentLectureMapper.findStudentLectureByStudentId"/>
        <collection property="studentHealthFemaleList" column="id" select="com.pengjs.kkb.mybatis.mapper.StudentHealthFemaleMapper.findStudentHealthFemaleByStuId"/>
      </resultMap>
    
      <select id="getStudentHealth" parameterType="int" resultMap="StudentHealthResultMap">
        select * from t_student where id = #{id}
      </select>
    

    StudentLectureScoreHealthBean

    @EqualsAndHashCode(callSuper = true)
    @Data
    @JsonIgnoreProperties(value = { "handler" })
    public class StudentLectureScoreHealthBean extends Student implements Serializable {
    
        private static final long serialVersionUID = 152987146649893684L;
        private StudentSelfCard studentSelfCard;
        private List<StudentLectureBean> studentLectureBeanList;
    
    }
    

    MaleStudentBean

    /**
     * @author: Jason
     * @date: 2020-06-26 18:59
     */
    @Data
    public class MaleStudentBean extends StudentLectureScoreHealthBean implements Serializable {
    
        private StudentSelfCard studentSelfCard;
        private List<StudentLectureBean> studentLectureBeanList;
        private List<StudentHealthMale> studentHealthMaleList;
    
    }
    

    FemaleStudentBean

    @Data
    public class FemaleStudentBean extends StudentLectureScoreHealthBean implements Serializable {
    
        private StudentSelfCard studentSelfCard;
        private List<StudentLectureBean> studentLectureBeanList;
        private List<StudentHealthFemale> studentHealthFemaleList;
    
    }
    

    MyBatis懒加载

    StudentController.java

    import com.nrsc.mybatis.service.StudentService;
    import com.nrsc.mybatis.vo.StudentSelfcardBean;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    /**
     * @Author: Jason
     * @Description: Created by Jason in 14:43 2019/5/12
     * @Modified By:
     */
    @RequestMapping(value = "/student")
    @RestController
    public class StudentController {
    
        @Autowired
        private StudentService studentService;
    
        @GetMapping(value = "/findStudentCard/{id}", name = "根据学生ID查询学生及其学生卡信息")
        @ResponseBody
        public StudentSelfcardBean findStudentCardService(@PathVariable(value = "id") int id) {
            return studentService.findStudentCard(id);
        }
    
        /**
         * 只有查询结果是List结构的才会懒加载,如果是一对一的就一个对象结果就直接一次查询出来了
         * @return
         */
        @GetMapping(value = "/findStudentCardList", name = "根据学生ID查询学生及其学生卡信息List")
        @ResponseBody
        public List<StudentSelfcardBean> findStudentCardList() {
            return studentService.findStudentCardList();
        }
    
    }
    

    StudentServiceImplr.java

    import com.nrsc.mybatis.domian.StudentSelfCard;
    import com.nrsc.mybatis.mapper.StudentMapper;
    import com.nrsc.mybatis.service.StudentService;
    import com.nrsc.mybatis.vo.StudentSelfcardBean;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * @author: Jason
     * @date: 2020-06-27 09:32
     */
    @Service
    public class StudentServiceImpl implements StudentService {
    
        @Autowired
        private StudentMapper studentMapper;
    
        @Override
        public StudentSelfcardBean findStudentCard(int id) {
            StudentSelfcardBean studentCard = studentMapper.findStudentCard(id);
            StudentSelfCard studentSelfCard = studentCard.getStudentSelfCard();
            return studentCard;
        }
    
        @Override
        public List<StudentSelfcardBean> findStudentCardList() {
            List<StudentSelfcardBean> studentSelfcardBeanList = studentMapper.findStudentCardList();
            StudentSelfCard studentSelfCard = studentSelfcardBeanList.get(0).getStudentSelfCard();
            return studentSelfcardBeanList;
        }
    
    }
    

    StudentMapper.xml

      <resultMap id="StudentCardResultMap" type="com.nrsc.mybatis.vo.StudentSelfcardBean" extends="BaseResultMap">
        <!-- 可以直接extends="BaseResultMap" -->
        <!--<id column="id" property="id" jdbcType="INTEGER" />
        <result column="cnname" property="cnname" jdbcType="VARCHAR" />
        <result column="sex" property="sex" jdbcType="TINYINT" />
        <result column="selfcard_no" property="selfcardNo" jdbcType="INTEGER" />
        <result column="note" property="note" jdbcType="VARCHAR" />
        <result column="status" property="status" jdbcType="TINYINT" />
        <result column="created" property="created" jdbcType="TIMESTAMP" />
        <result column="modified" property="modified" jdbcType="TIMESTAMP" />-->
        <!-- 使用传参的方式查询另一个SQL -->
        <association property="studentSelfCard"
                     column="id"
                     fetchType="lazy"
                     javaType="com.nrsc.mybatis.domian.StudentSelfCard"
                     select="com.nrsc.mybatis.mapper.StudentSelfCardMapper.findStudentSelfcardByStudentId"/>
      </resultMap>
    
      <select id="findStudentCard" parameterType="int" resultMap="StudentCardResultMap">
        select * from t_student where id = #{id}
      </select>
    
      <select id="findStudentCardList" parameterType="int" resultMap="StudentCardResultMap">
        select * from t_student where status = 0
      </select>
    

    相关文章

      网友评论

          本文标题:MyBatis级联查询

          本文链接:https://www.haomeiwen.com/subject/ilxrkktx.html