文章目录
环境:
jdk 1.8
springboot: 2.5.14
一、配置
1、maven依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
</dependencies>
<!-- 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependencies>
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.14</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、配置文件application.yaml
#数据源配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://1.13.152.218:3306/mp?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: zhuang123
#数据库名称
project:
database: mysql
#mybatis-plus配置
mybatis-plus:
configuration:
#sql日志打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#开启驼峰命名匹配
map-underscore-to-camel-case: true
#mapper文件
mapper-locations: classpath:mapper/${project.database}/**/*.xml,classpath:mapper/*.xml
#数据库实体类的包全路径,方便在mapper.xml中不许使用实体类的全路径,写类名就行(不区分大小写)
type-aliases-package: com.zhuang.mp.entity
global-config:
db-config:
#逻辑删除
logic-delete-value: 0
logic-not-delete-value: 1
logic-delete-field: deleted
二、创建过程
1.创建数据库与java实体类
新建user表:
java实体类:
package com.zhuang.mp.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Builder;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
@Data
@Builder
@TableName(value = "user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
@JsonAlias("user_name")
private String name;
@JsonAlias("user_age")
private Integer age;
@JsonAlias("user_email")
private String email = "862627527@qq.com";
@TableField(value = "create_time", fill = FieldFill.INSERT)
//后端传给前端的时间格式
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//前端传给后端的时间格式
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonAlias("create_time")
private Date createTime;
@JsonAlias("update_time")
@TableField(value = "update_time" ,fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
2.mapper或dao层
UserMapper接口:继承BaseMapper<T>
, T为实体类User,需要加上@Mappe
r注解,如果不加注解需要在启动类上加@MapperScan
注解
package com.zhuang.mp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhuang.mp.entity.User;
import com.zhuang.mp.entity.UserVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface UserMapper extends BaseMapper<User> {
List<User> searchByAges(@Param("ages") List<Long> ages);
List<UserVo> selectBynames(@Param("names") List<String> names);
}
3.mapper.xml文件
一般放在类路径下:src/main/resources/mapper/
设置命名空间 namespace
namespace
=“com.zhuang.mp.mapper.UserMapper
”
<?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.zhuang.mp.mapper.UserMapper">
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="searchByAges" resultType="com.zhuang.mp.entity.User">
select * from user where age in
<foreach collection="ages" item="age" open="(" close=")" separator=",">
#{age}
</foreach>
</select>
<select id="selectBynames" resultType="UserVo">
select name
from user where
<foreach collection="names" item="name" separator="or">
name like "%"#{name}"%"
</foreach>
</select>
</mapper>
4.service层
UserService接口:需要继承IService<T>
, T 为实体类User
package com.zhuang.mp.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zhuang.mp.entity.User;
import com.zhuang.mp.entity.UserVo;
import java.util.List;
/**
* @program: mp
* @description:
* @author: mrzhuang
* @create: 2022-12-15 00:48
**/
public interface UserService extends IService<User> {
int addUser(User user);
int updateUser(User user);
Page<User> searchPage(Page<User> page);
List<User> searchByAges(List<Long> ages);
List<UserVo> selectBynames(List<String> names);
}
UsrServiceIpml实现类:需要继承ServiceImpl<M extends BaseMapper, T>, M为接口UserMapper, T为实体类User,需要加上@Service
注解
package com.zhuang.mp.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuang.mp.entity.User;
import com.zhuang.mp.entity.UserVo;
import com.zhuang.mp.mapper.UserMapper;
import com.zhuang.mp.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import javax.annotation.Resource;
import java.util.List;
/**
* @program: mp
* @description:
* @author: mrzhuang
* @create: 2022-12-15 00:49
**/
@DS("slave_1")
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Resource
private UserMapper userMapper;
@Override
public int addUser(User user) {
int insert = userMapper.insert(user);
return insert;
}
@Override
public int updateUser(@RequestBody User user) {
int update = userMapper.updateById(user);
return update;
}
@Override
public Page<User> searchPage(Page<User> page) {
Page<User> userPage = userMapper.selectPage(page, null);
return userPage;
}
@Override
public List<User> searchByAges(List<Long> ages) {
List<User> list = userMapper.searchByAges(ages);
return list;
}
@Override
public List<UserVo> selectBynames(List<String> names) {
return userMapper.selectBynames(names);
}
}
5.controller层
UserController类:
package com.zhuang.mp.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhuang.mp.entity.User;
import com.zhuang.mp.entity.UserVo;
import com.zhuang.mp.enums.CodeEnum;
import com.zhuang.mp.service.UserService;
import com.zhuang.mp.vo.PageVo;
import com.zhuang.mp.vo.ResponseVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @program: mp
* @description:
* @author: mrzhuang
* @create: 2022-12-17 21:40
**/
@Slf4j
@Api(tags = "用户接口")
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
UserService userService;
@ApiOperation("用户增加")
@RequestMapping("/add")
public ResponseVo<User> addUser(@RequestBody User user){
log.info("user: {}", user);
int insert = userService.addUser(user);
if (insert > 0){
log.info("插入成功!");
return new ResponseVo<>(CodeEnum.SUCESS.code, CodeEnum.SUCESS.message);
}
log.error("插入失败!");
return new ResponseVo<>(CodeEnum.FAILUIRE.code, CodeEnum.FAILUIRE.message);
}
@RequestMapping("/update")
public ResponseVo<User> updateUser(@RequestBody User user){
log.info("user: {}", user);
int update = userService.updateUser(user);
if (update > 0){
log.info("更新成功!");
return new ResponseVo<>(CodeEnum.SUCESS.code, CodeEnum.SUCESS.message);
}
log.error("更新失败!");
return new ResponseVo<>(CodeEnum.FAILUIRE.code, CodeEnum.FAILUIRE.message);
}
@PostMapping("/searchPage")
public ResponseVo<PageVo<User>> searchPage(@RequestBody Page<User> page){
Page<User> userPage = userService.searchPage(page);
PageVo<User> userPageVo = new PageVo<>();
BeanUtils.copyProperties(userPage, userPageVo);
return new ResponseVo<>(userPageVo);
}
@PostMapping("/searchByAges")
public ResponseVo<List<User>> searchByAges(@RequestBody List<Long> ages){
List<User> list = userService.searchByAges(ages);
return new ResponseVo<>(list);
}
@PostMapping("/searchByNames")
public ResponseVo<List<UserVo>> searchByNames(@RequestBody List<String> names){
List<UserVo> list = userService.selectBynames(names);
return new ResponseVo<>(list);
}
}
三、设置时间自动填充
1.实体类日期类型设置
需要再实体类的日期属性上使用@TableField(fill = FieldFill.INSERT)
FiledFill为枚举类型
public enum FieldFill {
/**
* 默认不处理
*/
DEFAULT,
/**
* 插入时填充字段
*/
INSERT,
/**
* 更新时填充字段
*/
UPDATE,
/**
* 插入和更新时填充字段
*/
INSERT_UPDATE
}
实体类:
@TableField(value = "create_time", fill = FieldFill.INSERT)
//后端传给前端的时间格式
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//前端传给后端的时间格式
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonAlias("create_time")
private Date createTime;
@JsonAlias("update_time")
@TableField(value = "update_time" ,fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
2.自定义元对象处理器
实现 MetaObjectHandler
接口
package com.zhuang.mp.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); // 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date()); // 起始版本 3.3.0(推荐使用)
// // 或者
// this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
// // 或者
// this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
// // 或者
// this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
// // 或者
// this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
}
}
四、分页查询
1.配置类中创建bean
ackage com.zhuang.mp.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
//分页查询
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
2.调用分页查询的方法
@Resource
private UserMapper userMapper;
Page<User> userPage = userMapper.selectPage(page, null);
五、多对一映射、一对多映射
举例: 一个老师有多名学生是
一对多
关系,而一个学生只能有一个老师是多对一
关系
1.数据库表设计
设计studen和teacher表, 两个表中的字段命名需要不一样,否则在映射过程中会有问题。
1、student表
java实体类:包含老师属性
package com.zhuang.mp.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author mrzhuang
* @since 2022-12-21
*/
@ApiModel(value = "Student对象", description = "")
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
private Integer sid;
@TableField(value = "s_name")
private String studentName;
private Integer tid;
@TableField(exist = false)
private Teacher teacher;
}
2、teacher表:
java实体类:
package com.zhuang.mp.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author mrzhuang
* @since 2022-12-21
*/
@ApiModel(value = "Teacher对象", description = "教师")
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public class Teacher implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("老师id")
@TableId(value = "t_id", type = IdType.AUTO)
private Integer tid;
@ApiModelProperty("老师姓名")
@TableField(value = "t_name")
private String teacherName;
@ApiModelProperty("学生集合")
@TableField(exist = false)
private List<Student> studentList;
}
2.多对一映射:association
StudentMapper.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.zhuang.mp.mapper.StudentMapper">
<resultMap id="stuResultMap" type="Student">
<id property="sid" column="s_id"/>
<result property="studentName" column="s_name"/>
<result property="tid" column="t_id"/>
<association property="teacher" javaType="teacher">
<id property="tid" column="t_id"/>
<result property="teacherName" column="t_name"/>
</association>
</resultMap>
<select id="selectByMap" resultMap="stuResultMap">
select * from student s left join teacher t on s.t_id = t.t_id
</select>
</mapper>
StudentMapper类:
package com.zhuang.mp.mapper;
import com.zhuang.mp.entity.Student;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author mrzhuang
* @since 2022-12-21
*/
public interface StudentMapper extends BaseMapper<Student> {
/**
* 查询所有学生
* @return /
*/
List<Student> selectByMap();
}
StudentController:
package com.zhuang.mp.controller;
import com.zhuang.mp.entity.Student;
import com.zhuang.mp.service.IStudentService;
import com.zhuang.mp.vo.ResponseVo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author mrzhuang
* @since 2022-12-21
*/
@RestController
@RequestMapping("/mp/student")
public class StudentController {
@Resource
IStudentService studentService;
@GetMapping("/selectByMap")
public ResponseVo<List<Student>> selsectByMap(){
/**
* 查询所有学生
*/
List<Student> students = studentService.selectByMap();
return new ResponseVo<>(students);
}
}
结果:
3.一对多映射:collection
TeacherMapper.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.zhuang.mp.mapper.TeacherMapper">
<resultMap id="techResultMap" type="teacher">
<id property="tid" column="t_id"/>
<result property="teacherName" column="t_name"/>
<collection property="studentList" ofType="student">
<id property="sid" column="s_id"/>
<result property="studentName" column="s_name"/>
<result property="tid" column="t_id"/>
</collection>
</resultMap>
<select id="selectByMap" resultMap="techResultMap">
select * from teacher t right join student s on s.t_id = t.t_id
</select>
</mapper>
TeacherMapper类:
package com.zhuang.mp.mapper;
import com.zhuang.mp.entity.Teacher;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author mrzhuang
* @since 2022-12-21
*/
public interface TeacherMapper extends BaseMapper<Teacher> {
/**
* 查询全部老师
* @return
*/
List<Teacher> selectByMap();
}
TeacherController:
package com.zhuang.mp.controller;
import com.zhuang.mp.entity.Teacher;
import com.zhuang.mp.service.ITeacherService;
import com.zhuang.mp.vo.ResponseVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author mrzhuang
* @since 2022-12-21
*/
@Api(tags = "教师接口")
@RestController
@RequestMapping("/mp/teacher")
public class TeacherController {
@Resource
ITeacherService teacherService;
@ApiOperation("获得全部的老师")
@GetMapping("searchAll")
public ResponseVo<List<Teacher>> searchAll(){
List<Teacher> teachers = teacherService.searchAll();
return new ResponseVo<>(teachers);
}
@ApiOperation("一对一多映射")
@GetMapping("/selectByMap")
public ResponseVo<List<Teacher>> selectByMap(){
List<Teacher> teachers = teacherService.selectByMap();
return new ResponseVo<>(teachers);
}
}
结果:
六、代码生成器
1.maven依赖
<!--逆向代码生成模版-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
2.代码编写
package com.zhuang.generator;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
/**
* @program: mp
* @description: 逆向代码生成器
* @author: mrzhuang
* @create: 2022-12-17 20:56
**/
public class CodeGenerator {
public static void main(String[] args) {
String url = "jdbc:mysql://1.13.152.218:3306/mp?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai";
String username = "root";
String password = "zhuang123";
String author = "mrzhuang";
String outputDir = "/Users/mrzhuang/Downloads/mp/generator";
String parent = "com.zhuang";
String moduleName = "mp";
String xmlPath = "/Users/mrzhuang/Downloads/mp/generator";
//String tablename = "user";
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> {
builder.author(author) // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir(outputDir); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent(parent) // 设置父包名
.moduleName(moduleName) // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, xmlPath)); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("teacher").addInclude("student"); // 设置需要生成的表名
// .addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}