MyBatis一对多级联查询

Posted nuist__NJUPT

tags:

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

MyBatis一对多级联查询

级联关系是数据库实体的概念,有3种级联关系,分别为1对1级联,1对多级联,多对多级联。
级联的优点:关联数据十分方便。
缺点:级联过多会增加数据库系统的复杂度,同时降低系统性能。
如果表A引用了表B的主键,A表就是主表,B表就是父表,当查询表A数据时,通过A的外键将B的相关记录返回,这就是级联查询。例如,当查询一个人的个人信息,可以通过身份证号返回他的身份信息。
在实际生活中一对多级联关系有很多,例如一个用户可以有多个订单,而一个订单只属于一个用户。
下面通过用户和订单的关系实现一对多级联查询,根据uid查询用户及其关联的订单信息。
一对多级联查询:
1-在mysql中创建名为spring的数据库,在该数据库中创建用户表user和订单表,这两张表具有一对多级联关系。
user表:


orders表:


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

3-在src目录下创建com.po包,在该包中创建ordres表对应的持久化类Orders,user表对应的持久化类MyUser。
MyUser类:

import java.util.List;

public class MyUser {
    public Integer uid ; //主键
    public String uname ;
    public String usex ;
    private List<Orders> ordersList ;

    public List<Orders> getOrdersList() {
        return ordersList;
    }

    public void setOrdersList(List<Orders> ordersList) {
        this.ordersList = ordersList;
    }

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUsex() {
        return usex;
    }

    public void setUsex(String usex) {
        this.usex = usex;
    }
    @Override
    public String toString(){
        return "User [uid = " + uid + " uname = " + uname + " usex = " + usex + " orderList = " + ordersList + "]" ;
    }
}

Orders类:

import java.util.List;

/**
 * spring数据库中orders表的持久化类
 * 一个用户可以有多个订单,订单只属于一个用户,
 * 根据uid查询用户即其关联的订单信息
 */
public class Orders {
    private Integer id ;
    private String ordersn ;

    public Integer getId() {
        return id;
    }

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

    public String getOrdersn() {
        return ordersn;
    }

    public void setOrdersn(String ordersn) {
        this.ordersn = ordersn;
    }

    @Override
    public String toString(){
        return "Orders [id = " + id + " ordersn = " + ordersn + "]" ;
    }
}

4-在src目录下创建包com.mybatis,并在该包中创建两张表的映射文件UserMapper.xml和OrdersMpper.xml
UserMapper.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.UserDao">
    <!--一对多,根据用户uid,查询用户及其关联的订单信息,级联查询的第一种方法,嵌套查询-->
    <resultMap type = "com.po.MyUser" id = "userAndOrders1">
        <id property = "uid" column = "uid"/>
        <result property = "uname" column = "uname"/>
        <result property = "usex" column = "usex"/>
        <!--一对多级联查询,ofType表示集合中的元素类型,将uid传递给selectOrderById-->
        <collection property = "ordersList" ofType = "com.po.Orders" column = "uid"
                    select = "com.dao.OrdersDao.selectOrdersById"/>
    </resultMap>
    <select id = "selectUserOrdersById" parameterType = "Integer" resultMap ="userAndOrders1">
        select * from user where uid = #{uid}
    </select>
    <!--一对多:根据uid查询用户及其关联的订单信息,级联查询的第二种方法,嵌套结果-->
    <resultMap type = "com.po.MyUser" id = "userAndOrders2">
        <id property = "uid" column = "uid"/>
        <result property = "uname" column = "uname"/>
        <result property = "usex" column = "usex"/>
        <!--一对多级联查询,ofType表示集合中的元素类型-->
        <collection property = "ordersList" ofType = "com.po.Orders">
            <id property = "id" column = "id"/>
            <result property = "ordersn" column = "ordersn"/>
        </collection>
    </resultMap>
    <select id = "selectUserOrdersById2" parameterType = "Integer" resultMap = "userAndOrders2">
        select u.*, o.id, o.ordersn
        from user u, orders o
        where u.uid = o.user_id and uid = #{uid}
    </select>
    <!--一对多,根据uid查询用户及其关联的订单信息,连接查询,使用POJO存储查询结果-->
    <select id = "selectUserOrdersById3" parameterType = "Integer" resultType = "com.pojo.SelectUserOrdersById">
        select u.* , o.id, o.ordersn
        from user u , orders o
        where u.uid = o.user_id and uid = #{uid}
    </select>
</mapper>

OrdersMapper.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.OrdersDao">
   <!--根据用户uid查询用户订单信息-->
    <select id = "selectOrdersById" parameterType="Integer" resultType="com.po.Orders">
        select * from orders where user_id = #{uid}
    </select>
</mapper>

5-创建POJO类,用POJO存储结果,第三种级联查询方式需要创建该类,在src目录下创建com.pojo包,在该包中创建类SelectUserOrdersById.

public class SelectUserOrdersById {
    private Integer uid ;
    private String uname ;
    private String usex ;
    private Integer id ;

    public String getOrdersn() {
        return ordersn;
    }

    public void setOrdersn(String ordersn) {
        this.ordersn = ordersn;
    }

    private String ordersn ;

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUsex() {
        return usex;
    }

    public void setUsex(String usex) {
        this.usex = usex;
    }

    public Integer getId() {
        return id;
    }

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


    public String toString(){
        return "User [ uid = " + uid + " uname = " + uname + " usex = " + usex  + " oid = " + id + " ordersn = " + ordersn + "]" ;
    }
}

6-在src目录下创建com.dao包,在该包中创建映射文件对应的数据操作接口OrdersDao和UserDao.
OrdersDao:

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

import java.util.List;

@Repository
@Mapper
public interface OrdersDao {
    //一个用户可以有多个订单
    public List<Orders> selectOrdersById(Integer uid) ;
}

UserDao:

import com.po.MyUser;
import com.pojo.MapUser;
import com.pojo.SelectUserOrdersById;
import com.pojo.SelectUserParam;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;
//数据访问层的注解,表示该层交给Spring管理
@Repository
@Mapper
/**
 * Spring将指定包中使用@Mapper注解的接口自动装配为MyBatis的映射接口
 */
public interface UserDao {
    //一对多级联查询1
    public MyUser selectUserOrdersById(Integer uid) ;
    //一对多级联查询2
    public MyUser selectUserOrdersById2(Integer uid) ;
    //一对多级联查询3
    public SelectUserOrdersById selectUserOrdersById3(Integer uid) ;
}

7-在包com.mybatis中MyBatis的核心配置文件mybatis-config.xml,在该文件中需要告诉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/OrdersMapper.xml"/>
    </mappers>
</configuration>

8-在src目录下创建spring配置文件applicationContext.xml,在该配置文件中需要扫描指定的包,使得注解生效,同时需要配置数据源等。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--指定需要扫描的包,是注解生效-->
    <context:component-scan base-package="com.dao"/>
    <context:component-scan base-package="com.controller"/>
    <!--配置数据源-->
    <bean id = "dataSource" class = "org.apache.commons.dbcp2.BasicDataSource">
        <!--配置数据库驱动-->
        <property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
        <!--配置连接数据库的url-->
        <property name = "url" value = "jdbc:mysql://localhost:3306/spring?characterEncoding=utf8"/>
        <!--连接数据库的用户名-->
        <property name = "username" value = "root"/>
        <!--连接数据库的密码-->
        <property name = "password" value = "123456"/>
        <!--最大连接数-->
        <property name = "maxTotal" value = "30"/>
        <!--最大空闲连接数-->
        <property name = "maxIdle" value = "10"/>
        <!--初始化最大连接数-->
        <property name = "initialSize" value = "5"/>
    </bean>
    <!--添加事务支持-->
    <bean id = "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name = "dataSource" ref = "dataSource"/>
    </bean>
    <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="txManager"/>
    <!--配置MyBatis工厂,同时指定数据源,并与MyBatis完美整合-->
    <bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean">
        <property name = "dataSource" ref = "dataSource"/>
        <!--configLocation的属性值为MyBatis的核心配置文件-->
        <property name = "configLocation" value = "classpath:com/mybatis/mybatis-config.xml"/>
    </bean>
    <!--Mapper代理开发,使用Spring自动扫描MyBatis接口并装配,Spring将指定包中的所有被@Mapper注解过的接口自动装配为MyBatis的映射接口-->
    <bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--mybatis-spring的组件扫描器-->
        <property name = "basePackage" value = "com.dao"/>
        <property name = "sqlSessionFactoryBeanName" value = "sqlSessionFactory"/>
    </bean>
</beans>

9-在src目录下创建com.controller包,在该包中创建oneToMoreController类,在该类中调用数据操作接口UserDao中的接口方法


import com.dao.UserDao;
import com.po.MyUser;
import com.pojo.SelectUserOrdersById;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class

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

MyBatis一对一级联查询

mybatis怎么有条件的级联查询????

MyBatis-记录

MyBatis多对多级联查询

mybatis多对多级联查询

Mybatis 级联查询 (一对多 )