SpringBoot第24讲:SpringBoot集成MySQL - MyBatis XML方式

SpringBoot第24讲:SpringBoot集成MySQL - MyBatis XML方式

上文介绍了用JPA方式的集成MySQL数据库,JPA方式在中国以外地区开发而言基本是标配,在国内MyBatis及其延伸框架较为主流。本文是SpringBoot第24讲,主要介绍MyBatis技栈的演化以及SpringBoot集成基础的MyBatis XML实现方式的实例。

文章目录

  • SpringBoot第24讲:SpringBoot集成MySQL - MyBatis XML方式
    • 1、准备知识
      • 1.1、什么是MyBatis?
      • 1.2、为什么说MyBatis是半自动ORM?
      • 1.3、MyBatis栈技术演进
        • 1、JDBC,自行封装 JDBCUtil
        • 2、IBatis
        • 3、MyBatis(目前我们项目处于这个阶段)
        • 4、MyBatis衍生:代码生成工具等
        • 5、Spring+MyBatis 基于注解的配置集成
        • 6、MyBatis-Plus
    • 2、简单示例
      • 2.1、准备DB和依赖配置
      • 2.2、Mapper文件
      • 2.3、定义dao
      • 2.4、定义Service接口和实现类
      • 2.5、controller
    • 3、示例源码

1、准备知识

需要了解MyBatis及MyBatis技术栈的演进,这对开发新手可以很好的构筑其知识体系。

1.1、什么是MyBatis?

MyBatis是一款优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。

  • MyBatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。
  • MyBatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由MyBatis框架执行sql并将结果映射为java对象并返回。

MyBatis的主要设计目的就是让我们对执行SQL语句时对输入输出的数据管理更加方便,所以方便地写出SQL和方便地获取SQL的执行结果才是MyBatis的核心竞争力。

Mybatis的功能架构分为三层

  • API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
  • 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作
  • 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

更多介绍可以参考:MyBatis3 官方网站

1.2、为什么说MyBatis是半自动ORM?

为什么说MyBatis是半自动ORM?

  • 什么是ORM

JDBC,ORM知识点可以参考SpringBoot第6讲:SpringBoot入门 - 添加内存数据库H2

  • 什么是全自动ORM

ORM框架可以根据对象关系模型直接获取,查询关联对象或者关联集合对象,简单而言使用全自动的ORM框架查询时可以不再写SQL。典型的框架如Hibernate; 因为Spring-data-jpa很多代码也是Hibernate团队贡献的,所以spring-data-jpa也是全自动ORM框架。

  • MyBatis是半自动ORM

Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动ORM 映射工具。

(PS: 正是由于MyBatis是半自动框架,基于MyBatis技术栈的框架开始考虑兼容MyBatis开发框架的基础上提供自动化的能力,比如MyBatis-plus等框架)

1.3、MyBatis栈技术演进

了解MyBatis技术栈的演进,对你构建基于MyBatis的知识体系极为重要。

1、JDBC,自行封装 JDBCUtil

Java5的时代,通常的开发中会自行封装JDBC的Util,比如创建 Connection,以及确保关闭 Connection等。

2、IBatis

MyBatis的前身,它封装了绝大多数的 JDBC 样板代码,使得开发者只需关注 SQL 本身,而不需要花费精力去处理例如注册驱动,创建 Connection,以及确保关闭 Connection 这样繁杂的代码。

3、MyBatis(目前我们项目处于这个阶段)

伴随着JDK5+ 泛型和注解特性开始流行,IBatis在3.0变更为MyBatis,对泛型和注解等特性开始全面支持,同时支持了很多新的特性,比如:

  1. MyBatis实现了接口绑定,通过Dao接口和xml映射文件的绑定,自动生成接口的具体实现
  2. MyBatis支持 ognl表达式,比如 <if>, <else>使用ognl进行解析
  3. MyBatis插件机制等,(PageHelper分页插件应用而生,解决了数据库层的分页封装问题)

所以这个时期,MyBatis XML 配置方式 + PageHelper 成为重要的开发方式。

4、MyBatis衍生:代码生成工具等

MyBatis提供了开发上的便捷,但是依然需要写大量的xml配置,并且很多都是CRUD级别的(这便有了很多重复性的工作),所以为了减少重复编码,衍生出了MyBatis代码生成工具, 比如 CodeGenerator 等。

其它开发IDE也开始出现封装一些工具和插件来生成代码生成工具等。

由于后端视图解析引擎多样性(比如freemarker, volicty, thymeleaf等),以及前后端分离前端独立等,为了进一步减少重复代码的编写(包括视图层),自动生成的代码工具也开始演化为自动生成前端视图代码。

5、Spring+MyBatis 基于注解的配置集成

与此同时,Spring 2.5 开始完全支持基于注解的配置并且也支持JSR250 注解。在Spring后续的版本发展倾向于通过注解和Java配置结合使用。基于Spring+MyBatis开发技术栈开始有xml配置方式往注解和java配置方式反向发展

Spring Boot的出现便是要解决配置过多的问题,它实际上通过约定大于配置的方式大大简化了用户的配置,对于三方组件使用xx-starter统一的对Bean进行默认初始化,用户只需要很少的配置就可以进行开发了。所以出现了mybatis-spring-boot-starter的封装等。

这个阶段,主要的开发技术栈是 Spring + mybatis-spring-boot-starter 自动化配置 + PageHelper,并且很多数据库实体mapper还是通过xml方式配置的(伴随着使用一些自动化生成工具)。

6、MyBatis-Plus

为了更高的效率,出现了MyBatis-Plus这类工具,对MyBatis进行增强。

  1. 考虑到MyBatis是半自动化ORM,MyBatis-Plus 启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作; 并且内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求;总体上让其支持全自动化的使用方式(本质上借鉴了Hibernate思路)。
  2. 考虑到Java8 Lambda(函数式编程)开始流行,MyBatis-Plus支持 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  3. 考虑到MyBatis还需要独立引入PageHelper分页插件,MyBatis-Plus支持了内置分页插件,同PageHelper一样基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  4. 考虑到自动化代码生成方式,MyBatis-Plus也支持了内置代码生成器,采用代码或者 Maven 插件可快速生成 Mapper 、Model 、Service 、Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  5. 考虑到SQL性能优化等问题,MyBatis-Plus内置性能分析插件, 可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  6. 其它还有解决一些常见开发问题,比如支持主键自动生成,支持4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题;以及内置全局拦截插件,提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

顶层思维能力

用这种思路去理解,你便能很快了解MyBatis技术栈的演化(能够快速维护老一些的技术框架),以及理解新的中小项目中MyBatis-Plus被大量使用的原因(新项目的技术选型参考);所以java全栈知识体系的目标是帮助你构建知识体系,甚至是辅助你培养顶层思维能力。

2、简单示例

尽管MyBatis-Plus大行其道,MyBatis XML 配置方式 + PageHelper依然是基础使用方式。本例依然向你展示MyBatis XML 配置方式,考虑到和spring-data-jpa方式对比,这里沿用上一篇文章的数据库。后续的案例中将具体介绍MyBatis分页,以及MyBatis-Plus的使用等。

2.1、准备DB和依赖配置

创建MySQL的schema test_db, 导入SQL 文件如下

-- MySQL dump 10.13  Distrib 5.7.12, for Win64 (x86_64)
--
-- Host: localhost    Database: test_db
-- ------------------------------------------------------
-- Server version	5.7.17-log/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;--
-- Table structure for table `tb_role`
--DROP TABLE IF EXISTS `tb_role`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tb_role` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) NOT NULL,`role_key` varchar(255) NOT NULL,`description` varchar(255) DEFAULT NULL,`create_time` datetime DEFAULT NULL,`update_time` datetime DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;--
-- Dumping data for table `tb_role`
--LOCK TABLES `tb_role` WRITE;
/*!40000 ALTER TABLE `tb_role` DISABLE KEYS */;
INSERT INTO `tb_role` VALUES (1,'admin','admin','admin','2021-09-08 17:09:15','2021-09-08 17:09:15');
/*!40000 ALTER TABLE `tb_role` ENABLE KEYS */;
UNLOCK TABLES;--
-- Table structure for table `tb_user`
--DROP TABLE IF EXISTS `tb_user`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tb_user` (`id` int(11) NOT NULL AUTO_INCREMENT,`user_name` varchar(45) NOT NULL,`password` varchar(45) NOT NULL,`email` varchar(45) DEFAULT NULL,`phone_number` int(11) DEFAULT NULL,`description` varchar(255) DEFAULT NULL,`create_time` datetime DEFAULT NULL,`update_time` datetime DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;--
-- Dumping data for table `tb_user`
--LOCK TABLES `tb_user` WRITE;
/*!40000 ALTER TABLE `tb_user` DISABLE KEYS */;
INSERT INTO `tb_user` VALUES (1,'pdai','dfasdf','suzhou.daipeng@gmail.com',1212121213,'afsdfsaf','2021-09-08 17:09:15','2021-09-08 17:09:15');
/*!40000 ALTER TABLE `tb_user` ENABLE KEYS */;
UNLOCK TABLES;--
-- Table structure for table `tb_user_role`
--DROP TABLE IF EXISTS `tb_user_role`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tb_user_role` (`user_id` int(11) NOT NULL,`role_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;--
-- Dumping data for table `tb_user_role`
--LOCK TABLES `tb_user_role` WRITE;
/*!40000 ALTER TABLE `tb_user_role` DISABLE KEYS */;
INSERT INTO `tb_user_role` VALUES (1,1);
/*!40000 ALTER TABLE `tb_user_role` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;-- Dump completed on 2021-09-08 17:12:11

引入maven依赖

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version>
</dependency>
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.0</version>
</dependency>
<!--pagehelper分页 -->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.2.10</version>
</dependency>

增加yml配置

  • 在代码中没有找到
spring:datasource:url: jdbc:mysql://localhost:3306/test_db?useSSL=false&autoReconnect=true&characterEncoding=utf8driver-class-name: com.mysql.jdbc.Driverusername: rootpassword: adminmybatis:# Mapper 所对应的 XML 文件位置mapper-locations: classpath:mybatis/mapper/*.xml# 实体类根路径type-aliases-package: springboot.mysq.xml.entityconfiguration:# 开启二级缓存cache-enabled: trueuse-generated-keys: truedefault-executor-type: REUSEuse-actual-param-name: true

classpath:mybatis/mapper/*.xml 是mapper的位置。

2.2、Mapper文件

mapper 文件定义在配置的路径中(classpath:mybatis/mapper/*.xml

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="springboot.mysql.mybatis.dao.IUserDao"><resultMap type="springboot.mysql.mybatis.entity.User" id="UserResult"><id     property="id"       	column="id"      		/><result property="userName"     column="user_name"    	/><result property="password"     column="password"    	/><result property="email"        column="email"        	/><result property="phoneNumber"  column="phone_number"  	/><result property="description"  column="description"  	/><result property="createTime"   column="create_time"  	/><result property="updateTime"   column="update_time"  	/><collection property="roles" ofType="springboot.mysql.mybatis.entity.Role"><result property="id" column="rid"  /><result property="name" column="rname"  /><result property="roleKey" column="role_key"  /><result property="description" column="rdescription"  /><result property="createTime"   column="rcreate_time"  	/><result property="updateTime"   column="rupdate_time"  	/></collection></resultMap><sql id="selectUserSql">select u.id, u.password, u.user_name, u.email, u.phone_number, u.description, u.create_time, u.update_time, r.id rid, r.name rname, r.role_key, r.description rdescription, r.create_time rcreate_time, r.update_time rupdate_timefrom tb_user uleft join tb_user_role ur on u.id=ur.user_idinner join tb_role r on ur.role_id=r.id</sql><select id="findList" parameterType="springboot.mysql.mybatis.entity.query.UserQueryBean" resultMap="UserResult"><include refid="selectUserSql"/>where u.id != 0<if test="userName != null and userName != ''">AND u.user_name like concat('%', #{user_name}, '%')</if><if test="description != null and description != ''">AND u.description like concat('%', #{description}, '%')</if><if test="phoneNumber != null and phoneNumber != ''">AND u.phone_number like concat('%', #{phoneNumber}, '%')</if><if test="email != null and email != ''">AND u.email like concat('%', #{email}, '%')</if></select><select id="findById" parameterType="Long" resultMap="UserResult"><include refid="selectUserSql"/>where u.id = #{id}</select><delete id="deleteById" parameterType="Long">delete from tb_user where id = #{id}</delete><delete id="deleteByIds" parameterType="Long">delete from tb_user where id in<foreach collection="array" item="id" open="(" separator="," close=")">#{id}</foreach> </delete><update id="update" parameterType="springboot.mysql.mybatis.entity.User">update tb_user<set><if test="userName != null and userName != ''">user_name = #{userName},</if><if test="email != null and email != ''">email = #{email},</if><if test="phoneNumber != null and phoneNumber != ''">phone_number = #{phoneNumber},</if><if test="description != null and description != ''">description = #{description},</if>update_time = sysdate()</set>where id = #{id}</update><update id="updatePassword" parameterType="springboot.mysql.mybatis.entity.User">update tb_user<set>password = #{password}, update_time = sysdate()</set>where id = #{id}</update><insert id="save" parameterType="springboot.mysql.mybatis.entity.User" useGeneratedKeys="true" keyProperty="id">insert into tb_user(<if test="userName != null and userName != ''">user_name,</if><if test="password != null and password != ''">password,</if><if test="email != null and email != ''">email,</if><if test="phoneNumber != null and phoneNumber != ''">phone_number,</if><if test="description != null and description != ''">description,</if>create_time,update_time)values(<if test="userName != null and userName != ''">#{userName},</if><if test="password != null and password != ''">#{password},</if><if test="email != null and email != ''">#{email},</if><if test="phoneNumber != null and phoneNumber != ''">#{phoneNumber},</if><if test="description != null and description != ''">#{description},</if>sysdate(),sysdate())</insert>
</mapper> 

RoleMapper.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="springboot.mysql.mybatis.dao.IRoleDao"><resultMap type="springboot.mysql.mybatis.entity.Role" id="RoleResult"><id     property="id"       	column="id"      		/><result property="name" 		column="name"  /><result property="roleKey" 		column="role_key"  /><result property="description" 	column="description"  /><result property="createTime"   column="create_time"  	/><result property="updateTime"   column="update_time"  	/></resultMap><sql id="selectRoleSql">select  r.id, r.name, r.role_key, r.description, r.create_time, r.update_timefrom tb_role r</sql><select id="findList" parameterType="springboot.mysql.mybatis.entity.query.RoleQueryBean" resultMap="RoleResult"><include refid="selectRoleSql"/>where r.id != 0<if test="name != null and name != ''">AND r.name like concat('%', #{name}, '%')</if><if test="roleKey != null and roleKey != ''">AND r.role_key = #{roleKey}</if><if test="description != null and description != ''">AND r.description like concat('%', #{description}, '%')</if></select>
</mapper> 

2.3、定义dao

与Mapper文件中方法对应

UserDao

import java.util.List;
import springboot.mysql.mybatis.entity.User;
import springboot.mysql.mybatis.entity.query.UserQueryBean;/*** @author qiwenjie*/
public interface IUserService {List<User> findList(UserQueryBean userQueryBean);User findById(Long id);int deleteById(Long id);int deleteByIds(Long[] ids);int update(User user);int save(User user);int updatePassword(User user);
}

RoleDao

import java.util.List;
import springboot.mysql.mybatis.entity.Role;
import springboot.mysql.mybatis.entity.query.RoleQueryBean;public interface IRoleService {List<Role> findList(RoleQueryBean roleQueryBean);
}

2.4、定义Service接口和实现类

UserService接口

import java.util.List;
import springboot.mysql.mybatis.entity.User;
import springboot.mysql.mybatis.entity.query.UserQueryBean;/*** @author qiwenjie*/
public interface IUserService {List<User> findList(UserQueryBean userQueryBean);User findById(Long id);int deleteById(Long id);int deleteByIds(Long[] ids);int update(User user);int save(User user);int updatePassword(User user);
}

User Service的实现类

import java.util.List;
import org.springframework.stereotype.Service;
import springboot.mysql.mybatis.dao.IUserDao;
import springboot.mysql.mybatis.entity.User;
import springboot.mysql.mybatis.entity.query.UserQueryBean;
import springboot.mysql.mybatis.service.IUserService;@Service
public class UserDoServiceImpl implements IUserService {/*** userDao.*/private final IUserDao userDao;/*** init.** @param userDao2 user dao*/public UserDoServiceImpl(final IUserDao userDao2) {this.userDao = userDao2;}@Overridepublic List<User> findList(UserQueryBean userQueryBean) {return userDao.findList(userQueryBean);}@Overridepublic User findById(Long id) {return userDao.findById(id);}@Overridepublic int deleteById(Long id) {return userDao.deleteById(id);}@Overridepublic int deleteByIds(Long[] ids) {return userDao.deleteByIds(ids);}@Overridepublic int update(User user) {return userDao.update(user);}@Overridepublic int save(User user) {return userDao.save(user);}@Overridepublic int updatePassword(User user) {return userDao.updatePassword(user);}
}

Role Service 接口

import java.util.List;
import springboot.mysql.mybatis.entity.Role;
import springboot.mysql.mybatis.entity.query.RoleQueryBean;public interface IRoleService {List<Role> findList(RoleQueryBean roleQueryBean);
}

Role Service 实现类

import java.util.List;
import org.springframework.stereotype.Service;
import springboot.mysql.mybatis.service.IRoleService;
import springboot.mysql.mybatis.dao.IRoleDao;
import springboot.mysql.mybatis.entity.Role;
import springboot.mysql.mybatis.entity.query.RoleQueryBean;@Service
public class RoleDoServiceImpl implements IRoleService {/*** roleDao.*/private final IRoleDao roleDao;/*** init.** @param roleDao2 role dao*/public RoleDoServiceImpl(final IRoleDao roleDao2) {this.roleDao = roleDao2;}@Overridepublic List<Role> findList(RoleQueryBean roleQueryBean) {return roleDao.findList(roleQueryBean);}
}

2.5、controller

User Controller

import java.time.LocalDateTime;
import java.util.List;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springboot.mysql.mybatis.entity.User;
import springboot.mysql.mybatis.entity.query.UserQueryBean;
import springboot.mysql.mybatis.entity.response.ResponseResult;
import springboot.mysql.mybatis.service.IUserService;/*** @author qiwenjie*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate IUserService userService;/*** @param user user param* @return user*/@ApiOperation("Add/Edit User")@PostMapping("add")public ResponseResult<User> add(User user) {if (user.getId()==null) {user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userService.save(user);} else {user.setUpdateTime(LocalDateTime.now());userService.update(user);}return ResponseResult.success(userService.findById(user.getId()));}/*** @return user list*/@ApiOperation("Query User One")@GetMapping("edit/{userId}")public ResponseResult<User> edit(@PathVariable("userId") Long userId) {return ResponseResult.success(userService.findById(userId));}/*** @return user list*/@ApiOperation("Query User List")@GetMapping("list")public ResponseResult<List<User>> list(UserQueryBean userQueryBean) {return ResponseResult.success(userService.findList(userQueryBean));}
}

Role Controller

import java.util.List;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springboot.mysql.mybatis.entity.Role;
import springboot.mysql.mybatis.entity.query.RoleQueryBean;
import springboot.mysql.mybatis.entity.response.ResponseResult;
import springboot.mysql.mybatis.service.IRoleService;/*** @author qiwenjie*/
@RestController
@RequestMapping("/role")
public class RoleController {@Autowiredprivate IRoleService roleService;/*** @return user list*/@ApiOperation("Query Role List")@GetMapping("list")public ResponseResult<List<Role>> list(RoleQueryBean roleQueryBean) {return ResponseResult.success(roleService.findList(roleQueryBean));}
}

3、示例源码

完整示例可以看github源码

todo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14326.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安全学习DAY10_HTTP数据包

HTTP数据包 文章目录 HTTP数据包小节导图Request请求数据包结构Request请求方法&#xff08;方式&#xff09;请求头&#xff08;Header&#xff09;Response响应数据包结构Response响应数据包状态码状态码作用&#xff1a;部分状态码详解判断网站文件是否存在的状态码&#xf…

配置代理——解决跨域问题(详解)

之前写项目的时候总会遇到配置代理的问题&#xff0c;可是配置了之后有时有用&#xff0c;有时就没有用&#xff0c;自己之前学的也是懵懵懂懂&#xff0c;于是专门花了一个小时去了解了如何配置代理跨域&#xff0c;然后在此记录一下&#xff0c;方便自己以后查阅。 一、 常用…

vuex 同步数据和异步数据 存储 和 调用

同步存储 调用 要向 Vuex 中存储同步数据&#xff0c;你可以通过定义一个 mutation 来修改 state 中的数据。下面是一个简单的示例&#xff1a; 首先&#xff0c;在你的 Vuex 模块中定义一个 state 和一个 mutation&#xff1a; // store.jsimport Vue from vue; import Vuex …

RBF神经网络原理和matlab实现

1.案例背景 1.1 RBF神经网络概述 径向基函数(Radical Basis Function,RBF)是多维空间插值的传统技术,由Powell于1985年提出。1988年, Broomhead和 Lowe根据生物神经元具有局部响应这一特点,将 RBF引入神经网络设计中,产生了RBF神经网络。1989 年&#xff0c;Jackson论证了…

应用层协议——https

文章目录 1. HTTPS 是什么2. 什么是"加密"3. 常见的加密方式4. 数据摘要 && 数字签名5. HTTPS 的工作过程探究5.1 方案1 - 只使用对称加密5.2 方案2 - 只使用非对称加密5.3 方案3 - 双方都使用非对称加密5.4 方案4 - 非对称加密 对称加密5.5 中间人攻击5.6 …

【深度学习】InST,Inversion-Based Style Transfer with Diffusion Models,论文

代码&#xff1a;https://github.com/zyxElsa/InST 论文&#xff1a;https://arxiv.org/abs/2211.13203 文章目录 AbstractIntroductionRelated WorkImage style transferText-to-image synthesisInversion of diffusion models MethodOverview ExperimentsComparison with Sty…

C++ 多进程学习总结

C多进程 进程间通信 消息队列 消息队列&#xff1a;提供一个种进程间发送/接收数据块&#xff08;常为结构体数据&#xff09;的方法。 函数接口 ftok()&#xff1a;获取消息队列键值msgget()&#xff1a;创建和访问消息队列msgsnd()&#xff1a;向消息队列发送数据msgrcv…

VSCode配置之C++ SQLite3极简配置方案

背景 最近在学习《深入应用C11: 代码优化与工程级应用》&#xff0c;其中第13章说到SQLite库&#xff0c;查询网上诸多教程&#xff0c;发现比较容易出现bug且配置较为麻烦&#xff0c;故记录此次简化版方案&#xff0c;以供参考。 软件环境 SQLite 3.42.0 版本&#xff08;仅…

[SQL挖掘机] - 窗口函数 - rank

介绍: rank() 是一种常用的窗口函数&#xff0c;它为结果集中的每一行分配一个排名&#xff08;rank&#xff09;。这个排名基于指定的排序顺序&#xff0c;并且在遇到相同的值时&#xff0c;会跳过相同的排名。 用法: rank() 函数的语法如下&#xff1a; rank() over ([pa…

Python 进阶(五):os 模块

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录 1. 文件和目录的基本操作1.1 获取当前工作目录1.2 更改当前工作目录1.3 获取目录下所有…

ffmpeg批量分割视频解决视频前几秒黑屏的问题解决

echo 请输入视频地址&#xff1a; set /p fp echo 请输入开始时间&#xff1a; set /p st echo 请输入结束时间&#xff1a; set /p et echo 请输入分片时间&#xff1a; set /p sgt echo 注意&#xff1a;循环范围参数要空格。 for /l %%i in (%st%, %sgt%, %et%) do call :aa…

redis启动失败,oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo

在redis文件夹下&#xff0c;启动redis正常。 但是加入到system后启动redis失败。 一直处于starting状态。 对比正常redis服务的配置之后&#xff0c;把redis.conf里的守护进程关掉就可以了&#xff08;但是没用system管理之前&#xff0c;直接./redis.server启动是可以的&…

MongoDB 的增、查、改、删

Monogo使用 增 单条增加 db.member.insertOne({"name":"张三","age":18,"create":new Date()}) db.member.insert({"name":"李四1","age":18,"create":new Date()}) db.member.insertOne(…

35.图片幻灯片

图片幻灯片 html部分 <div class"carousel"><div class"image-container"><img src"./static/20180529205331_yhGyf.jpeg" alt"" srcset""><img src"./static/20190214214253_hsjqw.webp"…

Python网络编程详解:Socket套接字的使用与开发

Python网络编程详解&#xff1a;Socket套接字的使用与开发 1. 引言 网络编程是现代应用开发中不可或缺的一部分。通过网络编程&#xff0c;我们可以实现不同设备之间的通信和数据交换&#xff0c;为用户提供更加丰富的服务和体验。Python作为一种简洁而强大的编程语言&#x…

Java 模块化Modularity- 了解与测试

1. java9后JDK后目录的变化 不见了jre,新增了jmods目录。 1&#xff09;为什么不见了jre&#xff1f; 新版JDK提供了 jlink工具&#xff0c;使用它构建一个包含jre镜像的应用程序。 就是可以打包一个引用程序内部已经包含完整或部分jre&#xff0c;可以直接运行。 2&#xf…

MP的开发流程

MP的开发流程 1、添加依赖 <?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.ap…

【李宏毅 DLHLP 深度学习人类语言处理 HW1】

李宏毅 DLHLP 深度学习人类语言处理 HW1 相关资料HW1更多尝试1, 加深encoder:4层LSTM2, 加深encoder(4层LSTM)和加深decoder(2层LSTM)3, cnn代替vgg4, 再次加深decoder(4层LSTM) 语音小白在网上没有找到这门课的作业分享&#xff0c;那就记录一下自己的作业吧。 相关资料 课程…

4. 深度生成模型-扩散模型(基于扩散的生成模型与分数匹配的变分视角)

“基于扩散的生成模型”与“分数匹配”的变分视角 1. 介绍1.1. 变分自动编码器1.2. 基于扩散的建模1.3. 主要内容2. 基于得分的随机微分方程生成建模基于离散时间扩散的生成模型和分数匹配方法在高维图像数据建模方面显示出了良好的效果。 最近,Song等人(2021)表明,通过学…

基于SpringBoot+Vue的学习平台设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…