MyBatis一对一、一对多、多对多级联查询

0.准备工作:

创建Mysql表

1.引入maven依赖:其中包括mybatis本身和逆向工程生成依赖

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <!--Mybatis-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <!--Mysql的驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.13</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
    <!--log4j日志的两个核心jar-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.11.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.11.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
    <!--Mybatis工程逆向生成-->
    <dependency>
      <groupId>org.mybatis.generator</groupId>
      <artifactId>mybatis-generator-core</artifactId>
      <version>1.3.5</version>
    </dependency>
  </dependencies>
<build>
    <finalName>mybatisTestDay1_2</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        
        <!--Mybatis-generator插件,用于自动生成Mapper和POJO-->
        <plugin>
          <groupId>org.mybatis.generator</groupId>
          <artifactId>mybatis-generator-maven-plugin</artifactId>
          <version>1.3.2</version>
          <configuration>
            <!--配置文件的位置-->
            <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
            <verbose>true</verbose>
            <overwrite>true</overwrite>
          </configuration>
          <executions>
            <execution>
              <id>Generate MyBatis Artifacts</id>
              <goals>
                <goal>generate</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

 2.如果想在使用过程中查看日志输出,需要在resources中添加log4j的配置文件

<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="warn">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%m%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

3.关于逆向工程生成,可以看我另一篇博文

4.逆向生成好实体类、实体类的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>
    <!-- 1、mybatis也可以使用properties来引入外部properties配置文件的内容(主要还是配置数据库账号密码)
               resource 引入类路径下资源
               url 引入网络路径或磁盘路径下资源 -->
    <properties resource="dbConfig.properties"></properties>
    <!-- 2、settings包含很多重要的全局参数设置,一般使用默认即可
             setting标识具体的设置项
                 name表示设置项的名字
                 value表示设置项的值 -->
    <settings>
        <!--设置开启懒加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
        <setting name="cacheEnabled" value="true"/>
    </settings>
    <!-- 3、typeAliases 为java类型起别名,在parameterType和resultType中就可以直接使用别名了
              typeAlias 为某个具体的java类型取别名
                   type java类的全类名,默认别名就是类名小写
                   alias 自定义别名 -->
    <typeAliases>
        <typeAlias type="com.ogms.domain.User" alias="User" />
        <!-- package为某个包下面所有类批量起别名
           name 表示包的名称 默认别名为类名小写,在使用的的时候,首字母大小写都可以
           这里重复配置了User类,复制的时候注掉一种配置-->
        <!--<package name="com.ogms.domain" />-->
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <!-- 配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--单独加载,根目录是资源目录resources-->
        <mapper resource="mappers/UserMapper.xml"/>
        <mapper resource="mappers/ItemMapper.xml"/>
        <mapper resource="mappers/OrdersMapper.xml"/>
        <mapper resource="mappers/OrderdetailMapper.xml"/>
        <mapper resource="mappers/OrdersUserMapper.xml"/>
        <mapper resource="mappers/UserItemVoMapper.xml"/>
        <mapper resource="mappers/OrdersUserLazyLoadingMapper.xml"/>
        <!--批量加载,根目录是类的根目录java,即将UserMapper.xml放在com.ogms.configs下-->
        <!--<package name="com.ogms.configs"></package>-->
    </mappers>
</configuration>

5.获取SqlSession的类:

package com.ogms.dao;
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 java.io.IOException;
import java.io.InputStream;
/**
 * @Author: David.Xiao
 * @Date: 2018/11/17 15:52
 * @Description:
 */
public class MybatisUtils {
    static String resource = "mybatisConfig.xml";
    static SqlSessionFactory sqlSessionFactory;
    static SqlSession session;
    static InputStream inputStream;
    static {
        try {
            inputStream =  Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //创建Session工厂,用以产生session
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //得到session
        session = sqlSessionFactory.openSession();
    }
    public static SqlSession getSqlSession()
    {
        return session;
    }
}

6.一个订单只对应一个用户,一对一查询映射文件及测试代码:

首先在Orders类中添加User对象

public class Orders {  
  private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    //...省略其它成员
}

写OrdersUserMapper.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.ogms.domain.OrdersUserMapper" >
    <!--映射订单关联的用户-->
    <resultMap id="UserOrderVoResultMap" type="com.ogms.vo.OrderUserVo" >
        <id column="id" property="id" jdbcType="BIGINT" />
        <result column="user_id" property="userId" jdbcType="BIGINT" />
        <result column="number" property="number" jdbcType="VARCHAR" />
        <result column="createtime" property="createtime" jdbcType="TIMESTAMP" />
        <result column="note" property="note" jdbcType="VARCHAR" />
        <result column="username" property="userName" jdbcType="VARCHAR"/>
        <result column="sex" property="sex" jdbcType="CHAR"/>
        <result column="address" property="address" jdbcType="VARCHAR"/>
        <!--用于映射一对一关联查询, 一个订单关联一个用户,association表示被关联的表和java实体类之间的映射关系
        property:要将关联查询的用户信息映射到Orders中哪个属性,在此之前必须在Orders类中建立User user成员-->
        <association property="user" javaType="com.ogms.domain.User">
            <!--在 一个订单只关联一个用户 关联中,column指定订单表中唯一标识用户的字段-->
            <id column="user_id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
        </association>
    </resultMap>
    <!--一对一查询 映射订单关联的用户-->
    <select id="queryOrdersUser" resultMap="UserOrderVoResultMap">
        SELECT orders.*,username,sex,address FROM orders,user where orders.user_id = user.id;
    </select>
</mapper>

在OrdersUserMapper接口类中添加方法:

public interface OrdersUserMapper {
    List<OrderUserVo> queryOrdersUser();
}

测试代码:

package com.ogms.dao;

import com.ogms.domain.OrdersUserMapper;
import com.ogms.vo.OrderUserVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
 * @Author: David.Xiao
 * @Date: 2018/11/21 20:16
 * @Description:
 */
public class One2OneTest {
    @Test
    public void queryOrdersUser()
    {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //创建UserMapper代理对象
        OrdersUserMapper ordersUserMapper = sqlSession.getMapper(OrdersUserMapper.class);
        List<OrderUserVo> list = ordersUserMapper.queryOrdersUser();
        System.out.println(list);
    }
}

7.一对多映射文件及测试代码

<?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.ogms.domain.UserMapper">
  <!--使用二级缓存-->
  <cache/>
  <resultMap id="BaseResultMap" type="com.ogms.domain.User">
    <result column="id" jdbcType="BIGINT" property="id" />
    <result column="username" jdbcType="VARCHAR" property="username" />
    <result column="birthday" jdbcType="DATE" property="birthday" />
    <result column="sex" jdbcType="CHAR" property="sex" />
    <result column="address" jdbcType="VARCHAR" property="address" />
  </resultMap>

  <!--一对多映射:查询每个用户关联的订单-->
  <resultMap id="UserOrderResultMap" type="com.ogms.domain.User">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="birthday" property="birthday"/>
    <result column="sex" property="sex"/>
    <result column="address" property="address"/>
    <collection property="ordersList" ofType="com.ogms.domain.Orders">
      <id column="id" property="id"/>
      <result column="user_id" property="userId"/>
      <result column="number" property="number"/>
      <result column="createtime" property="createtime"/>
      <result column="note" property="note"/>
    </collection>
  </resultMap>
  <!--一对多查询:查询每个用户关联的订单-->
  <select id="queryUserOrder" resultMap="UserOrderResultMap">
        select user.*,user_id,number,createtime,note from user,orders where user.id = orders.user_id;
  </select>
  <select id="queryUserById" parameterType="int" resultMap="BaseResultMap">
    select user.* from user where id = #{user_id};
  </select>

</mapper>

在User实体类中添加OrderList成员

public class User {
    private List<Orders> ordersList;
    public List<Orders> getOrdersList() {
        return ordersList;
    }
    public void setOrdersList(List<Orders> ordersList) {
        this.ordersList = ordersList;
    }
    //省略其它成员    
}

UserMapper接口类:

public interface UserMapper {
    List<User> queryUserOrder();
    User queryUserById(int user_id);
}

测试代码:

package com.ogms.dao;

import com.ogms.domain.User;
import com.ogms.domain.UserMapper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
 * @Author: David.Xiao
 * @Date: 2018/11/22 14:47
 * @Description:
 */
public class One2ManyTest {
    /**
     * 一对多:查询一个用户关联的订单
     */
    @Test
    public void queryUserOrders()
    {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //创建UserMapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.queryUserOrder();
        System.out.println(userList);
    }
}

8.一个用户关联多个商品,一个商品也被多个用户购买,多对多操作

创建一个UserItem实体类,其中包含要查询出各个表中的字段对应的成员

public class UserItemVo {
    private int id;
    private String username;
    private String address;

    private int order_id;
    private String order_number;
    private Date order_createtime;

    private int item_id;
    private int orderdetail_num;

    private String item_name;
    private Float item_price;
}

映射文件:

<?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.ogms.domain.UserItemVoMapper" >
    <!--映射订单关联的用户-->
    <resultMap id="UserItemVoResultMap" type="com.ogms.vo.UserItemVo" >
        <id column="id" property="id" jdbcType="BIGINT" />
        <result column="username" property="username"/>
        <result column="address" property="address"/>
        <result column="order_id" property="order_id"/>
        <result column="number" property="order_number"/>
        <result column="order_createtime" property="order_createtime"/>
        <result column="item_id" property="item_id"/>
        <result column="item_num" property="orderdetail_num"/>
        <result column="name" property="item_name"/>
        <result column="price" property="item_price"/>
    </resultMap>
    <!--多对多查询 映射订单关联的用户-->
    <select id="queryUserItems" resultMap="UserItemVoResultMap">
        SELECT user.id,username,address,orders.id order_id,number,orders.createtime order_createtime,item.id item_id,item_num,name,price  FROM orders,user,orderdetail,item
        where orders.user_id = user.id and orderdetail.order_id = orders.id and item.id = orderdetail.item_id;
    </select>
</mapper>

接口类:

public interface UserItemVoMapper {
    List<UserItemVo> queryUserItems();
}

测试代码:

public class Many2ManyTest {
    /**
     * 多对多:查询一个用户关联的订单
     */
    @Test
    public void queryUserOrders()
    {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //创建UserMapper代理对象
        UserItemVoMapper userItemVoMapper = sqlSession.getMapper(UserItemVoMapper.class);
        List<UserItemVo> userList = userItemVoMapper.queryUserItems();
        for (UserItemVo useritem:userList) {
            System.out.println(useritem);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_22339269/article/details/84546458