一:阐述

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

二、一对一:

需要清楚:

现在我们创建2个表:

         CREATE TABLE username(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(),
sex VARCHAR()
); CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
num VARCHAR(),
user_id INT
);

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

参照物是:订单

联合查询sql:

 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类:

 package jd.com.ou;

 public class orders {
private String num;
private Integer user_id; public void setNum(String num) {
this.num = num;
} public void setUser_id(Integer user_id) {
this.user_id = user_id;
} public Integer getUser_id() {
return user_id;
} public String getNum() {
return num;
}
}

user类:

 package jd.com.ou;

 public class user {
private String name;
private String sex; public void setName(String name) {
this.name = name;
} public void setSex(String sex) {
this.sex = sex;
} public String getName() {
return name;
} public String getSex() {
return sex;
}
}

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

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

 package jd.com.ou;

 public class customuo extends orders {
private String name;
private String sex; public void setSex(String sex) {
this.sex = sex;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public String getName() {
return name;
} @Override
public String toString() {
return this.name+this.sex+this.getNum();
}
}

mapper配置文件:

 <?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="jd.com.ou.oumapper">
<select id="findOrderAndUser" resultType="jd.com.ou.customuo" parameterType="jd.com.ou.customuo">
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;
</select>
</mapper>

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

mapper接口:

 package jd.com.ou;

 import java.util.List;

 public interface oumapper {
List<customuo> findOrderAndUser();
}

测试类:

 package jd.com.ou;

 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 org.junit.jupiter.api.Test; import java.io.IOException;
import java.io.InputStream; import java.util.List; public class testDemo { @Test
public void testDemo() throws IOException {
String reource="SqlMapConfig.xml";
InputStream inp= Resources.getResourceAsStream(reource);
SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(inp);
SqlSession sqlSession=sqlSessionFactory.openSession();
oumapper oum=sqlSession.getMapper(oumapper.class);
List<customuo> list=oum.findOrderAndUser();
System.out.println(list);
}
}

注意:

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

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

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

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

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

 package jd.com.ou;

 public class custuo2 {
private String num;
private Integer user_id;
private user us;
private Integer id; public void setId(Integer id) {
this.id = id;
} public Integer getId() {
return id;
} public void setUs(user us) {
this.us = us;
} public user getUs() {
return us;
} public void setNum(String num) {
this.num = num;
} public void setUser_id(Integer user_id) {
this.user_id = user_id;
} public Integer getUser_id() {
return user_id;
} public String getNum() {
return num;
} @Override
public String toString() {
return this.getNum()+" "+this.getId()+" "+this.getUser_id()+" "+this.getUs().toString();
}
}

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

mapper配置文件:

   <select id="findOrderAndUserObj"  resultMap="UserObj">
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;
</select>
<!--
type:是我们resultMap类型的泛型值。
id:是别人调用该resultMap的唯一标识。
-->
<resultMap id="UserObj" type="jd.com.ou.custuo2" >
<!--
id:是主键列
result:非主键列
property:是类的属性名称
javaType:是属性名称的类型。
column:是实际数据库列的名称.
-->
<id property="id" javaType="int" column="oid"/>
<result property="user_id" javaType="int" column="uid"/>
<result javaType="string" property="num" column="num"/>
<association property="us" javaType="jd.com.ou.user" >
<!--
标签:association 是引用外部对象 我们写projo类的时候使用。
其中properites 是类中引用的属性的名称
javaType:引用对象的类型。
-->
<id javaType="int" property="id" column="id"/>
<result property="name" javaType="string" column="name"/>
<result property="sex" javaType="string" column="sex"/>
</association>
</resultMap>

三:一对多

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

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

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

mapper文件:

     <select id="findOrderAndUserObjlIST" resultMap="UseList" >
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;
</select>
<resultMap id="UseList" type="jd.com.ou.ouList" >
<id property="id" column="id" javaType="int"/>
<result property="name" javaType="string" column="name" />
<result property="sex" column="sex" javaType="string"/>
<collection property="ord" ofType="jd.com.ou.orders" >
<id property="id" column="oid"/>
<result property="num" column="num"/>
<result property="user_id" column="uid"/> </collection>
</resultMap>

接口文件:

 package jd.com.ou;

 import java.util.List;

 public interface oumapper {
List<customuo> findOrderAndUser();
List<customuo> findOrderAndUserObj();
List<ouList> findOrderAndUserObjlIST();
}

自定义接收类:

 package jd.com.ou;

 import java.util.List;

 public class ouList {
private Integer id;
private String name;
private String sex;
private List<orders> ord; public void setOrd(List<orders> ord) {
this.ord = ord;
} public List<orders> getOrd() {
return ord;
} public void setId(Integer id) {
this.id = id;
} public Integer getId() {
return id;
} public void setName(String name) {
this.name = name;
} public String getName() {
return name;
} public void setSex(String sex) {
this.sex = sex;
} public String getSex() {
return sex;
} @Override
public String toString() {
return this.getSex()+" "+this.getId()+" "+this.getName()+" "+this.getOrd().toString();
}
}

测试类:

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

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

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

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

JAVA框架 Mybaits 一对一、一对多的更多相关文章

  1. JAVA框架 Mybaits 核心配置

    一:mybaits的核心配置文件:SqlMapConfig.xml 配置文件中需要关注的属性: 二.properites属性:一般引用配置文件(properites文件)比如:数据库的配置.我们可以编 ...

  2. JAVA框架 Mybaits 动态代理

    一.动态代理: mybaits给咱们提供一套动态代理,我们只需要按他的要求写接口即可,mybatis帮做动态代理,相当于咱们写的接口的实现类.底层通过反射实例化代理对象,通过代理对象调用相应的方法, ...

  3. JAVA框架 Mybaits

     注意:我们在resultType中,对于selectlist方法也是projo类.resultType参数的含义是list的泛型的类型. 一:jar包下载: https://github.com/m ...

  4. java框架篇---hibernate(一对多)映射关系

    一对多关系可以分为单向和双向. 一对多关系单向 单向就是只能从一方找到另一方,通常是从主控类找到拥有外键的类(表).比如一个母亲可以有多个孩子,并且孩子有母亲的主键作为外键.母亲与孩子的关系就是一对多 ...

  5. JAVA框架 Mybaits 动态sql

    动态sql 一:if标签使用: 我们在查询的时候,有时候由于查询的条件的不确定性,导致where的后面的条件的不同,这时候就需要我们进行where后面的条件进行拼接. Mapper配置文件: < ...

  6. JAVA框架 Mybaits 输入和输出映射

    一.输入映射 当前端传来的参数,比较复杂,比如说用户名称.订单单号.账号信息等等.后端有可能有多个projo类对应这些信息.我们需要把这些的projo类封装成一个类似一个vo类. 通过设置字段形式关联 ...

  7. MyBaits一对一的查询方法

    MyBaits一对一的查询方法 一:表数据与表结构 CREATE TABLE teacher( t_id INT PRIMARY KEY AUTO_INCREMENT, t_name ) ); CRE ...

  8. 转 分享我在阿里工作十年接触过Java框架设计模式

    转 原文: 分享我在阿里工作十年接触过Java框架设计模式 一.前言 说起来设计模式,大家应该都耳熟能详,设计模式代表了软件设计的最佳实践,是经过不断总结提炼出来的代码设计经验的分类总结,这些模式或者 ...

  9. 一,java框架学习

    一,java框架学习 Hibernate概述Hibernate是一个开放源代码的ORM(对象关系映射)框架,对jdbc进行了轻量级的封装,是的java开发人员可以使用面向对象编程思想操作数据库,简化操 ...

随机推荐

  1. hadoop的namenode启动失败

    1.jps发现namenode启动失败 每次开机都要重新格式化一下namenode才可以 其实问题出现自tmp文件上,因为每次开机就会被清空,所以现在我们配置一个tmp文件目录. 如果之前没有配置过, ...

  2. git中的ssh和https方式的使用(gitee为例)

    在使用git管理代码,或者使用github,国内的码云(gitee)的时候,有两种方式可以使用,分别是https和ssh,以下均使用gitee为例. ssh方式 配置ssh,如果不配置ssh的话,cl ...

  3. BZOJ5322: [JXOI2018]排序问题

    传送门 不难看出期望就是 \(\frac{(n+m)!}{\prod_{v=1}^{max}(cnt_v!)}\),\(cnt_v\) 表示 \(v\) 这个数出现的次数. 贪心就是直接把 \(m\) ...

  4. 使用CSS 3创建不规则图形

    前言 CSS 创建复杂图形的技术即将会被广泛支持,并且应用到实际项目中.本篇文章的目的是为大家开启它的冰山一角.我希望这篇文章能让你对不规则图形有一个初步的了解. 现在,我们已经可以使用CSS 3 常 ...

  5. LeetCode题解之Binary Tree Tilt

    1.题目描述 2.分析 利用递归实现. 3.代码 int findTilt(TreeNode* root) { if (root == NULL) ; ; nodesTilt(root,ans); r ...

  6. CSS揭秘(一)引言

    借了一本CSS揭秘,国外的一本书,应该是目前相关书目里最好的了,内容非常扎实,不得不说图灵教育出的书真的不错,不然不是很厚的一本书卖到99也是.... 国外的这类书总是以问题开始,然后通过解决问题引出 ...

  7. Nginx服务器报 "Too Many Open Files"

    近日服务器上的运行的一个站点经常性出现500错误.查了下服务器负载,负载正常.而后查询了下nginx记录的站点运行错误日志,发现提示Too many open files.因为站点静态文件居多,而且h ...

  8. [IDEA_3] IDEA 配置 GitHub 并上传项目

    0. 说明 参考 Git & GitHub 的安装配置 IDEA 配置 GitHub 并上传项目 1. 安装配置 Git & GitHub 参照 Git & GitHub 的安 ...

  9. Active Directory、Exchange、单点登录,企业账号统一管理解决方案

    现在的公司一般都会有很多内部管理系统,比如OA.ERP.CRM.邮件系统等.员工入职之后如果每个系统都创建一个账号和密码,首先员工记系统账号就是一件非常头疼的事情,如果公司有一百个系统那就得创建一百个 ...

  10. Apache的权限设置与构建虚拟web主机

    实验拓扑图: 实验要求: 1.  搭建WEB服务器,能访问默认站点,并使用awstats软件能监控到默认站点的访问情况. 2.  修改Apache的主配置文件,设置1.10只能访问awstats网站, ...