本文介绍了Spring Boot中使用MybatisPlus进行多表查询的方法,包括一对多、多对一关系的实现,以及条件查询和分页查询的示例。
初学Spring boot
MybatisPlus多表查询
这个学的有点绕,下面我来仔细地捋一捋。
实现一对多
查询某用户的信息及所有订单
首先,在User实体中加入一个List
// 描述用户的所有订单
@TableField(exist = false)
private List<Order> orders;- User实体映射到数据库中表的规则
默认映射规则
MyBatis-Plus 默认的 实体类名到表名映射规则:
驼峰转下划线(CamelCase → snake_case)
去掉前缀(如果有的话,可自定义)
例子:
实体类名 数据库表名默认映射
User user
OrderItem order_item
ProductCategory product_category
所以如果表名就是 user,类名就是 User,完全匹配,就不需要 @TableName。
如果表明和实体名不一致,则需要在实体定义前边加上 @TableName("t_user"),意思是该类去对应数据库中的 't_user'表
@TableName("t_user")
public class User {
}然后,在UserMapper中加入该方法的映射关系
//查询用户及其所有订单
@Select("select * from t_user")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "password",property = "password"),
@Result(column = "birthday",property = "birthday"),
@Result(column = "id",property = "orders",javaType = List.class,
many = @Many(select = "org.example.mpdemo.mapper.OrderMapper.selectByUid")
)
})
List<User> selectAllUserAndOrders();- 一个小知识点,Mapper是interface,也就是接口,可以继承BaseMapper
(这个BaseMapper 里有许多内置的方法),在UserController这个拦截器里边,可以直接标注@AutoWired,相当于交给Spring容器,自动根据这个userMapper接口生成了一个实例,可以直接调用这个接口里的方法
@Autowired
private UserMapper usermapper;最后,可以在UserController中调用这个一对多的多表查询了
@GetMapping("/user/findAll")
public List<User> find() {
return usermapper.selectAllUserAndOrders();
}实现多对一
基本方法和原理同一对多的多表查询
OrderMapper中的映射写法
// 查询所有的订单,同时查询订单的用户
@Select("select * from t_order")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "order_time",property = "order_time"),
@Result(column = "total",property = "total"),
@Result(column = "uid",property = "user",javaType = User.class,
one = @One(select = "org.example.mpdemo.controller.UserController.selectById")
)
})
List<Order> selectAllOrdersAndUser();条件查询
// 条件查询
@GetMapping("/user/find")
public List<User> findByCond() {
QueryWrapper<User> queryWrapper = new QueryWrapper();
queryWrapper.eq("username","zhangsan");
return usermapper.selectList(queryWrapper);
}分页查询
要先在config中加一个拦截器
package org.example.mpdemo.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisConfig
{
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
interceptor.addInnerInterceptor(paginationInterceptor);
return interceptor;
}
}
// 分页查询 select * from xx limit 0,10
@GetMapping("/user/findByPage")
public IPage findByPage() {
//设置起始值及每页条数
Page<User> page = new Page(0,2);
IPage iPage = usermapper.selectPage(page,null);
return iPage;
}Cors 跨域问题
- 为了保证浏览器的安全,不同源的客户端脚本在没有明确授权的情况下,不能
读写对方资源,称为同源策略,同源策略是浏览器安全的基石 - 同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安
全功能 - 所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主
机(host)和端口号(port) - 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨
域,此时无法读取非同源网页的 Cookie,无法向非同源地址发送 AJAX 请求
跨域问题解决
- CORS(Cross-Origin Resource Sharing)是由W3C制定的一种跨域资源共享
技术标准,其目的就是为了解决前端的跨域请求。 - CORS可以在不破坏即有规则的情况下,通过后端服务器实现CORS接口,从而
实现跨域通信。 - CORS将请求分为两类:简单请求和非简单请求,分别对跨域通信提供了支持。
简单请求的服务器处理
- 对于简单请求,CORS的策略是请求时在请求头中增加一个Origin字段,
- 服务器收到请求后,根据该字段判断是否允许该请求访问,如果允许,则在
HTTP头信息中添加Access-Control-Allow-Origin字段。
非简单请求
- 对于非简单请求的跨源请求,浏览器会在真实请求发出前增加一次OPTION请
求,称为预检请求(preflight request) - 预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到
HTTP头信息字段中,询问服务器是否允许这样的操作。 - 例如一个GET请求:
- Access-Control-Request-Method表示请求使用的HTTP方法,Access- Control-Request-Headers包含请求的自定义头字段-
- 服务器收到请求时,需要分别对Origin、Access-Control-Request-Method、
Access-Control-Request-Headers进行验证,验证通过后,会在返回HTTP头
信息中添加: - Access-Control-Allow-Methods、Access-Control-Allow-Headers:真实请
求允许的方法、允许使用的字段 - Access-Control-Allow-Credentials: 是否允许用户发送、处理cookie
- Access-Control-Max-Age: 预检请求的有效期,单位为秒,有效期内不会重复
发送预检请求。
非简单请求 - 当预检请求通过后,浏览器才会发送真实请求到服务器。这样就实现了跨域资
源的请求访问。
Spring Boot中配置CORS
加一个CorsConfig文件
package org.example.mpdemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.maxAge(168000)
.allowedHeaders("*");
// .allowCredentials(true);
}
}
根据 W3C 的 CORS 规范,当服务器的响应中包含 Access-Control-Allow-Credentials: true 时,Access-Control-Allow-Origin 头不能设置为通配符 *。它必须明确指定一个或多个允许的来源域名。
对单个控制器进行处理
加上一个@CrossOrigin就可以了,但是仅对此控制器有效,不是全局的。
@RestController
@CrossOrigin
public class UserController {
}