• JAVA框架 Mybaits 一对一、一对多


    一:阐述

    我们在日常操作的时候,很多时候会遇到多表联合查询,由于参照物的不通 ,会出现一对一、一对多的情况。比如说:账号信息和订单表,从订单表角度和账号信息是一对一的情况(一个订单只能是一个用户的情况),从用户的角度,就会出现一对多的情况(一个用户会有多个订单)。

    二、一对一:

    需要清楚:

    现在我们创建2个表:

     1         CREATE TABLE username(
     2             id INT PRIMARY KEY AUTO_INCREMENT,
     3             NAME VARCHAR(20),
     4             sex VARCHAR(20)
     5         );
     6 
     7         CREATE TABLE orders (
     8             id INT PRIMARY KEY AUTO_INCREMENT,
     9             num VARCHAR(20),
    10             user_id INT
    11         );

    创建订单表和用户表。插入一些值。

    参照物是:订单

    联合查询sql:

    1 SELECT o.`id`AS oid ,o.`num` AS num ,o.`user_id` AS uid,u.* FROM orders AS o, username AS u WHERE o.user_id=u.id;

    结果:

    第一个方法:

    首先映射类:

    orders类:

     1 package jd.com.ou;
     2 
     3 public class orders {
     4     private String num;
     5     private Integer user_id;
     6 
     7     public void setNum(String num) {
     8         this.num = num;
     9     }
    10 
    11     public void setUser_id(Integer user_id) {
    12         this.user_id = user_id;
    13     }
    14 
    15     public Integer getUser_id() {
    16         return user_id;
    17     }
    18 
    19     public String getNum() {
    20         return num;
    21     }
    22 }

    user类:

     1 package jd.com.ou;
     2 
     3 public class user {
     4     private String name;
     5     private String sex;
     6 
     7     public void setName(String name) {
     8         this.name = name;
     9     }
    10 
    11     public void setSex(String sex) {
    12         this.sex = sex;
    13     }
    14 
    15     public String getName() {
    16         return name;
    17     }
    18 
    19     public String getSex() {
    20         return sex;
    21     }
    22 }

    注意:并不是为了联合查询就需要建立这2个表,而是这2个类是user表和ordes表的projo类。

    然后我们定义返回数据的projo类:

     1 package jd.com.ou;
     2 
     3 public class customuo extends orders {
     4     private String name;
     5     private String sex;
     6 
     7     public void setSex(String sex) {
     8         this.sex = sex;
     9     }
    10 
    11     public void setName(String name) {
    12         this.name = name;
    13     }
    14 
    15     public String getSex() {
    16         return sex;
    17     }
    18 
    19     public String getName() {
    20         return name;
    21     }
    22 
    23     @Override
    24     public String toString() {
    25         return this.name+this.sex+this.getNum();
    26     }
    27 }

    mapper配置文件:

    1 <?xml version="1.0" encoding="UTF-8" ?>
    2 <!DOCTYPE mapper
    3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5 <mapper namespace="jd.com.ou.oumapper">
    6     <select id="findOrderAndUser" resultType="jd.com.ou.customuo" parameterType="jd.com.ou.customuo">
    7         SELECT o.`id`AS oid ,o.`num` AS num ,o.`user_id` AS uid,u.* FROM orders AS o, username AS u WHERE o.`user_id`=u.id;
    8     </select>
    9 </mapper>

    注意在sql语句中,where关键字中,前面定义列的别名,在where的表达是中不能用列的别名。

    mapper接口:

    1 package jd.com.ou;
    2 
    3 import java.util.List;
    4 
    5 public interface oumapper {
    6     List<customuo> findOrderAndUser();
    7 }

    测试类:

     1 package jd.com.ou;
     2 
     3 import org.apache.ibatis.io.Resources;
     4 import org.apache.ibatis.session.SqlSession;
     5 import org.apache.ibatis.session.SqlSessionFactory;
     6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
     7 import org.junit.jupiter.api.Test;
     8 
     9 import java.io.IOException;
    10 import java.io.InputStream;
    11 
    12 import java.util.List;
    13 
    14 public class testDemo {
    15 
    16     @Test
    17     public  void  testDemo() throws IOException {
    18         String reource="SqlMapConfig.xml";
    19         InputStream inp= Resources.getResourceAsStream(reource);
    20         SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(inp);
    21         SqlSession sqlSession=sqlSessionFactory.openSession();
    22         oumapper oum=sqlSession.getMapper(oumapper.class);
    23         List<customuo> list=oum.findOrderAndUser();
    24         System.out.println(list);
    25     }
    26 }

    注意:

        这里我们的定义接收返回值的customuo类中,我们并没有将user的字段设置成customuo的属性。为什么呢??

    因为我们没有传入参数,也就是说,无法设置user类到customuo的属性中,这样,如果调用customuo的user属性会是对象的默认值:null。

    那如果我们想使用user字段该怎么操作呢?

    第二种方法:实际生产用的情况。

    将orders类的字段和user对象的设置成新类custuo2。

     1 package jd.com.ou;
     2 
     3 public class custuo2 {
     4     private String num;
     5     private Integer user_id;
     6     private user us;
     7     private Integer id;
     8 
     9     public void setId(Integer id) {
    10         this.id = id;
    11     }
    12 
    13     public Integer getId() {
    14         return id;
    15     }
    16 
    17     public void setUs(user us) {
    18         this.us = us;
    19     }
    20 
    21     public user getUs() {
    22         return us;
    23     }
    24 
    25     public void setNum(String num) {
    26         this.num = num;
    27     }
    28 
    29     public void setUser_id(Integer user_id) {
    30         this.user_id = user_id;
    31     }
    32 
    33     public Integer getUser_id() {
    34         return user_id;
    35     }
    36 
    37     public String getNum() {
    38         return num;
    39     }
    40 
    41     @Override
    42     public String toString() {
    43         return this.getNum()+" "+this.getId()+" "+this.getUser_id()+" "+this.getUs().toString();
    44     }
    45 }

    mapper配置文件,resultType的类型改为:resultMap该属性字段值是resultMap标签的id值。

    mapper配置文件:

     1   <select id="findOrderAndUserObj"  resultMap="UserObj">
     2         SELECT o.`id`AS oid ,o.`num` AS num ,o.`user_id` AS uid,u.* FROM orders AS o, username AS u WHERE o.`user_id`=u.id;
     3     </select>
     4     <!--
     5      type:是我们resultMap类型的泛型值。
     6      id:是别人调用该resultMap的唯一标识。
     7     -->
     8     <resultMap id="UserObj" type="jd.com.ou.custuo2"  >
     9         <!--
    10         id:是主键列
    11         result:非主键列
    12         property:是类的属性名称
    13         javaType:是属性名称的类型。
    14         column:是实际数据库列的名称.
    15         -->
    16         <id property="id" javaType="int" column="oid"/>
    17         <result property="user_id" javaType="int" column="uid"/>
    18         <result javaType="string" property="num" column="num"/>
    19         <association property="us" javaType="jd.com.ou.user" >
    20             <!--
    21             标签:association 是引用外部对象 我们写projo类的时候使用。
    22             其中properites 是类中引用的属性的名称
    23             javaType:引用对象的类型。
    24             -->
    25             <id javaType="int" property="id" column="id"/>
    26             <result property="name" javaType="string" column="name"/>
    27             <result property="sex" javaType="string" column="sex"/>
    28         </association>
    29     </resultMap>

     三:一对多

    一对多,那自定义 接收类中,对于一对多种的多的类型写成泛型的List对象。

    1、需要注意的是在mapper文件中接收集合的是使用标签<collection>

    2、需要注意的是collection标签的 需要设置属性ofType而不是javaType。该属性值是你自定义的接受类的定义的泛型的类型。

    mapper文件:

     1     <select id="findOrderAndUserObjlIST" resultMap="UseList" >
     2         SELECT o.`id`AS oid ,o.`num` AS num ,o.`user_id` AS uid,u.* FROM orders AS o, username AS u WHERE o.`user_id`=u.id;
     3     </select>
     4     <resultMap id="UseList" type="jd.com.ou.ouList"  >
     5         <id property="id"  column="id" javaType="int"/>
     6         <result property="name" javaType="string" column="name" />
     7         <result property="sex" column="sex" javaType="string"/>
     8         <collection property="ord" ofType="jd.com.ou.orders" >
     9             <id property="id" column="oid"/>
    10             <result property="num" column="num"/>
    11             <result property="user_id" column="uid"/>
    12 
    13         </collection>
    14     </resultMap>

    接口文件:

    1 package jd.com.ou;
    2 
    3 import java.util.List;
    4 
    5 public interface oumapper {
    6     List<customuo> findOrderAndUser();
    7     List<customuo> findOrderAndUserObj();
    8     List<ouList> findOrderAndUserObjlIST();
    9 }

    自定义接收类:

     1 package jd.com.ou;
     2 
     3 import java.util.List;
     4 
     5 public class ouList {
     6     private Integer id;
     7     private String name;
     8     private String sex;
     9     private List<orders>  ord;
    10 
    11     public void setOrd(List<orders> ord) {
    12         this.ord = ord;
    13     }
    14 
    15     public List<orders> getOrd() {
    16         return ord;
    17     }
    18 
    19     public void setId(Integer id) {
    20         this.id = id;
    21     }
    22 
    23     public Integer getId() {
    24         return id;
    25     }
    26 
    27     public void setName(String name) {
    28         this.name = name;
    29     }
    30 
    31     public String getName() {
    32         return name;
    33     }
    34 
    35     public void setSex(String sex) {
    36         this.sex = sex;
    37     }
    38 
    39     public String getSex() {
    40         return sex;
    41     }
    42 
    43     @Override
    44     public String toString() {
    45         return this.getSex()+" "+this.getId()+" "+this.getName()+" "+this.getOrd().toString();
    46     }
    47 }

     测试类:

     1   @Test
     2     public  void  testdemo2() throws IOException {
     3         String resource="SqlMapConfig.xml";
     4         InputStream inp=Resources.getResourceAsStream(resource);
     5         SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inp);
     6         SqlSession sqlSession=sqlSessionFactory.openSession();
     7         oumapper oum=sqlSession.getMapper(oumapper.class);
     8         List<ouList> list=oum.findOrderAndUserObjlIST();
     9         System.out.println(list);
    10     }

     注意:一对一的时候,我们使用的2种方法。

    其中第一种方法需要注意的是:不设置projo类型的字段,否则获取不到值,这是因为自定义的projo引用,这时候需要通过set方法才能加载内存如果不设置的话,会使用其默认值。

    第二种方法,通过标签<association>来实现projo类型的引用的。一对多也是。推荐第二种方法。

  • 相关阅读:
    Visual Studio Code 上java开发环境搭建
    c++编译时打印宏定义
    git使用
    Let's Encrypt申请证书及使用
    使用docker创建aosp编译环境
    项目中使用protobuf 3.0
    ubuntu14.04 安装mono
    ubuntu14.04 安装apache+mysql+php
    Discuz & UCenter 修改手记
    代码细节重构:请对我的代码指手划脚(四)
  • 原文地址:https://www.cnblogs.com/evilliu/p/8951803.html
Copyright © 2020-2023  润新知