MyBatis一对一级联查询

Posted nuist__NJUPT

tags:

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

MyBatis一对一级联查询

级联关系是数据库实体的概念,有3种级联关系,分别为1对1级联,1对多级联,多对多级联。
级联的优点:关联数据十分方便。
缺点:级联过多会增加数据库系统的复杂度,同时降低系统性能。
如果表A引用了表B的主键,A表就是主表,B表就是父表,当查询表A数据时,通过A的外键将B的相关记录返回,这就是级联查询。例如,当查询一个人的个人信息,可以通过身份证号返回他的身份信息。

一对一级联查询
通过resultMap的字元素association处理一一对应关系,association包含四个常用属性。
(1)property:指定映射到实体类的对象属性。
(2)column:指定表中对应字段。
(3)javaType:指定映射到实体类对象的属性类型。
(4)select:指定引入嵌套查询的ziSQL语句,该属性用于关联映射中的嵌套查询。

下面演示个人信息与身份证之间的一对一级联查询的处理过程
1-在mysql中创建名为spring的数据库,在该数据库中创建身份证表idcard和个人信息表person,这两张表具有一对一的级联关系。

身份证表idcard的设计


个人信息表的设计


2-在IDEA创建创建web应用Mappers,并导入相关jar包到web目录下的WEB-INF文件夹下,将所有jar包添加为库项目。
jar包如下:

将jar包添加为库项目:
3-在src目录下创建包com.po,在该包下,创建身份证表idcard的持久化类Idcard,创建个人信息表person的持久化类Person

Idcard类

public class IdCard {
    //Spring数据库idcard表的持久化类
    private Integer id ;
    private String code ;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
    @Override
    public String toString(){
        return "IdCard [id = " + id + " code = " + code + "]" ;
    }
}

Person类:

public class Person {
    //spring数据库中person表的持久化类
    private Integer id ;
    private String name ;
    private Integer age ;
    //个人身份证关联
    private IdCard card ;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public IdCard getCard() {
        return card;
    }

    public void setCard(IdCard card) {
        this.card = card;
    }
    public String toString(){
        return "Person [id = " + id + " name = " + name + " age = " + age + " card = " + card + "]" ;
    }
}

4-在src目录下创建包com.mybatis,在该包中创建两张表的映射文件IdCardMapper.xml和PersonMapper.xml。
IdCardMapper.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.dao.IdCardDao">
    <select id = "selectCodeById" parameterType = "Integer" resultType = "com.po.IdCard">
        select * from idcard where id = #{id}
    </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.dao.PersonDao">
    <!--一对一,根据id查询个人信息,级联查询的第一种方法,嵌套查询,执行两个SQL方法-->
    <resultMap type = "com.po.Person" id = "cardAndPerson1">
        <id property = "id" column = "id"/>
        <result property = "name" column = "name"/>
        <result property = "age" column = "age"/>
        <!--一对一级联查询-->
        <association property = "card" column = "idcard_id" javaType="com.po.IdCard"
        select = "com.dao.IdCardDao.selectCodeById"/>
    </resultMap>
    <select id = "selectPersonById1" parameterType="Integer" resultMap="cardAndPerson1">
        select * from person where id = #{id}
    </select>
    <!--一对一:根据id查询个人信息,级联查询第二种方法,嵌套结果,执行一个SQL语句-->
    <resultMap type = "com.po.Person" id = "cardAndPerson2">
        <id property = "id" column = "id"/>
        <result property = "name" column = "name"/>
        <result property = "age" column = "age"/>
        <!--一对一级联查询-->
        <association property = "card" javaType = "com.po.IdCard">
            <id property = "id" column = "id"/>
            <result property = "code" column = "code"/>
        </association>
    </resultMap>
    <select id = "selectPersonById2" parameterType = "Integer" resultMap = "cardAndPerson2">
        select p.*, ic.code
        from person p, idcard ic
        where p.idcard_id = ic.id and p.id = #{id}
    </select>
    <!--一对一:根据id查询个人信息,连接查询,根据POJO存储结果-->
    <select id = "selectPersonById3" parameterType = "Integer" resultType = "com.pojo.SelectPersonById">
           select p.*, ic.code
        from person p, idcard ic
        where p.idcard_id = ic.id and p.id = #{uid}
    </select>
</mapper>

5-在包com.mybatis中创建MyBatis核心配置文件mybatis-config.xml。在该文件中需要配置mappers。告诉MyBatis去哪里加载SQL映射文件。

<?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>
    <!--在使用MyBatis嵌套查询方式进行关联查询时,使用MyBatis延时加载可以在一定程度上提高查询效率-->
    <settings>
        <!--打开延时加载开关-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--将积极加载改成按需加载-->
        <setting name = "aggressiveLazyLoading" value = "false"/>
    </settings>
    <!--告诉MyBatis映射文件的位置-->
    <mappers>
        <mapper resource = "com/mybatis/UserMapper.xml"/>
        <mapper resource = "com/mybatis/IdCardMapper.xml"/>
        <mapper resource = "com/mybatis/PersonMapper.xml"/>
    </mappers>
</configuration>

6-创建POJO类,第三种查询方式是使用POJO类存储结果,采用前2种级联查询方式则不需要创建该类。即在src目录下创建包com.pojo,在该包下创建POJO类为SelectPersonById.


public class SelectPersonById {
    private Integer id ;
    private String name ;
    private Integer age ;
    private String code ;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
    @Override
    public String toString(){
        return "Person [id = " + id + " name = " + name + " age = " + age + " code = " + code + "]" ;
    }
}

7-在src目录下创建包com.dao,在该包中创建映射文件的数据操作接口IdCardDao和PersonDao

IdCardDao接口:


import com.po.IdCard;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Repository
@Mapper
public interface IdCardDao {
    public IdCard selectCodeById(Integer i) ;
}

PersonDao接口:

import com.po.Person;
import com.pojo.SelectPersonById;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Repository
@Mapper
public interface PersonDao {
    public Person selectPersonById1(Integer id) ;
    public Person selectPersonById2(Integer id) ;
    public SelectPersonById selectPersonById3(Integer id) ;
}

8-在src目录下创建com.controller包,在该包中创建OneToOneController类,在该类中调用接口方法

import com.dao.PersonDao;
import com.po.Person;
import com.pojo.SelectPersonById;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class OneToOneController {
    @Autowired
    private PersonDao personDao ;
    public void test(){
        Person p1 = personDao.selectPersonById1(1) ;
        System.out.println(p1) ;
        System.out.println("====================") ;
        Person p2 = personDao.selectPersonById2(1) ;
        System.out.println(p2) ;
        System.out.println("====================") ;
        SelectPersonById p3 = personDao.selectPersonById3(1) ;
        System.out.println(p3) ;
    }
}

9-在com.controller包中创建测试类TestOneToOne.

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestOneToOne {
    public static void main(String[] args){
        ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml") ;
        OneToOneController oto = (OneToOneController) appCon.getBean("oneToOneController");
        oto.test() ;
    }
}

10-运行结果如下:

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

mybatis 一对一级联 一对多

java,mybatis 一对多级联查询,怎么给多的一方添加条件啊???

Mybatis 级联查询 (一对多 )

MyBatis一对多级联查询

SSM-MyBatis-15:Mybatis中关联查询(多表操作)

mybatis 一对多和多对一关联查询