Mybatis的多表操作
1.Mybatis多表查询
1.1 一对一查询
1.1.1 一对一查询的模型MapperScannerConfigurer
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户
1.1.2一对一查询的语句
对应的sql语句:select * from orders o,user u where o.uid=u.id;
查询的结果如下:
1.1.3 创建Order和User实体
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
1.1.4 创建OrderMapper接口
public interface OrderMapper {
List<Order> findAll();
}
1.1.5 配置OrderMapper.xml
主键ID比较的特殊,因此使用id column
其他的用result
<?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.itheima.mapper.OrderMapper">
<resultMap id="orderMap" type="com.itheima.domain.Order">
<!--手动指定字段与实体属性的映射关系
column: 数据表的字段名称
property:实体的属性名称
-->
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
<result column="uid" property="user.id"></result>
<result column="username" property="user.username"></result>
<result column="password" property="user.password"></result>
<result column="birthday" property="user.birthday"></result>
</resultMap>
<select id="findAll" resultMap="orderMap">
SELECT *,o.id oid FROM orders o,USER u WHERE o.uid=u.id
</select>
</mapper>
换种封装方式,将user单独配置了
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
<!--<result column="uid" property="user.id"></result>
<result column="username" property="user.username"></result>
<result column="password" property="user.password"></result>
<result column="birthday" property="user.birthday"></result>-->
<!--
property: 当前实体(order)中的属性名称(private User user)
javaType: 当前实体(order)中的属性的类型(User)
-->
<association property="user" javaType="user">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
</association>
1.1.6 测试结果
@Test
public void test1() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List<Order> orderList = mapper.findAll();
for (Order order : orderList) {
System.out.println(order);
}
sqlSession.close();
}
1.2 一对多查询
1.2.1 一对多查询的模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
1.2.2 一对多查询的语句
SELECT *,o.id oid FROM USER u,orders o WHERE u.id=o.uid
查询的结果如下:
1.2.3 修改User实体
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List<Order> orderList;
}
1.2.4 创建UserMapper接口
public interface UserMapper {
List<User> findAll();
}
1.2.5 配置UserMapper.xml
<mapper namespace="com.itheima.mapper.UserMapper">
<resultMap id="userMap" type="com.itheima.domain.User">
<id column="uid" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
<!--配置集合信息
property:集合名称
ofType:当前集合中的数据类型
-->
<collection property="orderList" ofType="com.itheima.domain.Order">
<!--封装order的数据-->
<id column="oid" property="id"></id>
<result column="ordertime" property="ordertime"></result>
<result column="total" property="total"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="userMap">
SELECT *,o.id oid FROM USER u,orders o WHERE u.id=o.uid
</select>
</mapper>
1.2.6 测试结果
@Test
public void test2() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.findAll();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
1.3 多对多查询
1.3.1 多对多查询的模型
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用
多对多查询的需求:查询用户同时查询出该用户的所有角色
核心就是user_rolse的两个外键
1.3.2 多对多查询的语句
对应的sql语句: SELECT * FROM USER u,sys_user_role ur,sys_role r WHERE u.id=ur.userId AND ur.roleId=r.id
查询的结果如下:
1.3.3 创建Role实体,修改User实体
package com.itheima.domain;
public class Role {
private int id;
private String roleName;
private String roleDesc;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List<Order> orderList;
//代表当前用户具备哪些角色
private List<Role> roleList;
}
public class Role {
private int id;
private String rolename;
}
1.3.4 添加UserMapper接口方法
public List<User> findUserAndRoleAll();
1.3.5 配置UserMapper.xml
<!--自定义别名-->
<typeAliases>
<typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>
<typeAlias type="com.itheima.domain.Order" alias="order"></typeAlias>
<typeAlias type="com.itheima.domain.Role" alias="role"></typeAlias>
</typeAliases>
<resultMap id="userRoleMap" type="user">
<!--user的信息-->
<id column="userId" property="id"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<result column="birthday" property="birthday"></result>
<!--user内部的roleList信息-->
<collection property="roleList" ofType="role">
<id column="roleId" property="id"></id>
<result column="roleName" property="roleName"></result>
<result column="roleDesc" property="roleDesc"></result>
</collection>
</resultMap>
<select id="findUserAndRoleAll" resultMap="userRoleMap">
SELECT * FROM USER u,sys_user_role ur,sys_role r WHERE u.id=ur.userId AND ur.roleId=r.id
</select>
1.3.6 测试结果
@Test
public void test3() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userAndRoleAll = mapper.findUserAndRoleAll();
for (User user : userAndRoleAll) {
System.out.println(user);
}
sqlSession.close();
}
1.4 知识小结
MyBatis多表配置方式:
一对一配置:使用<resultMap>做配置
一对多配置:使用<resultMap>+<collection>做配置
多对多配置:使用<resultMap>+<collection>做配置
2.Mybatis的注解开发
2.1 MyBatis的常用注解
这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper
映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
2.2 MyBatis的增删改查
我们完成简单的user表的增删改查的操作
public class MyBatisTest {
private UserMapper mapper;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
mapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testSave(){
User user = new User();
user.setUsername("tom");
user.setPassword("abc");
mapper.save(user);
}
@Test
public void testUpdate(){
User user = new User();
user.setId(18);
user.setUsername("lucy");
user.setPassword("123");
mapper.update(user);
}
@Test
public void testDelete(){
mapper.delete(18);
}
@Test
public void testFindById(){
User user = mapper.findById(2);
System.out.println(user);
}
@Test
public void testFindAll(){
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
}
}
配置UserMapper的接口
package com.itheima.mapper;
import com.itheima.domain.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserMapper {
@Insert("insert into user values(#{id},#{username},#{password},#{birthday})")
public void save(User user);
@Update("update user set username=#{username},password=#{password} where id=#{id}")
public void update(User user);
@Delete("delete from user where id=#{id}")
public void delete(int id);
@Select("select * from user where id=#{id}")
public User findById(int id);
@Select("select * from user")
public List<User> findAll();
@Select("select * from user")
@Results({
@Result(id=true ,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "password",property = "password"),
@Result(
property = "orderList",
column = "id",
javaType = List.class,
many = @Many(select = "com.itheima.mapper.OrderMapper.findByUid")
)
})
public List<User> findUserAndOrderAll();
@Select("SELECT * FROM USER")
@Results({
@Result(id = true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "password",property = "password"),
@Result(
property = "roleList",
column = "id",
javaType = List.class,
many = @Many(select = "com.itheima.mapper.RoleMapper.findByUid")
)
})
public List<User> findUserAndRoleAll();
}
修改MyBatis的核心配置文件,我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可,或者指定扫描包含映射关系的接口所在的包也可以
<!--加载映射关系-->
<mappers>
<!--指定接口所在的包-->
<package name="com.itheima.mapper"></package>
</mappers>
2.3 MyBatis的注解实现复杂映射开发
实现复杂关系映射之前我们可以在映射文件中通过配置<resultMap>来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置
2.4 一对一查询
2.4.1 一对一查询的模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户
2.4.2 一对一查询的语句
对应的sql语句:
select * from orders;
select * from user where id=查询出订单的uid;
2.4.3 创建Order和User实体
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
}
2.4.4 创建OrderMapper接口
public interface OrderMapper {
List<Order> findAll();
}
2.4.5 使用注解配置Mapper
@Select("select *,o.id oid from orders o,user u where o.uid=u.id")
@Results({
@Result(column = "oid",property = "id"),
@Result(column = "ordertime",property = "ordertime"),
@Result(column = "total",property = "total"),
@Result(column = "uid",property = "user.id"),
@Result(column = "username",property = "user.username"),
@Result(column = "password",property = "user.password")
})
public List<Order> findAll();
对应的sql语句:
select * from orders;
select * from user where id=查询出订单的uid;
@Select("select * from orders")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "ordertime",property = "ordertime"),
@Result(column = "total",property = "total"),
@Result(
property = "user", //要封装的属性名称
column = "uid", //根据那个字段去查询user表的数据
javaType = User.class, //要封装的实体类型
//select属性 代表查询那个接口的方法获得数据
one = @One(select = "com.itheima.mapper.UserMapper.findById")
)
})
public List<Order> findAll();
public interface UserMapper {
@Select("select * from user where id=#{id}")
User findById(int id);
}
通过查询结果中的uid再进行查询,执行查询语句
2.4.6 测试结果
package com.itheima.test;
import com.itheima.domain.Order;
import com.itheima.domain.User;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.UserMapper;
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.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyBatisTest2 {
private OrderMapper mapper;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
mapper = sqlSession.getMapper(OrderMapper.class);
}
@Test
public void testSave(){
List<Order> all = mapper.findAll();
for (Order order : all) {
System.out.println(order);
}
}
}
2.5 一对多查询
2.5.1 一对多查询的模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
select * from user;
select * from orders where uid=查询出用户的id;
2.5.3 修改User实体
public class Order {
private int id;
private Date ordertime;
private double total;
//代表当前订单从属于哪一个客户
private User user;
}
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些订单
private List<Order> orderList;
}
2.5.4 创建UserMapper接口
public List<User> findUserAndOrderAll();
2.5.5 使用注解配置Mapper
public interface UserMapper {
@Select("select * from user")
@Results({
@Result(id=true ,column = "id",property = "id"),//主键
@Result(column = "username",property = "username"),
@Result(column = "password",property = "password"),
@Result(
property = "orderList",
column = "id",
javaType = List.class,
many = @Many(select = "com.itheima.mapper.OrderMapper.findByUid")
)
})
public List<User> findUserAndOrderAll();
}
public interface OrderMapper {
@Select("select * from orders where uid=#{uid}")
List<Order> findByUid(int uid);
}
2.5.6 测试结果
public class MyBatisTest3 {
private UserMapper mapper;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
mapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testSave(){
List<User> userAndOrderAll = mapper.findUserAndOrderAll();
for (User user : userAndOrderAll) {
System.out.println(user);
}
}
}
2.6 多对多查询
2.6.1 多对多查询的模型
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用
多对多查询的需求:查询用户同时查询出该用户的所有角色
2.6.2 多对多查询的语句
2.6.3 创建Role实体,修改User实体
public class User {
private int id;
private String username;
private String password;
private Date birthday;
//代表当前用户具备哪些角色
private List<Role> roleList;
}
public class Role {
private int id;
private String rolename;
}
2.6.4 添加UserMapper接口方法
public List<User> findUserAndRoleAll();
2.6.5 使用注解配置Mapper
@Select("SELECT * FROM USER")
@Results({
@Result(id = true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "password",property = "password"),
@Result(
property = "roleList",
column = "id",
javaType = List.class,
many = @Many(select = "com.itheima.mapper.RoleMapper.findByUid")
)
})
public List<User> findUserAndRoleAll();
public interface RoleMapper {
@Select("SELECT * FROM sys_user_role ur,sys_role r WHERE ur.roleId=r.id AND ur.userId=#{uid}")
public List<Role> findByUid(int uid);
}
2.6.6 测试结果
public class MyBatisTest4 {
private UserMapper mapper;
@Before
public void before() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
mapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void testSave(){
List<User> userAndRoleAll = mapper.findUserAndRoleAll();
for (User user : userAndRoleAll) {
System.out.println(user);
}
}
}
Mybatis的多表操作的更多相关文章
- 阶段3 1.Mybatis_09.Mybatis的多表操作_2 完成account表的建立及实现单表查询
mybatis中的多表查询: 示例:用户和账户 一个用户可以有多个账户 一个账户只能属于一个用户(多个账户也可以属于同一个用户) ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_1 mybatis表之间关系分析
4.mybatis中的多表查询 表之间的关系有几种: 一对多 多对一 一对一 多对多 举例: 用户和订单 ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_8 mybatis多对多操作-查询角色获取角色下所属用户信息
一个角色对应多个用户 生成getter和setter 查看两个表的数据 中间表定义了谁有角色,谁没有角色 根据中间表的关系,最终查询出来的列表的数据样子.这需要两个左外链接才能实现功能. 第一个左外链 ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_7 mybatis多对多准备角色表的实体类和映射配置
创建Role表和user_role表 DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `ID` int(11) NOT NULL COMMENT ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_6 分析mybatis多对多的步骤并搭建环境
示例:用户和角色 一个用户可以有多个角色 一个角色可以赋予多个用户 步骤: 1.建立两张表:用户表,角色表 ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_3 完成account的一对一操作-通过写account的子类方式查询
先把多表查询的sql语句写出来 想要显示的字段 创建一个AccountUser类 继承Account.这样它就会从父类上继承一些信息 这里只需要定义username和address就可以了 .然后生成 ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_9 mybatis多对多操作-查询用户获取用户所包含的角色信息
sql语句以user作为主表 用户的全部信息,以为用户下的角色的.并不是所有的用户都有角色,有角色的就带角色.没角色的就为null 首先修改实体类 定义List<Role> 生成gette ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_5 完成user的一对多查询操作
定义List<Account> accounts,生成getter和setter 复制AccountTest类改名UserTest类 修改测试类 还没封装所以Account的list都是n ...
- 阶段3 1.Mybatis_09.Mybatis的多表操作_4 完成account一对一操作-建立实体类关系的方式
定义user的实体.然后生成getter和setter 定义一个可以封装Account和User的Map type这里虽然是account类型 这一段只能保证account的数据完成.并不能保证use ...
随机推荐
- NGK与Captain technology合作 推出贷款体验用于简化汽车经销商流程
据外媒报导,近日,NGK.IO正在与Captain technology恰谈合作事宜,以简化购车体验,包括简化购车流程.NGK的CTO Stephen Litan表示:"NGK宣布与Capt ...
- 【HTB系列】靶机Access的渗透测试详解
出品|MS08067实验室(www.ms08067.com) 本文作者:大方子(Ms08067实验室核心成员) Hack The Box是一个CTF挑战靶机平台,在线渗透测试平台.它能帮助你提升渗透测 ...
- rabbitMQ高可用方案
普通模式 默认的集群模式,以两个节点(rabbit01.rabbit02)为例来进行说明.对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和r ...
- MYSQL安全模式"sql_safe_updates"设置update和delete不带where的操作限制
前言 在数据库操作中,如果在update和delete没有加上where条件,数据将会全部修改. 不只是初识mysql的开发者会遇到这个问题,工作有一定经验的开发者有时难免也会忘记写入where条件. ...
- python进阶(7)垃圾回收机制
Python垃圾回收 基于C语言源码底层,让你真正了解垃圾回收机制的实现 引用计数器 标记清除 分代回收 缓存机制 Python的C源码(3.8.2版本) 1.引用计数器 1.1环状双向链表 refc ...
- Redis 使用入门
NoSql概述 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",它泛指非关系型的数据库, Redis 是一个高性能的开源的.C语言写的Nosql( ...
- 大数据开发-Spark-Streaming处理数据到mysql
前面一篇讲到streamin读取kafka数据加工处理后写到kafka数据,大数据开发-Spark-开发Streaming处理数据 && 写入Kafka是针对比如推荐领域,实时标签等场 ...
- 五. SpringCloud服务降级和熔断
1. Hystrix断路器概述 1.1 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.这就造成有可能会发生服务雪崩.那么什么是服务雪崩呢 ...
- HDOJ-3065(AC自动机+每个模板串的出现次数)
病毒侵袭持续中 HDOJ-3065 第一个需要注意的是树节点的个数也就是tree的第一维需要的空间是多少:模板串的个数*最长模板串的长度 一开始我的答案总时WA,原因是我的方法一开始不是这样做的,我是 ...
- Boltdb学习笔记之〇--概述
更多精彩内容,请关注微信公众号:后端技术小屋 看了boltdb也有一阵子了,看完之后总想写点什么,因为感觉到这可能是个不小的坑,所以迟迟没有动笔(没错我的拖延症又犯了..).最近有一种流行的说法:如果 ...