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

现在我们创建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 一对一、一对多的更多相关文章
- JAVA框架 Mybaits 核心配置
一:mybaits的核心配置文件:SqlMapConfig.xml 配置文件中需要关注的属性: 二.properites属性:一般引用配置文件(properites文件)比如:数据库的配置.我们可以编 ...
- JAVA框架 Mybaits 动态代理
一.动态代理: mybaits给咱们提供一套动态代理,我们只需要按他的要求写接口即可,mybatis帮做动态代理,相当于咱们写的接口的实现类.底层通过反射实例化代理对象,通过代理对象调用相应的方法, ...
- JAVA框架 Mybaits
注意:我们在resultType中,对于selectlist方法也是projo类.resultType参数的含义是list的泛型的类型. 一:jar包下载: https://github.com/m ...
- java框架篇---hibernate(一对多)映射关系
一对多关系可以分为单向和双向. 一对多关系单向 单向就是只能从一方找到另一方,通常是从主控类找到拥有外键的类(表).比如一个母亲可以有多个孩子,并且孩子有母亲的主键作为外键.母亲与孩子的关系就是一对多 ...
- JAVA框架 Mybaits 动态sql
动态sql 一:if标签使用: 我们在查询的时候,有时候由于查询的条件的不确定性,导致where的后面的条件的不同,这时候就需要我们进行where后面的条件进行拼接. Mapper配置文件: < ...
- JAVA框架 Mybaits 输入和输出映射
一.输入映射 当前端传来的参数,比较复杂,比如说用户名称.订单单号.账号信息等等.后端有可能有多个projo类对应这些信息.我们需要把这些的projo类封装成一个类似一个vo类. 通过设置字段形式关联 ...
- MyBaits一对一的查询方法
MyBaits一对一的查询方法 一:表数据与表结构 CREATE TABLE teacher( t_id INT PRIMARY KEY AUTO_INCREMENT, t_name ) ); CRE ...
- 转 分享我在阿里工作十年接触过Java框架设计模式
转 原文: 分享我在阿里工作十年接触过Java框架设计模式 一.前言 说起来设计模式,大家应该都耳熟能详,设计模式代表了软件设计的最佳实践,是经过不断总结提炼出来的代码设计经验的分类总结,这些模式或者 ...
- 一,java框架学习
一,java框架学习 Hibernate概述Hibernate是一个开放源代码的ORM(对象关系映射)框架,对jdbc进行了轻量级的封装,是的java开发人员可以使用面向对象编程思想操作数据库,简化操 ...
随机推荐
- spring-bean实例化三种方式
在spring中,bean的示例化有三种方式. 1.使用类的无参构造函数创建 2.使用静态工厂方式创建 3.使用实例化工厂方式创建. 具体代码如下 静态工厂方式: Bean2.java package ...
- 【读书笔记】iOS-自定义视图的创建
静态创建自定义视图就是以拖动的方法来创建. 动态创建自定义视图可以理解为使用代码来创建自定义视图. 参考资料:<iOS7开发快速入门>
- equals 与 == 的区别
equals 是 用来比较二个对象内容是否相等. == 是用来比较二个对象的内存是否相等. public void testString(){ String s1="123"; S ...
- Python 基于python实现ADSL宽带帐号,密码的获取及宽带拨号
基于python实现ADSL宽带帐号的获取及宽带拨号 基本思想: 1.研究上网方式(实验环境为电信网线接入式ADSL,拨号方式PPPOE) 2.研究宽带帐号和密码生成规律(实验环境,宽带帐号为 ...
- 8 张脑图入门 JavaScript - 基础面试不倒
8 张脑图入门 JavaScript - 基础面试不倒 转载请注明出处 第一:JavaScript 的变量 第二:JavaScript 运算符 第三:JavaScript 数组 第四:JavaScri ...
- Android--解决EditText放到popupWindow中,原有复制、粘贴、全选、选择功能失效问题
1.原来是将EditView放到了popupwindow,发现EditView原有的复制.粘贴.全选.选择功能失效了,所以便用DialogFragment代替了popupWindow 直接上代码 ①. ...
- java EE 监听器
生命周期监听器与属性改变监听器都必须使用@WebListener或在web.xml中声明,容器才会知道要加载.读取相关的监听器.
- Android学习 -- Activity 以及Activity之间值传递
项目结构如图 关键代码如下 strings.xml文件代码如下: <?xml version="1.0" encoding="utf-8"?> &l ...
- window平台搭建Hudson服务器
1.1 环境 Microsoft Windows server 2008 x64 1.2 资源下载 TortoiseSVN-1.7.11.23600-x64-svn-1.7.8.msi h ...
- 如何将SQL Server 2000备份的数据库文件还原(升级)为SQL Server 2005或更高版本的数据库?
其实很简单,有两种方法. 方法一:将SQL Sever 2000数据库备份的数据库文件名后面加上“.bak”,然后直接在SQL Sever 2005或者高版本软件里面直接还原即可: 方法二:在SQL ...