当前位置: 首页 > news >正文

MyBatis与MyBatis-Plus(基础)

MyBatis-Plus的优势

在 Spring Data JPA 已经很方便的情况下,有时仍然选择使用 MyBatis-Plus 的核心原因主要有以下三点:

1. 复杂 SQL 控制能力更强

  • MyBatis-Plus 允许直接编写和优化 SQL,适合复杂查询、精细化 SQL 控制的场景。特别是在性能要求高的应用中,通过手写 SQL 可以确保更高的查询效率。
  • Spring Data JPA 自动生成的 SQL 对于简单 CRUD 很方便,但在复杂 SQL(如多表关联查询、子查询等)场景中,性能和灵活性上不如 MyBatis-Plus。

2. 动态 SQL 支持强大

  • MyBatis-Plus 提供了 Wrapper 条件构造器,灵活构建动态查询条件,适合复杂的业务逻辑(如根据用户输入动态构建查询条件)。
  • Spring Data JPA 尽管支持 @QuerySpecifications,但在动态 SQL 构建上不如 MyBatis-Plus 简洁易用。

3. 高效代码生成,适合大规模表操作

  • MyBatis-Plus 自带代码生成器,能快速生成实体、Mapper、Service 等基础代码,减少样板代码的编写。
  • Spring Data JPA 没有代码生成器,需要手动创建实体和 Repository 接口,在操作大量表时,MyBatis-Plus 的代码生成器能显著提高开发效率。

1. MyBatis 基础

1.1 MyBatis 配置与集成

在 Spring Boot 中集成 MyBatis,首先需要引入 MyBatis 依赖并配置数据库连接等基础信息。

1.1.1 引入 MyBatis 依赖

pom.xml 中添加 MyBatis 相关依赖。Spring Boot 提供了 mybatis-spring-boot-starter,使 MyBatis 与 Spring Boot 无缝集成。

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version> <!-- 使用最新版本 -->
</dependency>
1.1.2 配置数据库连接

application.yml(或 application.properties)中配置数据库连接信息。以 MySQL 为例:

spring:datasource:url: jdbc:mysql://localhost:3306/mydbusername: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driver

这部分配置告诉 Spring Boot 如何连接到数据库,并为 MyBatis 提供必要的连接信息。

1.1.3 配置 MyBatis 扫描路径

MyBatis 需要知道 Mapper 接口和 XML 映射文件的位置。可以在 application.yml 中配置 mapper-locationstype-aliases-package

mybatis:mapper-locations: classpath*:mapper/*.xmltype-aliases-package: com.example.demo.model  # 实体类包路径
  • mapper-locations:指定 MyBatis XML 映射文件的位置(在 resources/mapper 目录下)。
  • type-aliases-package:指定实体类所在的包路径,MyBatis 会自动为该包中的实体类创建别名。
1.1.4 启动类中配置 @MapperScan

在 Spring Boot 启动类中,使用 @MapperScan 指定 MyBatis Mapper 接口所在的包路径,这样 MyBatis 才能自动扫描并加载这些接口。

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.example.demo.mapper")  // Mapper 接口的包路径
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

这样,Spring Boot 项目就成功集成了 MyBatis,可以开始使用 MyBatis 的功能了。


1.2 Mapper 映射

MyBatis 使用 Mapper 接口与 XML 映射文件结合的方式来完成数据库操作。通过这种映射方式,可以将 Java 方法与 SQL 语句对应起来。

1.2.1 创建 Mapper 接口

com.example.demo.mapper 包中创建一个 Mapper 接口,定义数据库操作方法。例如,定义 UserMapper 接口:

package com.example.demo.mapper;import com.example.demo.model.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;@Mapper
public interface UserMapper {User selectUserById(Long id);List<User> selectAllUsers();int insertUser(User user);int updateUser(User user);int deleteUserById(Long id);
}
  • Mapper 接口:定义数据库操作方法。Spring Boot 会自动扫描带有 @Mapper 注解的接口,将它们注册为 MyBatis Mapper。
1.2.2 创建 XML 映射文件

resources/mapper 目录下创建一个与 UserMapper 对应的 XML 文件 UserMapper.xml,在其中编写具体的 SQL 语句。

<?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"><select id="selectUserById" resultType="com.example.demo.model.User">SELECT * FROM users WHERE id = #{id}</select><select id="selectAllUsers" resultType="com.example.demo.model.User">SELECT * FROM users</select><insert id="insertUser" parameterType="com.example.demo.model.User">INSERT INTO users (name, email)VALUES (#{name}, #{email})</insert><update id="updateUser" parameterType="com.example.demo.model.User">UPDATE usersSET name = #{name}, email = #{email}WHERE id = #{id}</update><delete id="deleteUserById" parameterType="Long">DELETE FROM users WHERE id = #{id}</delete></mapper>
  • namespace:指定 XML 文件对应的 Mapper 接口的完全限定名。
  • id:对应 Mapper 接口中的方法名。
  • parameterTyperesultType:分别表示传入参数的类型和返回值的类型。

以上代码展示了如何使用 XML 映射文件实现基本的 CRUD 操作。


1.3 动态 SQL

MyBatis 提供了动态 SQL 标签,可以根据传入的参数生成不同的 SQL 语句。常用的动态 SQL 标签包括 <if><choose><when><otherwise><foreach>

1.3.1 <if> 标签

<if> 标签根据条件判断是否生成相应的 SQL 片段,适用于可选查询条件。

<select id="selectUsersByName" resultType="com.example.demo.model.User">SELECT * FROM usersWHERE 1=1<if test="name != null">AND name = #{name}</if>
</select>
  • test:判断条件,当 name 不为 null 时,会生成 AND name = #{name}
1.3.2 <choose><when><otherwise> 标签

类似于 if...else if...else 的结构。<choose> 包含多个 <when> 和一个 <otherwise>,用于条件分支选择。

<select id="selectUsers" resultType="com.example.demo.model.User">SELECT * FROM users<choose><when test="name != null">WHERE name = #{name}</when><when test="email != null">WHERE email = #{email}</when><otherwise>WHERE status = 'active'</otherwise></choose>
</select>
  • name 不为空时,生成 WHERE name = #{name}
  • 如果 email 不为空且 name 为空,则生成 WHERE email = #{email}
  • 否则,生成 WHERE status = 'active'
1.3.3 <foreach> 标签

<foreach> 标签用于循环生成 SQL,常用于 IN 查询。<foreach> 可以将集合中的元素逐一添加到 SQL 中。

<select id="selectUsersByIds" resultType="com.example.demo.model.User">SELECT * FROM usersWHERE id IN<foreach item="id" collection="idList" open="(" separator="," close=")">#{id}</foreach>
</select>
  • collection:指定参数的集合名。
  • item:指定集合中每个元素的名称。
  • openseparatorclose**:分别指定起始符、分隔符和结束符。

idList 传入 [1, 2, 3] 时,生成的 SQL 为:WHERE id IN (1, 2, 3)

2. MyBatis-Plus 基础

2.1 MyBatis-Plus 配置与集成

在 Spring Boot 项目中集成 MyBatis-Plus 是第一步,通常包括引入依赖、配置数据源以及扫描路径等基础配置。

2.1.1 引入 MyBatis-Plus 依赖

pom.xml 中添加 MyBatis-Plus 的依赖,通常还需要 MyBatis 和 MySQL 的驱动依赖:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.0</version> <!-- 使用最新稳定版本 -->
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version>
</dependency>
2.1.2 配置数据库连接

application.yml(或 application.properties)中配置数据库连接信息。以 MySQL 为例:

spring:datasource:url: jdbc:mysql://localhost:3306/mydbusername: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driver
2.1.3 启动类配置 @MapperScan

在 Spring Boot 启动类中使用 @MapperScan 注解,指定 MyBatis-Plus Mapper 接口的扫描路径:

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.example.demo.mapper") // Mapper 接口的包路径
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

完成这些步骤后,Spring Boot 项目便成功集成了 MyBatis-Plus,可以开始使用它的增强功能。


2.2 BaseMapper 基础 CRUD 操作

MyBatis-Plus 提供了 BaseMapper 接口,封装了常用的 CRUD 操作。只需继承 BaseMapper,即可获得基本的数据库操作方法,而不需要编写复杂的 SQL 语句。

2.2.1 创建实体类

com.example.demo.model 包中创建实体类 User,并使用 @TableId 指定主键:

package com.example.demo.model;import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.IdType;
import lombok.Data;@Data
public class User {@TableId(type = IdType.AUTO) // 自增主键private Long id;private String name;private String email;
}
2.2.2 创建 Mapper 接口

com.example.demo.mapper 包中创建 UserMapper 接口,继承 BaseMapper<User> 即可:

package com.example.demo.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper extends BaseMapper<User> {
}

BaseMapper 提供的常用方法有:

  • selectById(id):根据主键查询。
  • selectList(null):查询所有记录。
  • insert(entity):插入新记录。
  • updateById(entity):根据主键更新。
  • deleteById(id):根据主键删除。
2.2.3 使用示例

在 Service 或 Controller 中可以直接注入 UserMapper,并调用这些方法:

import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public User getUserById(Long id) {return userMapper.selectById(id);}public List<User> getAllUsers() {return userMapper.selectList(null);}public void addUser(User user) {userMapper.insert(user);}public void updateUser(User user) {userMapper.updateById(user);}public void deleteUser(Long id) {userMapper.deleteById(id);}
}

通过继承 BaseMapper,实现了基本的 CRUD 操作,大大简化了数据库操作。


2.3 分页查询

MyBatis-Plus 提供了分页功能,可以使用 Page 对象直接实现分页查询。

2.3.1 引入分页插件

在 Spring Boot 中需要配置分页插件,通常在配置类中添加 PaginationInterceptor

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyBatisPlusConfig {@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}
}
2.3.2 使用 Page 对象进行分页查询

在 Service 中可以通过 Page 对象传递分页参数,进行分页查询:

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public Page<User> getUsersPage(int page, int size) {Page<User> userPage = new Page<>(page, size);return userMapper.selectPage(userPage, null);}
}
  • Page<User> userPage = new Page<>(page, size);:指定当前页和每页的记录数。
  • userMapper.selectPage(userPage, null);:执行分页查询,其中 null 表示没有额外的查询条件。

分页查询结果包含分页信息和数据列表,可以直接返回给前端。


2.4 Wrapper 条件构造器

MyBatis-Plus 提供了 Wrapper 条件构造器,用于灵活构建查询条件,常用的构造器包括 QueryWrapperUpdateWrapper 等。

2.4.1 使用 QueryWrapper 进行条件查询

QueryWrapper 用于构建查询条件,例如条件查询、模糊查询、排序等:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<User> getUsersByName(String name) {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", name); // 相当于 WHERE name = #{name}return userMapper.selectList(queryWrapper);}
}
  • eq("name", name):等于条件,生成 WHERE name = #{name}
  • QueryWrapper 支持链式调用,可以组合多个条件。
2.4.2 使用 UpdateWrapper 进行条件更新

UpdateWrapper 用于构建更新条件,例如更新指定条件的记录:

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public void updateUserEmail(Long id, String email) {UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("id", id); // 更新条件 WHERE id = #{id}User user = new User();user.setEmail(email);userMapper.update(user, updateWrapper);}
}
  • eq("id", id):等于条件,生成 WHERE id = #{id}
  • userMapper.update(user, updateWrapper):根据 UpdateWrapper 条件更新记录。
常用的 Wrapper 方法
  • eq:等于。
  • ne:不等于。
  • like:模糊查询。
  • gt / lt:大于 / 小于。
  • orderByDesc:降序排序。
  • between:区间查询。

3. 必备注解与功能

3.1 @TableId 和 @IdType:定义主键与生成策略

在 MyBatis-Plus 中,@TableId 注解用于指定数据库表的主键字段,而 @IdType 则用于设置主键的生成策略。

3.1.1 @TableId 注解

@TableId 注解用于标识实体类中的主键字段。使用 @TableId 可以指定主键字段的名称和生成策略。

示例

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.IdType;
import lombok.Data;@Data
public class User {@TableId(type = IdType.AUTO) // 主键生成策略为自增private Long id;private String name;private String email;
}
  • 属性
    • value:指定主键字段对应的数据库列名(默认与字段名相同)。
    • type:指定主键生成策略(使用 @IdType 枚举)。
3.1.2 @IdType:主键生成策略

MyBatis-Plus 提供了多种主键生成策略,可以通过 @IdType 设置主键生成策略。常用的生成策略有:

  • IdType.AUTO:自增主键,通常依赖数据库自增机制(适用于 MySQL 等支持自增的数据库)。
  • IdType.INPUT:手动输入,必须在插入数据前手动设置主键值。
  • IdType.UUID:全局唯一的 UUID。
  • IdType.ASSIGN_ID:雪花算法生成的唯一 ID(适用于分布式场景)。

示例

@TableId(type = IdType.AUTO)      // 数据库自增主键
@TableId(type = IdType.UUID)      // UUID 作为主键
@TableId(type = IdType.ASSIGN_ID) // 使用雪花算法生成唯一 ID

选择合适的主键生成策略可以有效减少主键冲突,尤其是在分布式环境下。


3.2 @TableLogic(逻辑删除)

@TableLogic 注解用于实现逻辑删除,逻辑删除并不会物理删除记录,而是将记录标记为删除状态。MyBatis-Plus 会根据 @TableLogic 的配置自动过滤被逻辑删除的数据。

3.2.1 使用逻辑删除注解

在实体类的逻辑删除字段上添加 @TableLogic 注解,可以实现逻辑删除功能。

示例

import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;@Data
public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private String email;@TableLogicprivate Integer deleted; // 逻辑删除标识字段:0 - 未删除,1 - 已删除
}
  • deleted 字段被 @TableLogic 注解标记后,在执行删除操作时,MyBatis-Plus 不会物理删除数据,而是将 deleted 字段的值更新为 1。
  • 通常使用 Integer 类型字段来表示删除状态,0 表示未删除,1 表示已删除。
3.2.2 配置逻辑删除值

可以在 application.yml 中配置逻辑删除值,指定删除和未删除的状态:

mybatis-plus:global-config:db-config:logic-delete-value: 1    # 删除状态logic-not-delete-value: 0 # 未删除状态

配置好后,MyBatis-Plus 会自动处理逻辑删除的数据查询和删除。例如,以下代码将只查询未删除的数据:

public List<User> getAllActiveUsers() {return userMapper.selectList(null); // 只会查询 deleted 为 0 的记录
}

使用逻辑删除的好处

  • 逻辑删除避免了物理删除带来的数据丢失,保留历史数据。
  • 在数据恢复、日志审计等场景下更为方便。

3.3 乐观锁(@Version)

在并发环境下,乐观锁可以确保数据的一致性。@Version 注解用于启用乐观锁机制,MyBatis-Plus 会在更新数据时自动检查 @Version 字段,只有在没有其他线程修改该数据的情况下,才会执行更新操作。

3.3.1 使用乐观锁注解

在实体类中添加一个版本号字段,并在字段上添加 @Version 注解。每次更新时,MyBatis-Plus 会检查版本号是否一致,确保数据安全。

示例

import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;@Data
public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private String email;@Versionprivate Integer version; // 乐观锁版本号字段
}
  • 版本号字段通常使用 IntegerLong 类型,每次更新时版本号自动递增。
3.3.2 乐观锁工作原理

乐观锁的原理是:在执行更新操作时,检查数据库中的 version 字段是否与传入的 version 值一致,如果一致则执行更新并将 version +1,否则放弃更新操作。

示例流程

  1. 查询数据,获取当前版本号(假设 version=1)。
  2. 更新时,检查 WHERE 条件中的版本号是否仍为 1
  3. 如果版本号一致,执行更新并将版本号递增。
  4. 如果版本号不一致,表示数据已经被其他线程修改过,此时更新操作会失败。
3.3.3 配置乐观锁插件

为确保乐观锁功能正常工作,通常需要在配置类中添加乐观锁插件:

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyBatisPlusConfig {@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}
}

添加 OptimisticLockerInterceptor 插件后,MyBatis-Plus 会自动处理 @Version 字段的更新操作。

4. 代码生成器(MyBatis-Plus)

代码生成器的作用是根据数据库表自动生成符合 MyBatis-Plus 规范的基础代码。通过配置代码生成器,可以生成以下内容:

  • 实体类:包含表字段的映射,以及常用的注解(如 @TableId@TableLogic 等)。
  • Mapper 接口:继承 BaseMapper,提供基础的 CRUD 方法。
  • Service 接口和实现类:包含业务逻辑层的接口和实现,简化业务层代码。
  • Controller:包含基础的 HTTP 接口,提供 API 层的访问入口。

4.1 基本配置

代码生成器可以在 Spring Boot 项目的任意位置编写,例如,可以在 src/test/java 中创建一个专用的测试类,用于运行代码生成器并生成文件。

4.1.1 引入依赖

pom.xml 中添加代码生成器依赖(如果已引入 mybatis-plus-boot-starter,可以忽略此步):

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.0</version> <!-- 最新稳定版本 -->
</dependency>
<dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version> <!-- 模板引擎,用于生成代码模板 -->
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version>
</dependency>
4.1.2 创建代码生成器配置类

src/test/java 目录下新建一个测试类 CodeGenerator,在其中进行代码生成的配置。以下是一个完整的代码生成器示例。

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;public class CodeGenerator {public static void main(String[] args) {// 1. 创建代码生成器AutoGenerator mpg = new AutoGenerator();// 2. 全局配置GlobalConfig gc = new GlobalConfig();gc.setOutputDir(System.getProperty("user.dir") + "/src/main/java"); // 生成文件的输出目录gc.setAuthor("YourName"); // 设置作者gc.setOpen(false); // 生成后是否打开文件夹gc.setFileOverride(true); // 是否覆盖已有文件gc.setIdType(IdType.AUTO); // 主键策略gc.setSwagger2(true); // 是否启用 Swagger2mpg.setGlobalConfig(gc);// 3. 数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("password");mpg.setDataSource(dsc);// 4. 包配置PackageConfig pc = new PackageConfig();pc.setParent("com.example.demo"); // 设置父包名pc.setModuleName("user"); // 设置模块名(可选)pc.setEntity("model"); // 设置实体类包名pc.setMapper("mapper"); // 设置 Mapper 包名pc.setService("service"); // 设置 Service 包名pc.setServiceImpl("service.impl"); // 设置 Service 实现类包名pc.setController("controller"); // 设置 Controller 包名mpg.setPackageInfo(pc);// 5. 策略配置StrategyConfig strategy = new StrategyConfig();strategy.setNaming(NamingStrategy.underline_to_camel); // 表名转换为驼峰命名strategy.setColumnNaming(NamingStrategy.underline_to_camel); // 字段名转换为驼峰命名strategy.setEntityLombokModel(true); // 使用 Lombok 注解strategy.setRestControllerStyle(true); // 生成 RESTful 风格的 Controllerstrategy.setInclude("user"); // 生成的表名strategy.setControllerMappingHyphenStyle(true); // URL 中驼峰转连字符mpg.setStrategy(strategy);// 6. 模板引擎mpg.setTemplateEngine(new VelocityTemplateEngine());// 7. 执行生成mpg.execute();}
}
配置说明
  • 全局配置 (GlobalConfig):配置作者、输出目录、是否覆盖文件、主键策略等全局参数。
  • 数据源配置 (DataSourceConfig):配置数据库连接信息,包括 URL、用户名、密码等。
  • 包配置 (PackageConfig):设置各层的包名结构,指定父包名和各个模块的包名。
  • 策略配置 (StrategyConfig):指定生成策略,包括表名、字段命名策略、是否使用 Lombok、是否启用 REST 风格 Controller 等。
  • 模板引擎:设置使用 Velocity 模板引擎生成代码(可选的模板引擎还有 Freemarker、Beetl 等)。

配置完成后,运行 CodeGeneratormain 方法,即可自动生成代码。


4.2 生成代码示例

运行代码生成器后,将会在 src/main/java 目录下生成以下代码文件:

  • 实体类User):在 model 包下生成实体类,包括表字段、主键等的映射,并带有 Lombok 注解。
  • Mapper 接口UserMapper):在 mapper 包下生成 Mapper 接口,继承自 BaseMapper,包含 CRUD 方法。
  • Service 接口和实现类UserServiceUserServiceImpl):在 serviceservice.impl 包下生成业务接口和实现类。
  • ControllerUserController):在 controller 包下生成 RESTful 风格的 Controller,提供 HTTP 接口。

生成的代码示例如下:

4.2.1 实体类
package com.example.demo.model;import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;@Data
public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private String email;@TableLogicprivate Integer deleted; // 逻辑删除字段@Versionprivate Integer version; // 乐观锁字段
}
4.2.2 Mapper 接口
package com.example.demo.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.model.User;public interface UserMapper extends BaseMapper<User> {
}
4.2.3 Service 接口和实现类

Service 接口

package com.example.demo.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.model.User;public interface UserService extends IService<User> {
}

Service 实现类

package com.example.demo.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
4.2.4 Controller
package com.example.demo.controller;import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/list")public List<User> listUsers() {return userService.list();}@PostMapping("/add")public boolean addUser(@RequestBody User user) {return userService.save(user);}@PutMapping("/update")public boolean updateUser(@RequestBody User user) {return userService.updateById(user);}@DeleteMapping("/delete/{id}")public boolean deleteUser(@PathVariable Long id) {return userService.removeById(id);}
}

相关文章:

MyBatis与MyBatis-Plus(基础)

MyBatis-Plus的优势 在 Spring Data JPA 已经很方便的情况下&#xff0c;有时仍然选择使用 MyBatis-Plus 的核心原因主要有以下三点&#xff1a; 1. 复杂 SQL 控制能力更强 MyBatis-Plus 允许直接编写和优化 SQL&#xff0c;适合复杂查询、精细化 SQL 控制的场景。特别是在性…...

一文总结java语法规则

1. 题记 Java是一门拥有较强语法规则的编程语言&#xff0c;本博文主要总结介绍java语言的java语法规则。 2. java语法规则 2.1 标识符&#xff08;Identifiers&#xff09; 定义&#xff1a;标识符是用来给变量、类、方法、接口等命名的字符序列。规则&#xff1a; –标识…...

使用 npm 安装 Yarn

PS E:\WeChat Files\wxid_fipwhzebc1yh22\FileStorage\File\2024-11\spid-admin\spid-admin> yarn install yarn : 无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后…...

vue3中利用路由信息渲染菜单栏

1. 创建路由时将路由信息对象进行抽离 将路由信息对象单独抽离到router/routes.ts文件 关键&#xff1a;利用路由元信息meta&#xff0c;定义3个属性 hidden&#xff1a;控制当前路由是否显示在菜单栏中title&#xff1a;菜单拦名称icon&#xff1a;对应菜单名称前面的图标 …...

Mysql每日一题(行程与用户,困难※)

今天给大家分享一个截止到目前位置&#xff0c;我遇到最难的一道mysql题目&#xff0c;非常建议大家亲手做一遍 完整代码如下&#xff0c;这道题的主要难点是它有两个外键&#xff0c;以前没遇到过&#xff0c;我也没当回事&#xff0c;分享一下错误经验哈 当时我写的where判断…...

adb 命令 查找启动的包名以及导出安装包

查看安卓内包名 adb 查看所有安装的包 adb shell pm list packages查看安装的第三方app的包名 adb shell pm list packages -3查看启动的app的包名 adb shell dumpsys activity top | find "ACTIVITY"adb shell dumpsys activity activities | findstr "Run…...

Flink_DataStreamAPI_输出算子Sink

Flink_DataStreamAPI_输出算子Sink 1连接到外部系统2输出到文件3输出到Kafka4输出到MySQL&#xff08;JDBC&#xff09;5自定义Sink输出 Flink作为数据处理框架&#xff0c;最终还是要把计算处理的结果写入外部存储&#xff0c;为外部应用提供支持。 1连接到外部系统 Flink的D…...

标准C++ 字符串

一、标准库中的字符串类型 在C中&#xff0c;字符串是一个非常重要的数据类型&#xff0c;用于表示和处理文本信息。C提供了多种方式来处理字符串&#xff0c;每种方式都有其特点和适用场景。以下是几种常见的字符串类型及其用法&#xff1a; 1. C 风格字符串 (char* 或 char…...

时序预测:多头注意力+宽度学习

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

day06(单片机)IIC+STH20

目录 IICSHT20 I2C基础简介 为什么I2C需要使用上拉电阻&#xff1f; I2C特点 时序图分析 起始信号与终止信号 数据传输时序 字节传输和应答信号 I2C寻址 主机给从机发送一个字节 主机给从机发送多个字节 主机从从机接收一个字节 主机从从机接收多个字节 I2C寄存器 I2C_RXDR&…...

Bugku CTF_Web——文件上传

Bugku CTF_Web——文件上传 进入靶场 My name is margin,give me a image file not a php抓个包上传试试 改成png也上传失败 应该校验了文件头 增加了文件头也不行 试了一下 把文件类型改成gif可以上传 但是还是不能连接 将Content-Type改大小写 再把文件后缀名改成php4 成…...

C#版使用融合通信API发送手机短信息

目录 功能实现 范例运行环境 实现范例 类设计 类代码实现 调用范例 总结 功能实现 融合云通信服务平台&#xff0c;为企业提供全方位通信服务&#xff0c;发送手机短信是其一项核心功能&#xff0c;本文将讲述如何使用融合云服务API为终端手机用户发送短信信息&#xf…...

人工智能:重塑医疗、企业与生活的未来知识管理——以HelpLook为例

一、医疗行业&#xff1a;AI引领的医疗革新 随着人工智能&#xff08;AI&#xff09;技术的持续飞跃&#xff0c;我们正身处一场跨行业的深刻变革之中。在医疗健康的广阔舞台上&#xff0c;人工智能技术正扮演着日益重要的角色。它不仅能够辅助医生进行病例的精准诊断&#xf…...

MVVM(Model-View-ViewModel)模型

MVVM&#xff08;ModelViewViewModel&#xff09;模型是一种常用于软件开发中的架构模式&#xff0c;尤其在前端框架&#xff08;如 Vue.js、React、Angular&#xff09;中被广泛应用。它将程序的用户界面与业务逻辑分离&#xff0c;便于维护和扩展。 MVVM 的三个组成部分 1. …...

权限系统:权限应用服务设计

今天聊聊权限系统的应用服务设计。 从业务需求的角度来看&#xff0c;权限系统需要解决两个核心问题&#xff1a; 1、菜单渲染与动态展示 当用户成功登录并接入系统后&#xff0c;系统需要动态获取并展示该用户有权限访问的菜单项。 这一过程涉及前端系统与权限系统的交互。前端…...

Android音频架构

音频基础知识 声音有哪些重要属性呢&#xff1f; 响度(Loudness) 响度就是人类可以感知到的各种声音的大小&#xff0c;也就是音量。响度与声波的振幅有直接关系。 音调(Pitch) 音调与声音的频率有关系&#xff0c;当声音的频率越大时&#xff0c;人耳所感知到的音调就越高&a…...

AI 智享直播:开启直播新篇,引领未来互动新趋势!

在数字化浪潮席卷全球的今天&#xff0c;AI技术正以不可阻挡之势渗透进我们生活的方方面面&#xff0c;从智能家居到自动驾驶&#xff0c;从医疗健康到金融服务&#xff0c;无一不彰显着其强大的影响力和无限的潜力。而在这一波科技革新的洪流中&#xff0c;直播行业也迎来了前…...

【AIGC】国内AI工具复现GPTs效果详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;前言&#x1f4af;本文所要复现的GPTs介绍&#x1f4af;GPTs指令作为提示词在ChatGPT实现类似效果&#x1f4af;国内AI工具复现GPTs效果可能出现的问题解决方法解决后的效果 &#x1…...

Charles抓https包-配置系统证书(雷电)

1、导出证书 2、下载 主页上传资源中有安装包&#xff0c;免费的 openssl 安装教程自己搜 openssl x509 -subject_hash_old -in charles.pem 3、修改证书名、后缀改成点0 雷电打开root和磁盘写入 4、导入雷电证书根目录 证书拖进去&#xff0c;基本就完成了&#xff…...

在卷积神经网络中真正占用内存的是什么

在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;占用内存的主要部分包括以下几个方面&#xff1a; 1. 模型参数&#xff08;Weights and Biases&#xff09; CNN 中的权重和偏置&#xff08;即模型的参数&#xff09;通常是占用内存的最大部分。具体来说&#xff1…...

2024 ECCV | DualDn: 通过可微ISP进行双域去噪

文章标题&#xff1a;《DualDn: Dual-domain Denoising via Differentiable ISP》 论文链接&#xff1a; DualDn 代码链接&#xff1a; https://openimaginglab.github.io/DualDn/ 本文收录于2024ECCV&#xff0c;是上海AI Lab、浙江大学、香港中文大学&#xff08;薛天帆等…...

Elasticsearch 和 Kibana 8.16:Kibana 获得上下文和 BBQ 速度并节省开支!

作者&#xff1a;来自 Elastic Platform Product Team Elastic Search AI 平台&#xff08;Elasticsearch、Kibana 和机器学习&#xff09;的 8.16 版本包含大量新功能&#xff0c;可提高性能、优化工作流程和简化数据管理。 使用更好的二进制量化 (Better Binary Quantizatio…...

Linux 抓包工具 --- tcpdump

序言 在传输层 Tcp 的学习中&#xff0c;我们了解了 三次握手和四次挥手 的概念&#xff0c;但是看了这么多篇文章&#xff0c;我们也只是停留在 纸上谈兵。  欲知事情如何&#xff0c;我们其实可以尝试去看一下具体的网络包的信息。在这篇文章中将向大家介绍&#xff0c;在 L…...

Vector Optimization – Stride

文章目录 Vector优化 – stride跳跃Vector优化 – stride跳跃 This distance between memory locations that separates the elements to be gathered into a single register is called the stride. A stride of one unit is called a unit-stride. This is equivalent to se…...

git config是做什么的?

git config是做什么的&#xff1f; git config作用配置级别三种配置级别的介绍及使用&#xff0c;配置文件说明 使用说明git confi查看参数 默认/不使用这个参数 情况下 Git 使用哪个配置等级&#xff1f; 一些常见的行为查看配置信息设置配置信息删除配置信息 一些常用的配置信…...

计算机网络(7) 数据链路层

数据链路层的内容不学不知道&#xff0c;一学真的是吓一跳哦&#xff0c;内容真的挺多的&#xff0c;但是大家不要害怕&#xff0c;总会学完的。 还有由于数据链路层的内容太多&#xff0c;一篇肯定是讲不完的所以我决定把它分为好几个部分进行学习与讲解。大家可以关注以后文…...

2024年秋国开电大《建筑结构试验》形考任务1-4

形考作业一 1.下列选项中,( )项不属于科学研究性试验。 答案:检验结构的质量,说明工程的可靠性 2.下列各项,( )项不属于工程鉴定性试验。 答案:验证结构计算理论的假定 3.按试验目的进行分类,可将结构试验分成( )。 答案:工程鉴定性试验和科学研究性试验…...

【MySQL】explain之type类型

explain的type共有以下几种类型&#xff0c;system、const、eq_ref、ref、range、index、all。 system&#xff1a;当表中只有一条记录并且该表使用的存储引擎的统计数据是精确的&#xff0c;比如MyISAM、Memory&#xff0c;那么对该表的访问方法就是system。 const&#xff…...

Llama架构及代码详解

Llama的框架图如图&#xff1a; 源码中含有大量分布式训练相关的代码&#xff0c;读起来比较晦涩难懂&#xff0c;所以我们对llama自顶向下进行了解析及复现&#xff0c;我们对其划分成三层&#xff0c;分别是顶层、中层、和底层&#xff0c;如下&#xff1a; Llama的整体组成…...

Android onConfigurationChanged 基础配置

onConfigurationChanged 代替重建 0. **定义与基本用途**1. **具体使用场景 - 屏幕方向改变**2. **具体使用场景 - 键盘可用性改变**3. **具体使用场景 - 语言设置变更**4. **具体使用场景 - 屏幕密度变化**5. **具体使用场景 - 字体大小改变**6. **具体使用场景 - 屏幕尺寸变化…...