spring boot 2使用Mybatis多表关联查询
模拟业务关系:
一个用户user有对应的一个公司company,每个用户有多个账户account。
spring boot 2的环境搭建见上文:spring boot 2整合mybatis
一、mysql创表和模拟数据sql
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`company_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO
`user`
VALUES
(1, 'aa', 1),
(2, 'bb', 2); INSERT INTO
`company`
VALUES
(1, 'xx公司'),
(2, 'yy公司'); INSERT INTO
`account`
VALUES
(1, '中行', 1),
(2, '工行', 1),
(3, '中行', 2);
二、创建实体
public class User {
private Integer id;
private String name;
private Company company;
private List<Account> accounts;
//getter/setter 这里省略...
}
public class Company {
private Integer id;
private String companyName;
//getter/setter 这里省略...
}
public class Account {
private Integer id;
private String accountName;
//getter/setter 这里省略...
}
三、开发Mapper
方法一:使用注解
1、AccountMapper.java
package com.example.demo.mapper; import java.util.List; import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select; import com.example.demo.entity.Account; public interface AccountMapper {
/*
* 根据用户id查询账户信息
*/
@Select("SELECT * FROM `account` WHERE user_id = #{userId}")
@Results({
@Result(property = "accountName", column = "name")
})
List<Account> getAccountByUserId(Long userId);
}
2、CompanyMapper.java
package com.example.demo.mapper; import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select; import com.example.demo.entity.Company; public interface CompanyMapper {
/*
* 根据公司id查询公司信息
*/
@Select("SELECT * FROM company WHERE id = #{id}")
@Results({
@Result(property = "companyName", column = "name")
})
Company getCompanyById(Long id);
}
3、UserMapper.java
package com.example.demo.mapper; import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Many; import com.example.demo.entity.User; public interface UserMapper { /*
* 一对一查询
* property:查询结果赋值给此实体属性
* column:对应数据库的表字段,做为下面@One(select方法的查询参数
* one:一对一的查询
* @One(select = 方法全路径) :调用的方法
*/
@Select("SELECT * FROM user WHERE id = #{id}")
@Results({
@Result(property = "company", column = "company_id", one = @One(select = "com.example.demo.mapper.CompanyMapper.getCompanyById"))
})
User getUserWithCompany(Long id); /*
* 一对多查询
* property:查询结果赋值给此实体属性
* column:对应数据库的表字段,可做为下面@One(select方法)的查询参数
* many:一对多的查询
* @Many(select = 方法全路径) :调用的方法
*/
@Select("SELECT * FROM user WHERE id = #{id}")
@Results({
@Result(property = "id", column = "id"),//加此行,否则id值为空
@Result(property = "accounts", column = "id", many = @Many(select = "com.example.demo.mapper.AccountMapper.getAccountByUserId"))
})
User getUserWithAccount(Long id); /*
* 同时用一对一、一对多查询
*/
@Select("SELECT * FROM user")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "company", column = "company_id", one = @One(select = "com.example.demo.mapper.CompanyMapper.getCompanyById")),
@Result(property = "accounts", column = "id", many = @Many(select = "com.example.demo.mapper.AccountMapper.getAccountByUserId"))
})
List<User> getAll();
}
方法二:使用XML
参考上文spring boot 2整合mybatis配置application.properties和mybatis-config.xml等后,
以上面的getAll()方法为例,UserMapper.xml配置如下:
<?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.example.demo.mapper.UserMapper" >
<resultMap id="UserMap" type="com.example.demo.entity.User">
<id column="id" jdbcType="INTEGER" property="id" />
<result property="name" column="name" jdbcType="VARCHAR" />
<!--封装映射company表数据,user表与company表1对1关系,配置1对1的映射
association:用于配置1对1的映射
属性property:company对象在user对象中的属性名
属性javaType:company属性的java对象 类型
属性column:user表中的外键引用company表
-->
<association property="company" javaType="com.example.demo.entity.Company" column="company_id">
<id property="id" column="companyid"></id>
<result property="companyName" column="companyname"></result>
</association>
<!--配置1对多关系映射
property:在user里面的List<Account>的属性名
ofType:当前account表的java类型
column:外键
-->
<collection property="accounts" ofType="com.example.demo.entity.Account" column="user_id">
<id property="id" column="accountid"></id>
<result property="accountName" column="accountname"></result>
</collection>
</resultMap> <select id="getAll" resultMap="UserMap" >
SELECT
u.id,u.name,c.id companyid, c.name companyname, a.id accountid,a.name accountname
FROM user u
LEFT JOIN company c on u.company_id=c.id
LEFT JOIN account a on u.id=a.user_id
</select> </mapper>
四、控制层
package com.example.demo.web; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper; @RestController
public class UserController {
@Autowired
private UserMapper userMapper; //请求例子:http://localhost:9001/getUserWithCompany/1
/*请求结果:{"id":1,"name":"aa","company":{"id":1,"companyName":"xx公司"},"accounts":null}*/
@RequestMapping("/getUserWithCompany/{id}")
public User getUserWithCompany(@PathVariable("id") Long id) {
User user = userMapper.getUserWithCompany(id);
return user;
} //请求例子:http://localhost:9001/getUserWithAccount/1
/*请求结果:{"id":1,"name":"aa","company":null,"accounts":[{"id":1,"accountName":"中行"},{"id":2,"accountName":"工行"}]}*/
@RequestMapping("/getUserWithAccount/{id}")
public User getUserWithAccount(@PathVariable("id") Long id) {
User user = userMapper.getUserWithAccount(id);
return user;
} //请求例子:http://localhost:9001/getUserWithAccount/1
/*请求结果:[{"id":1,"name":"aa","company":{"id":1,"companyName":"xx公司"},"accounts":[{"id":1,"accountName":"中行"},
{"id":2,"accountName":"工行"}]},{"id":2,"name":"bb","company":{"id":2,"companyName":"yy公司"},"accounts":[{"id":3,"accountName":"中行"}]}]*/
@RequestMapping("/getUsers")
public List<User> getUsers() {
List<User> users=userMapper.getAll();
return users;
}
}
spring boot 2使用Mybatis多表关联查询的更多相关文章
- 三、mybatis多表关联查询和分布查询
前言 mybatis多表关联查询和懒查询,这篇文章通过一对一和一对多的实例来展示多表查询.不过需要掌握数据输出的这方面的知识.之前整理过了mybatis入门案例和mybatis数据输出,多表查询是在前 ...
- JAVA入门[9]-mybatis多表关联查询
概要 本节要实现的是多表关联查询的简单demo.场景是根据id查询某商品分类信息,并展示该分类下的商品列表. 一.Mysql测试数据 新建表Category(商品分类)和Product(商品),并插入 ...
- mybatis多表关联查询之resultMap单个对象
resultMap的n+1方式实现多表查询(多对一) 实体类 创建班级类(Clazz)和学生类(Student),并在Student中添加一个Clazz类型的属性,用于表示学生的班级信息. mappe ...
- MyBatis 多表关联查询
多表关联查询 一对多 单条SQL实现. //根据部门编号查询出部门和部门成员姓名public dept selectAll() thorws Excatipon; //接口的抽象方法 下面是对应接口的 ...
- Mybatis多表关联查询字段值覆盖问题
一.错误展示 1.首先向大家展示多表关联查询的返回结果集 <resultMap id="specialdayAndWorktimeMap type="com.hierway. ...
- 5.mybatis一对一表关联查询
方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集,封装联表查询的数据(去除重复的数据) SELECT * FROM class c,teacher t WHERE c.tid = t.t ...
- 三、Mybatis多表关联查询应用
一对一查询 实现语句:select * from neworder o, user u where o.uid = u.id 实体Order: 接口: 配置: 测试: 一对多查询 实现语句:selec ...
- Spring Boot入门系列(十七)整合Mybatis,创建自定义mapper 实现多表关联查询!
之前讲了Springboot整合Mybatis,介绍了如何自动生成pojo实体类.mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能.mybatis 插件自动生成的mappe ...
- Spring Boot:实现MyBatis动态创建表
综合概述 在有些应用场景中,我们会有需要动态创建和操作表的需求.比如因为单表数据存储量太大而采取分表存储的情况,又或者是按日期生成日志表存储系统日志等等.这个时候就需要我们动态的生成和操作数据库表了. ...
随机推荐
- 解决spring 用@Value注入配置时候出现中文乱码问题
只要是乱码,很明显需要指定编码格式,为utf-8 <!-- 注解使用properties --> <bean id="configProperties" clas ...
- mysql查询两个日期之前相隔的天数
select timestampdiff(SECOND,'2011-09-25 23:23:13','2011-09-26 22:23:11'); 其中SECOND同样可以改为HOUR,MINUTE
- tfs权限设置
需求,管理员用户可以看到tfs里面的所有项目,现在需要给某个开发人员设置权限,只让其看到其中某一个项目. 一.tfs服务器设置 1.在服务器管理器中的[本地用户和组]中添加一个新用户,并在“组”将新用 ...
- AndroidStudio中如何使用GsonFormat
转载:https://www.jianshu.com/p/3b82f42e5937 第一步: 找到AndroidStudio中得Prefrences的plugins的Browse repositori ...
- netty例子
流式编程 客户端 这里MessageToByteEncoder继承于outchanel 服务端
- python借助ADB工具实现自动化操作手机
核心工具——ADB工具 adb工具用于连接Android手机和PC端,我们借助adb工具,就可以通过命令行对手机进行相应的操作 注意:若要通过adb操作手机,需打开手机的开发者模式,并打开USB调试功 ...
- ESP8266 RTOS SDK(IDF)编译环境搭建
前提条件 按照https://www.cnblogs.com/ansersion/p/10458171.html的步骤搭建非IDF环境 下载 https://github.com/espressif/ ...
- MATLAB符号对象与符号运算
序言 符号对象(Symbolic Objects 不同于普通的数值计算)是Matlab中的一种特殊数据类型,它可以用来表示符号变量.表达式以及矩阵,利用符号对象能够在不考虑符号所对应的具体数值的情况下 ...
- numpy处理时间序列
1. 字符串转成numpy.datetime64格式 import numpy as np #将字符串转换成numpy格式时间 #注意个位前补0,如1月写成01 nd=np.datetime64('2 ...
- 6#day2总结
一次小小的总结https://github.com/DuGuQiuBai/Java/blob/master/day02/day02%E6%80%BB%E7%BB%93.txt 1:常量(掌握) (1) ...