springboot整合mybatis/mybatis-Plus

107 阅读10分钟

一. Mybatis介绍:

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

Mybatis中文文档:MyBatis中文网


  • 创建一个父工程:

1. pom.xml中导入相关依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
​
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
    </parent>
​
    <groupId>com.chenshi</groupId>
    <artifactId>mybatis-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>spring-mybatis</module>
    </modules>
​
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
​
    <dependencies>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.0.33</version>
        </dependency>
​
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.18</version>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
​
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.33</version>
        </dependency>
​
​
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies></project>

2. 搭建一个子工程项目:

  • springboot三步走:pom.xml,application.yml,App启动类;

3. 继承父工程后,子工程Application.yml中添加配置参数:

server:
  port: 8080

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/cmd_test #数据库连接
      username: root
      password: 123456



4. 创建一个App启动类:

@SpringBootApplication
public class MybatisApp {
    public static void main(String[] args) {
        SpringApplication.run(MybatisApp.class,args);
    }
}

5. 搭建好三层架构:

  • 1, Controller
@RestController
@RequestMapping("/citizen")
public class CitizenController {
​
​
}
  • 2, Service
public interface CitizenService {
​
}    
  • 3, ServiceImpl
@Service("citizenService")
public class CitizenServiceImpl implements CitizenService {
​
    static Logger log = Logger.getLogger(CitizenServiceImpl.class.getName());
​
    @Resource private CitizenMapper citizenMapper;
​
​
}
  • 4, Mapper
@Mapper
public interface CitizenMapper {
​
    

5. 搭建一个对象实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Citizen {
​
    @Range(min = 1,message = "id需要大于0")
    private Integer id;
​
    @NotBlank
    private String name;
​
    @Range(min = 0,max = 2,message = "性别只能为0或2")//2表示其它
    private Integer gender;
​
    @Range(min = 1,max = 120,message = "年龄得在1到120之间")
    private Integer age;
​
    @Length(min = 11,message = "请填写正确的手机号")
    private String phoneNum;
​
    @Nullable
    private String job;
​
    @Nullable
    private String workAddress;
​
    @Range(min = 0,message = "请填写正确的工资")
    private BigDecimal salary;
​
    @Range(min = 0,max = 3,message = "心情状态在0 - 3之间")//数字越高心情越差
    private Integer status;
​
}
​

6. 搭建一个通用返回类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class R<T> {
​
    @Nullable
    private Integer code;
​
    @Nullable
    private String msg;
​
    @Nullable
    private T data;
​
}

7. 搭建一个通用返回码:

public enum ResultCode {
​
    ERROR(4004,"不存在"),
    SUCCESS(2000,"成功!"),
    SERVER_ERROR(5000,"服务器内部错误"),
    DENIED(7000,"拒绝访问"),
    ILLEGAL_ARGUMENT(8000,"非法参数");
​
    private final int code;
    private final String msg;
​
​
    ResultCode(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
​
    public int getCode() {
        return code;
    }
​
    public String getMsg() {
        return msg;
    }
​
}

8,使用java自带的日志:

//在需要的类上加入,静态方法
static Logger log = Logger.getLogger(string name);
​
log.info();
log.warning();
log.severe();

9. 在App启动类添加配置:

@SpringBootApplication
@MapperScan("com.chenshi.mapper")//扫描mapper类
public class SpringMybatisApp {
    public static void main(String[] args) {
        SpringApplication.run(SpringMybatisApp.class,args);
    }
}

10. Mybatis的增删改查:

1. 填加(insert):

  • Controller层:
@RestController
@RequestMapping("/citizen")
public class CitizenController {
@PostMapping("/add/citizen")
    
    @Resource private CitizenService citizenService;
    
    @ResponseBody
    public R<String> addCitizen(@RequestBody Citizen citizen){
        return citizenService.addCitizen(citizen);
    }
    
}

  • Service层:
public interface CitizenService {
​
    R<String> addCitizen(Citizen citizen);

  • ServiceImpl层:
@Service("citizenService")
public class CitizenServiceImpl implements CitizenService {
​
    static Logger log = Logger.getLogger(CitizenServiceImpl.class.getName());
​
    @Resource private CitizenMapper citizenMapper;
    
    @Override
    public R<String> addCitizen(Citizen citizen) {
        try {
            if ("".equals(citizen.getJob()) && "".equals(citizen.getWorkAddress())) {
                citizen.setJob("无业游民");
                citizen.setWorkAddress("在家吃喝睡");
            }
            Boolean ok = citizenMapper.insertCitizen(citizen);
            if (ok) {
                return new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), "Citizen添加成功!");
            }
            throw new RuntimeException("无法添加Citizen");
        } catch (Exception e) {
            log.warning(e.getMessage());
            return new R<>(ResultCode.ILLEGAL_ARGUMENT.getCode(),ResultCode.ILLEGAL_ARGUMENT.getMsg(), "Citizen添加失败!");
        }
    }
    
}

  • Mapper层:
@Mapper
public interface CitizenMapper {
    
    Boolean insertCitizen(Citizen citizen);
    
}
  • Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenshi.mapper.CitizenMapper">
    
    <insert id="insertCitizen" parameterType="com.chenshi.domain.Citizen">
        insert into citizeninfo (id,name,gender,age,phoneNum,job,workAddress,salary,status) values
        (#{id},#{name},#{gender},#{age},#{phoneNum},#{job},#{workAddress},#{salary},#{status});
    </insert>
    
</mapper>

2. 删除(delete):

  • Controller层:
@RestController
@RequestMapping("/citizen")
public class CitizenController {
​
    @Resource private CitizenService citizenService;
​
    @DeleteMapping("/delete/citizen")
        @ResponseBody
        public R<String> deleteCitizen(@RequestBody List<Integer> ids){
            return citizenService.deleteCitizen(ids);
        }
    
    }

  • Service层:
public interface CitizenService {
​
    R<String> deleteCitizen(List<Integer> ids);
​
}

  • SerivceImpl层:
@Service("citizenService")
public class CitizenServiceImpl implements CitizenService {
​
    static Logger log = Logger.getLogger(CitizenServiceImpl.class.getName());
​
    @Resource private CitizenMapper citizenMapper;  
​
    @Override
    public R<String> deleteCitizen(List<Integer> ids) {
        Boolean ok = false;
        try {
            if (null != ids) {
                ok = citizenMapper.removeCitizenById(ids);
            }
            if (Boolean.TRUE.equals(ok)) {
                return new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), "CitizenId删除成功!");
            }
            throw new RuntimeException("Citizen修改失败!");
        } catch (Exception e) {
            log.warning(e.getMessage());
            return new R<>(ResultCode.DENIED.getCode(),ResultCode.DENIED.getMsg(), "服务器内部出错!");
        }
    }
​
}

  • Mapper层:
@Mapper
public interface CitizenMapper {
​
    Boolean removeCitizenById(List<Integer> ids);
​
}
  • Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenshi.mapper.CitizenMapper">
​
    <delete id="removeCitizenById" parameterType="java.util.Map">
        delete from citizeninfo where id in
        <foreach collection="list" open="(" separator="," close=")"  item="id">
            #{id}
        </foreach>
    </delete></mapper>

3. 修改(update):

  • Controller层:
@RestController
@RequestMapping("/citizen")
public class CitizenController {
​
    @PutMapping("/edit/citizen")
    @ResponseBody
    public R<String> editCitizen(@RequestBody Citizen citizen){
        return citizenService.editCitizen(citizen);
    }
    
}

  • Serivice层:
public interface CitizenService {
​
    R<String> editCitizen(Citizen citizen);
​
}

  • ServiceImpl层:
@Service("citizenService")
public class CitizenServiceImpl implements CitizenService {
​
    static Logger log = Logger.getLogger(CitizenServiceImpl.class.getName());
​
    @Resource private CitizenMapper citizenMapper;
​
    @Override
    public R<String> editCitizen(Citizen citizen) {
        Boolean ok = false;
        try {
            Citizen citizenInfo = citizenMapper.findCitizenByName(citizen.getName());
            if (citizenInfo.getName().equals(citizen.getName())) {
                if ("".equals(citizen.getJob()) && "".equals(citizen.getWorkAddress())) {
                    citizen.setJob("无业游民");
                    citizen.setWorkAddress("在家吃喝睡");
                    ok = citizenMapper.updateCitizen(citizen);
                }
            } else {
                return new R<>(ResultCode.ILLEGAL_ARGUMENT.getCode(), ResultCode.ILLEGAL_ARGUMENT.getMsg(), "该CitizenId不存在!");
            }
​
            if (Boolean.TRUE.equals(ok)) {
                return new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), "Citizen信息修改成功!");
            }
            throw new RuntimeException("Citizen修改失败!");
        } catch (Exception e) {
            log.warning(e.getMessage());
            return new R<>(ResultCode.DENIED.getCode(), ResultCode.DENIED.getMsg(), "Citizen修改失败!");
        }
    }
​
}

  • Mapper层:
@Mapper
public interface CitizenMapper {    
​
    Citizen findCitizenByName(String name);
    
    Boolean updateCitizen(Citizen citizen);
​
}

  • Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenshi.mapper.CitizenMapper">
​
    <update id="updateCitizen" parameterType="com.chenshi.domain.Citizen">
        update citizeninfo set name = #{name}, gender = #{gender}, age = #{age}, phoneNum = #{phoneNum},
        job = #{job}, workAddress = #{workAddress}, 
        salary = #{salary}, status = #{status} where name = #   {name};
    </update></mapper>

4. 查询(select):

  • Controller层:
@RestController
@RequestMapping("/citizen")
public class CitizenController {
​
    @Resource private CitizenService citizenService;
​
    @GetMapping("/find/id/{id}")
    @ResponseBody
    public R<Citizen> getNameById(@PathVariable("id") Integer id) {
        return citizenService.getNameById(id);
    }
    
}

  • Service层:
public interface CitizenService {
​
    R<Citizen> getNameById(Integer id);
    
}

  • ServiceImpl层:
@Service("citizenService")
public class CitizenServiceImpl implements CitizenService {
​
    static Logger log = Logger.getLogger(CitizenServiceImpl.class.getName());
​
    @Resource private CitizenMapper citizenMapper;
    
    @Override
    public R<Citizen> getNameById(Integer id) {
        try {
            if (0 > id) {
                throw new RuntimeException("传入参数异常");
            }
            Citizen citizen = citizenMapper.findNameById(id);
            return new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), citizen);
        } catch (Exception e) {
            log.warning(e.getMessage());
            return new R<>(ResultCode.ILLEGAL_ARGUMENT.getCode(), ResultCode.ILLEGAL_ARGUMENT.getMsg(), new Citizen());
        }
​
    }
    
}

  • Mapper层:
@Mapper
public interface CitizenMapper {
    
    Citizen findNameById(Integer id);
    
}

  • Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenshi.mapper.CitizenMapper">
    
    <select id="findNameById" parameterType="Integer" resultType="com.chenshi.domain.Citizen">
        select * from citizeninfo where id = #{id}
    </select>
    
</mapper>

5. 添加&修改(合并):

  • Controller层:
@RestController
@RequestMapping("/citizen")
public class CitizenController {
​
    @Resource private CitizenService citizenService;
​
    @PostMapping("/edit/citizen")
    @ResponseBody
    public R<String> editCitizen(@RequestBody Citizen citizen){
        return citizenService.editCitizen(citizen);
    }
    
}

  • Serivice层:
public interface CitizenService {
​
    R<String> editCitizen(Citizen citizen);
    
}

  • ServiceImpl层:
@Service("citizenService")
public class CitizenServiceImpl implements CitizenService {
​
    static Logger log = Logger.getLogger(CitizenServiceImpl.class.getName());
​
    @Resource private CitizenMapper citizenMapper;
​
    @Override
    public R<String> editCitizen(Citizen citizen) {
        try {
            Boolean ok;
            if ("".equals(citizen.getJob()) && "".equals(citizen.getWorkAddress())) {
                citizen.setJob("无业游民");
                citizen.setWorkAddress("在家吃喝睡");
            }
            Citizen citizenInfo = citizenMapper.findNameById(citizen.getId());
            //添加路线
            if(null == citizenInfo) {
                ok = citizenMapper.insertCitizen(citizen);
            //修改路线
            }else {
                ok = citizenMapper.updateCitizen(citizen);
            }
            if (Boolean.TRUE.equals(ok)) {
                return new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), "Citizen信息修改成功!");
            }
            throw new RuntimeException();
        } catch (RuntimeException e) {
            log.warning(e.getMessage());
            return new R<>(ResultCode.ILLEGAL_ARGUMENT.getCode(), ResultCode.ILLEGAL_ARGUMENT.getMsg(), "Citizen信息生成失败!");
        }
​
    }
​
}

  • Mapper层:
@Mapper
public interface CitizenMapper {
    
    Boolean insertCitizen(Citizen citizen);
​
    Boolean updateCitizen(Citizen citizen);
​
}

  • Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenshi.mapper.CitizenMapper">
    
     <insert id="insertCitizen" parameterType="com.chenshi.domain.Citizen">
        insert into citizeninfo (id,name,gender,age,phoneNum,job,workAddress,salary,status) values
        (#{id},#{name},#{gender},#{age},#{phoneNum},#{job},#{workAddress},#{salary},#{status});
    </insert>
​
    <update id="updateCitizen" parameterType="com.chenshi.domain.Citizen">
        update citizeninfo set name = #{name}, gender = #{gender}, age = #{age}, phoneNum = #{phoneNum},
        job = #{job}, workAddress = #{workAddress}, salary = #{salary}, status = #{status} 
        where name = #{name};
    </update>
    
</mapper>

二. springboot整合mybatis-plus:

Mybatis-Plus介绍:

MyBatis-Plus是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

1, 它的优点也是非常多之多:

无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作

强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求

支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错

2, 支持多种SQL数据库:

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb,informix,TDengine,redshift
  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库,优炫数据库,星瑞格数据库

3, 它也是MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍!。

Mybatis-Plus中文文档:baomidou.com/

1. 父工程中导入依赖:

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    
    <!--这里用仅用springSecurity的Bcrypt加密-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

2. 创建实体类:

2-1. 创建User实体类:

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {
​
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
​
    @TableField("username")
    @NotBlank(message = "请填写用户名!")
    private String username;
​
    @TableField("password")
    private String password;
​
    @TableField("score")
    private BigDecimal score;
​
    //@TableLogic(value = "0",delval = "1")//逻辑删除delval = 1
    @TableField("delFlag")
    private Integer delFlag;
    
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date create_time;
​
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date update_time;
​
}

2-2. 创建Role实体类:

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("role")
public class Role {
​
    @TableId(value = "id",type = IdType.AUTO)
    private int id;
​
    @TableField("roleName")
    private String roleName;
​
    @TableField("roleDescribe")
    private String roleDescribe;
​
    //@TableLogic(value = "0" , delval = "1")
    @TableField("delFlag")
    private Integer delFlag;
    
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date create_time;
​
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date update_time;
​
}

2-3. 创建中间表User_Role:

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user_role")
public class User_Role {
​
    @TableField("userId")
    private Integer userId;
​
    @TableId("roleId")
    private Integer roleId;
​
}

2-4. 配置SpringSecurity放行规则:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
​
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                .antMatchers("/**")
                .permitAll().anyRequest()
                .authenticated()
                .and()
                .csrf()
                .disable();
    }
}

2-5. APP启动类配置bean:

@SpringBootApplication
@MapperScan("com.chenshi.mapper")
public class SpringMybatisApp {
    public static void main(String[] args) {
        SpringApplication.run(SpringMybatisApp.class,args);
    }
​
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}
​

2-6. Mybatis-plus参数配置:

@Configuration
public class MybatisPlusConfig implements MetaObjectHandler {


    @Override
    public void insertFill(MetaObject metaObject) {
        /*
        * 添加更新时填充字段数据
        * */
        this.strictInsertFill(metaObject, "create_time", Date.class, new Date());
        this.strictInsertFill(metaObject, "update_time", Date.class, new Date());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        /*
        * 修改更新时填充字段数据
        * */
        this.strictUpdateFill(metaObject, "update_time", Date.class, new Date());
    }

}

3. 异常自定义:

3-1. 创建自定义异常:

//让自定义异常继承运行时异常
public class BusinessException extends RuntimeException {

    public BusinessException(String message) {
        super(message);
    }
}

3-2. 创建全局异常处理:

@RestControllerAdvice
public class GlobalExceptionHandler {
​
    static Logger log = Logger.getLogger("GlobalExceptionHandler");
​
    @ExceptionHandler(BusinessException.class)
    public R<String> handleBusinessException(BusinessException e){
        log.severe(e.getMessage());
        return new R<>(ResultCode.ILLEGAL_ARGUMENT.getCode(), ResultCode.ILLEGAL_ARGUMENT.getMsg(), "非法参数!");
    }
    //处理全局异常
    @ExceptionHandler(RuntimeException.class)
    public R<String> handleGlobalException(RuntimeException e){
        log.severe(e.getMessage());
        return new R<>(ResultCode.SERVER_ERROR.getCode(), ResultCode.SERVER_ERROR.getMsg(), "服务器异常");
    }
​
}

4. 搭建三层架构:

  • Controller层:
@RestController
@RequestMapping("/user")
public class UserController {
​
    @Resource private com.chenshi.service.userService userService;
​
}

  • Service层:
public interface userService {
​
}

  • ServiceImpl层:
@Service("userService")
public class userServiceImpl implements userService {
​
    @Resource private com.chenshi.mapper.userMapper userMapper;
​
}

  • Mapper层:
@Mapper
public interface userMapper extends BaseMapper<User> {

}

5. Mybatis-Plus的增删改查:

1. 添加&修改(合并):

  • Controller层:
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource private UserService userService;

    @PostMapping("/edit/user")
    @ResponseBody
    public R<String> editUser(@RequestBody User user){
        return userService.editUser(user);
    }

    @PostMapping("/edit/role")
    @ResponseBody
    public R<String> editRole(@RequestBody Role role){
        return userService.editRole(role);
    }
    
}

  • Service层:
public interface UserService {
    R<String> editUser(User user);
    R<String> editRole(Role role);
}

  • ServiceImpl层:
@Service("userService")
public class UserServiceImpl implements UserService {
​
    static Logger log = Logger.getLogger("UserServiceImpl");
    static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
​
    @Resource private UserMapper userMapper;
​
    @Resource
    private UserValidateService userValidateService;
​
    @Override
    public R<String> editUser(User user) {
        try {
            User validateUser = userValidateService.isEmpty(user);
            User dBuser = userMapper.selectById(validateUser.getId());
            int finish = (null == dBuser) ? userMapper.insert(validateUser) : userMapper.updateById(validateUser);
            return finish > 0 ? new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), "User信息更新成功!") : new R<>(ResultCode.ERROR.getCode(),"User信息更新失败!");
        } catch (RuntimeException e) {
            log.warning(e.getMessage());
            return new R<>(ResultCode.ILLEGAL_ARGUMENT.getCode(), ResultCode.ILLEGAL_ARGUMENT.getMsg(), e.getMessage());
        }
​
    }
  
    
    //Role插入Role的数据
    @Override
    public R<String> editRole(Role role) {
        try {
            Role validateRole = validateService.isEmptyRole(role);
            Role dbRole = roleMapper.selectById(validateRole.getId());
            int finish = (null == dbRole) ? roleMapper.insert(validateRole) : roleMapper.updateById(validateRole);
            return finish > 0 ? new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), "Role信息更新成功!") : new R<>(ResultCode.ERROR.getCode(), "Role信息更新失败");
        } catch (RuntimeException e) {
            log.severe(e.getMessage());
            return new R<>(ResultCode.ILLEGAL_ARGUMENT.getCode(), ResultCode.ILLEGAL_ARGUMENT.getMsg(), e.getMessage());
        }
    }
​
}
  1. User的参数校验:
@Service("userValidateService")
public class UserValidateService {
​
    static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    static Logger log = Logger.getLogger(UserValidateService.class.getName());
​
    /*
    * 设置默认值
    * */
    public User isEmpty(User user) {
        try {
            if (StringUtils.isEmpty(user.getPassword())) {
                String encode = encoder.encode("123456");
                user.setPassword(encode);
            }
            if (null == user.getScore()) {
                user.setScore(new BigDecimal(10));
            }
            if (null == user.getDelFlag()) {
                user.setDelFlag(0);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return user;
    }
}

  1. Role的参数校验:
public Role isEmptyRole(Role role) {
    try {
        if (null == role.getDelFlag()) {
            role.setDelFlag(0);
        }
        if (StringUtils.isEmpty(role.getRoleDescribe())) {
            role.setRoleDescribe("角色描述待定");
        }

    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
    return role;
}

2. 给中间表插入数据:

@Override
    public R<String> editUserRole(User_Role userRole) {
        int finish;
        try {
            User_Role roleId = userRoleMapper.selectById(userRole.getRoleId());
            User_Role userId = userRoleMapper.selectById(userRole.getUserId());
            if (null == roleId && null == userId) {
                finish = userRoleMapper.insert(userRole);
            }else {
                finish = userRoleMapper.updateById(userRole);
            }
            if (0 >= finish) {
                throw new BusinessException("UserRole更新失败!");
            }
            return new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), "UserRole更新成功!");
        } catch (BusinessException e) {
            log.severe(e.getMessage());
            return new R<>(ResultCode.ILLEGAL_ARGUMENT.getCode(), ResultCode.ILLEGAL_ARGUMENT.getMsg(), e.getMessage());
        }
    }

3. 通过userId查询role:

  • Controller层:
@RestController
@RequestMapping("/user")
public class UserController {
​
    @Resource private UserService userService;
​
    @GetMapping("/get/userRole/{id}")
    public R<Role> getUserRole(@PathVariable("id") Integer userId){
        return userService.getUserRoleById(userId);
    }
​
}

  • Service层:
public interface UserService {
    R<Role> getUserRoleById(Integer userId);
}

  • ServiceImpl层:
@Service("userService")
public class UserServiceImpl implements UserService {
​
    static Logger log = Logger.getLogger("UserServiceImpl");
    static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    @Resource private UserMapper userMapper;
    @Resource private RoleMapper roleMapper;
    @Resource private UserRoleMapper userRoleMapper;
​
    @Override
    public R<Role> getUserRoleById(Integer userId) {
        try {
            Role role = roleMapper.selectUserRoleById(userId);
            User user = userMapper.selectById(userId);
            if (null == role && user.getDelFlag() == 1) {
                throw new BusinessException("UserRole不存在!");
            }
            return new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), role);
        } catch (BusinessException e) {
            throw new RuntimeException(e);
        }
        
    }
    
}

  • Mapper层:
@Mapper
public interface RoleMapper extends BaseMapper<Role> {
    Role selectUserRoleById(Integer userId);
}

  • Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chenshi.mapper.RoleMapper">
​
    <select id="selectUserRoleById" parameterType="java.lang.Integer" resultType="com.chenshi.domain.Role">
        select r.* from user
        left join user_role ur on ur.userId = user.id
        left join role r on r.id = ur.roleId
        where user.id = #{userId}
    </select></mapper>

4. 删除User(逻辑删除):

  1. Controller层:
@DeleteMapping("/remove/userById/{id}")
public R<String> deleteUserAndRole(@PathVariable("id") Integer userId){
    return userService.removeUserAndRoleById(userId);
}

  1. Service层:
R<String> removeUserAndRoleById(Integer userId);

  1. ServiceImpl层:
@Override
@Transactional
public R<String> removeUserAndRoleById(Integer userId) {
    try {
        int flag = 0;
        User user = userMapper.selectById(userId);
        Role role = roleMapper.selectUserRoleById(user.getId());
        if (null == role) {
            throw new BusinessException("UserRole不存在!");
        }
        //如果已被逻辑删除,再调用此接口为彻底删除该user信息
        if (1 == user.getDelFlag()) {
            userMapper.deleteById(userId);
            userRoleMapper.deleteById(user.getId());
            userRoleMapper.deleteById(role.getId());
        } else {
            user.setDelFlag(1);
            flag = userMapper.updateById(user);
        }
​
        if (0 < flag) {
            return new R<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), "UserRole删除成功!");
        }
        return new R<>(ResultCode.ERROR.getCode(), ResultCode.ERROR.getMsg(), "UserRole删除失败!");
    } catch (BusinessException e) {
        throw new RuntimeException(e);
    }
​
}

6. Iservice<T>接口的使用:

1. 自定义接口:

  • 自定义接口继承Iservice<>类,泛型为自定义实体类;
public interface UserService extends IService<User> {
    //添加自定义方法的实现
}

2.实现类的继承:

  • 实现类继承ServiceImpl<>,泛型1为M,表示Mapper,泛型2为T,表示自定义的实体类;
  • 并且实现继承了Iservice的接口;
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    //重写自定义方法
}

3. 添加&修改:

  • saveOrUpdate( ):该方法底层会判断是添加还是修改;
Boolean saveOrUpdate(entity);

4. 查询:

  • getById( ): 通过id查询,返回自定义实体类;
  • listByIds( ): 根据主键集合查询实体列表;
  • page( ): 通过条件构造器, 进行分页查询;
  • List( ): 查询该实体类的所有数据;
  • map( ): 根据条件查询实体转换为 Map。
  • List(quryWrapper): 自定义条件构造器查询指定数据;
User getById(id);
List<T> listByIds(Collection<? extends Serializable> idList):
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper)
List<T> list();
Map<String, Object> map(Wrapper<T> queryWrapper)
List<T> List(quryWrapper);
​
//列入:
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getId, validateUser.getId());
list(wrapper);

5. 删除:

  • removeById( ): 根据Id删除实体;
  • removeByIds(): 根据Id集合删除实体;
  • remove( ): 根据条件构造器删除实体
boolean removeById(id);
boolean removeByIds(Collection<? extends Serializable> idList);
boolean remove(Wrapper<T> queryWrapper);

6.IService的其他操作:

  • int count( ): 查询总记录数;
  • int count( ): 根据条件构造器查询记录数;
  • getOne( ): 根据条件构造器查询一个实体;
  • exists( ): 根据条件构造器判断是否存在实体;
int count();
int count(Wrapper<T> queryWrapper);
T getOne(Wrapper<T> queryWrapper);
boolean exists(Wrapper<T> queryWrapper);