JAVA框架 Mybaits 一对一对多

Posted evil_liu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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类型的引用的。一对多也是。推荐第二种方法。

 

以上是关于JAVA框架 Mybaits 一对一对多的主要内容,如果未能解决你的问题,请参考以下文章

一对多和递归关系 - 强制设置值

sql 训练及总结

实体框架4.1代码优先中的一对多关系

Mybatis框架中实现一对多关系映射

框架 day32 Hibernate,一级缓存,关联关系映射(一对多,多对多)

Java--Mybatis关联映射之关联单个对象(即一对一);关联多个对象(即一对多)