【黑马SpringCloud微服务开发与实战】(一)MybatisPlus篇

2024最新SpringCloud微服务开发与实战 视频教程 下载 │ Elasticsearch01-14.JavaRestClient-文档的CRUD.mp4。│ Elasticsearch01-13.JavaRestClient-新增文档.mp4。│ MybatisPlus-10.核心功能-IService的Lambda方法.mp4。│ MybatisPlus-11.核心功能-IService的批量新增.mp4。│ Elasticsearch01-07.索引库操作-索引库的CRUD.mp4。 阅读详情

(一)MybatisPlus入门案例

在这里插入图片描述

数据库表的建立sql,可以复制到txt文本导入即可,也可以直接复制到navicat直接执行。

-- --------------------------------------------------------
-- 主机:                           127.0.0.1
-- 服务器版本:                        8.0.28 - MySQL Community Server - GPL
-- 服务器操作系统:                      Win64
-- HeidiSQL 版本:                  12.2.0.6576
-- --------------------------------------------------------

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!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 */;


-- 导出 mp 的数据库结构
CREATE DATABASE IF NOT EXISTS `mp` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `mp`;

-- 导出  表 mp.address 结构
CREATE TABLE IF NOT EXISTS `address` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `user_id` bigint DEFAULT NULL COMMENT '用户ID',
  `province` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '省',
  `city` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '市',
  `town` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '县/区',
  `mobile` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '手机',
  `street` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '详细地址',
  `contact` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '联系人',
  `is_default` bit(1) DEFAULT b'0' COMMENT '是否是默认 1默认 0否',
  `notes` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',
  `deleted` bit(1) DEFAULT b'0' COMMENT '逻辑删除',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=COMPACT;

-- 正在导出表  mp.address 的数据:~11 rows (大约)

INSERT INTO `address` (`id`, `user_id`, `province`, `city`, `town`, `mobile`, `street`, `contact`, `is_default`, `notes`, `deleted`) VALUES
	(59, 2, '北京', '北京', '朝阳区', '13900112222', '金燕龙办公楼', 'Rose', b'1', NULL, b'0'),
	(60, 1, '北京', '北京', '朝阳区', '13700221122', '修正大厦', 'Jack', b'0', NULL, b'0'),
	(61, 1, '上海', '上海', '浦东新区', '13301212233', '航头镇航头路', 'Jack', b'1', NULL, b'0'),
	(63, 2, '广东', '佛山', '永春', '13301212233', '永春武馆', 'Rose', b'0', NULL, b'0'),
	(64, 3, '浙江', '杭州', '拱墅区', '13567809102', '浙江大学', 'Hope', b'1', NULL, b'0'),
	(65, 3, '浙江', '杭州', '拱墅区', '13967589201', '左岸花园', 'Hope', b'0', NULL, b'0'),
	(66, 4, '湖北', '武汉', '汉口', '13967519202', '天天花园', 'Thomas', b'1', NULL, b'0'),
	(67, 3, '浙江', '杭州', '拱墅区', '13967589201', '左岸花园', 'Hopey', b'0', NULL, b'0'),
	(68, 4, '湖北', '武汉', '汉口', '13967519202', '天天花园', 'Thomas', b'1', NULL, b'0'),
	(69, 3, '浙江', '杭州', '拱墅区', '13967589201', '左岸花园', 'Hopey', b'0', NULL, b'0'),
	(70, 4, '湖北', '武汉', '汉口', '13967519202', '天天花园', 'Thomas', b'1', NULL, b'0');

-- 导出  表 mp.user 结构
CREATE TABLE `user` (
	`id` BIGINT(19) NOT NULL AUTO_INCREMENT COMMENT '用户id',
	`username` VARCHAR(50) NOT NULL COMMENT '用户名' COLLATE 'utf8_general_ci',
	`password` VARCHAR(128) NOT NULL COMMENT '密码' COLLATE 'utf8_general_ci',
	`phone` VARCHAR(20) NULL DEFAULT NULL COMMENT '注册手机号' COLLATE 'utf8_general_ci',
	`info` JSON NOT NULL COMMENT '详细信息',
	`status` INT(10) NULL DEFAULT '1' COMMENT '使用状态(1正常 2冻结)',
	`balance` INT(10) NULL DEFAULT NULL COMMENT '账户余额',
	`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
	`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
	PRIMARY KEY (`id`) USING BTREE,
	UNIQUE INDEX `username` (`username`) USING BTREE
)
COMMENT='用户表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=COMPACT
AUTO_INCREMENT=5
;

-- 正在导出表  mp.user 的数据:~4 rows (大约)

INSERT INTO `user` (`id`, `username`, `password`, `phone`, `info`, `status`, `balance`, `create_time`, `update_time`) VALUES
	(1, 'Jack', '123', '13900112224', '{"age": 20, "intro": "佛系青年", "gender": "male"}', 1, 1600, '2023-05-19 20:50:21', '2023-06-19 20:50:21'),
	(2, 'Rose', '123', '13900112223', '{"age": 19, "intro": "青涩少女", "gender": "female"}', 1, 600, '2023-05-19 21:00:23', '2023-06-19 21:00:23'),
	(3, 'Hope', '123', '13900112222', '{"age": 25, "intro": "上进青年", "gender": "male"}', 1, 100000, '2023-06-19 22:37:44', '2023-06-19 22:37:44'),
	(4, 'Thomas', '123', '17701265258', '{"age": 29, "intro": "伏地魔", "gender": "male"}', 1, 800, '2023-06-19 23:44:45', '2023-06-19 23:44:45');

/*!40103 SET TIME_ZONE=IFNULL(@OLD_TIME_ZONE, 'system') */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 你的密码
logging:
  level:
    com.itheima: debug
  pattern:
    dateformat: HH:mm:ss
mybatis:
  mapper-locations: classpath*:mapper/*.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 https://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.12</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.itheima.mp</groupId>
    <artifactId>mp-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mp-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.11</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

在这里插入图片描述
在这里插入图片描述
注释mybatis的依赖,加速mp的依赖

<!--        <dependency>-->
<!--            <groupId>org.mybatis.spring.boot</groupId>-->
<!--            <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!--            <version>2.3.1</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>

继承Basemapper,mp对mybaits的代码时是无侵入的,因此可以继续保留原mybaits的代码

public interface UserMapper extends BaseMapper<User> {

    void saveUser(User user);

    void deleteUser(Long id);

    void updateUser(User user);

    User queryUserById(@Param("id") Long id);

    List<User> queryUserByIds(@Param("ids") List<Long> ids);
}

<?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.itheima.mp.mapper.UserMapper">
    <insert id="saveUser" parameterType="com.itheima.mp.domain.po.User">
        INSERT INTO `user` (`id`, `username`, `password`, `phone`, `info`, `balance`)
        VALUES
        (#{id}, #{username}, #{password}, #{phone}, #{info}, #{balance});
    </insert>
    <update id="updateUser" parameterType="com.itheima.mp.domain.po.User">
        UPDATE `user`
        <set>
            <if test="username != null">
                `username`=#{username}
            </if>
            <if test="password != null">
                `password`=#{password}
            </if>
            <if test="phone != null">
                `phone`=#{phone}
            </if>
            <if test="info != null">
                `info`=#{info}
            </if>
            <if test="status != null">
                `status`=#{status}
            </if>
            <if test="balance != null">
                `balance`=#{balance}
            </if>
        </set>
        WHERE `id`=#{id};
    </update>
    <delete id="deleteUser" parameterType="com.itheima.mp.domain.po.User">
        DELETE FROM user WHERE id = #{id}
    </delete>

    <select id="queryUserById" resultType="com.itheima.mp.domain.po.User">
        SELECT *
        FROM user
        WHERE id = #{id}
    </select>

    <select id="queryUserByIds" resultType="com.itheima.mp.domain.po.User">
        SELECT *
        FROM user
        <if test="ids != null">
            WHERE id IN
            <foreach collection="ids" open="(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </if>
        LIMIT 10
    </select>

</mapper>

单元测试

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testInsert() {
        User user = new User();
        user.setId(5L);
        user.setUsername("Lucy");
        user.setPassword("123");
        user.setPhone("18688990011");
        user.setBalance(200);
        user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.saveUser(user);
    }

    @Test
    void testSelectById() {
        User user = userMapper.queryUserById(5L);
        System.out.println("user = " + user);
    }


    @Test
    void testQueryByIds() {
        List<User> users = userMapper.queryUserByIds(List.of(1L, 2L, 3L, 4L));
        users.forEach(System.out::println);
    }

    @Test
    void testUpdateById() {
        User user = new User();
        user.setId(5L);
        user.setBalance(20000);
        userMapper.updateUser(user);
    }

    @Test
    void testDeleteUser() {
        userMapper.deleteUser(5L);
    }
}

测试原mybatis的代码依旧可用,但是我们要学习的是mp
在这里插入图片描述
注释掉的是原mybaits代码,新的是mq,测试都阔以通过

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testInsert() {
        User user = new User();
        user.setId(5L);
        user.setUsername("Lucy");
        user.setPassword("123");
        user.setPhone("18688990011");
        user.setBalance(200);
        user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
//        userMapper.saveUser(user);
        // mp实现
        userMapper.insert(user);
    }

    @Test
    void testSelectById() {
//        User user = userMapper.queryUserById(5L);
        User user = userMapper.selectById(5L);
        System.out.println("user = " + user);
    }


    @Test
    void testQueryByIds() {
//        List<User> users = userMapper.queryUserByIds(List.of(1L, 2L, 3L, 4L));
        List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));
        users.forEach(System.out::println);
    }

    @Test
    void testUpdateById() {
        User user = new User();
        user.setId(5L);
        user.setBalance(20000);
//        userMapper.updateUser(user);
        userMapper.updateById(user);
    }

    @Test
    void testDeleteUser() {
//        userMapper.deleteUser(5L);
        userMapper.deleteById(5L);
    }
}

在这里插入图片描述

(二)MybatisPlus常用注解

在这里插入图片描述
在这里插入图片描述
为了成为mp的个人练习生,需要修改一下表面不一致,因为我们一开始的实体和数据库太一致了。。。这里就只测试表名了,想测试的小伙伴可以自己根据条件去修改。。。

在这里插入图片描述

@Data
@TableName("tb_user")
public class User {

    /**
     * 用户id
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 注册手机号
     */
    private String phone;

    /**
     * 详细信息
     */
    private String info;

    /**
     * 使用状态(1正常 2冻结)
     */
    private Integer status;

    /**
     * 账户余额
     */
    private Integer balance;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}

在这里插入图片描述

(三)MybatisPlus常用配置

在这里插入图片描述

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 你的密码
logging:
  level:
    com.itheima: debug
  pattern:
    dateformat: HH:mm:ss
#mybatis:
#  mapper-locations: classpath*:mapper/*.xml

mybatis-plus:
  type-aliases-package: com.itheima.mp.domain.po
  mapper-locations: classpath*:mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto

在这里插入图片描述

(四)MybatisPlus条件构造器

在这里插入图片描述
在这里插入图片描述

    @Test
    void testQueryWrapper(){
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .select("id","username","info","balance")
                .like("username", "o")
                .ge("balance", 1000);

        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

    @Test
    void testUpdateQueryWrapper(){

        User user = new User();
        user.setBalance(2000);

        QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username","jack");

        userMapper.update(user,wrapper);

    }

在这里插入图片描述
在这里插入图片描述

    @Test
    void testUpdateWrapper(){
        List<Long> ids = List.of(1L,2L,4L);
        UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
                .setSql("balance = balance - 200")
                .in("id", ids);
        userMapper.update(null,wrapper);

    }

避免硬编码机制:

    @Test
    void testLambdaQueryWrapper(){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .select(User::getId,User::getUsername,User::getInfo,User::getBalance)
                .like(User::getUsername, "o")
                .ge(User::getBalance, 1000);

        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

在这里插入图片描述

(五)MybatisPlus自定义sql

在这里插入图片描述

在这里插入图片描述

    @Test
    void testUpdateWrapper2(){
        // 1.更新条件
        List<Long> ids = List.of(1L,2L,4L);
        int amount = 200;
        QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);
        userMapper.updateBalanceByIds(wrapper, amount);

    }


void updateBalanceByIds(@Param("ew") QueryWrapper<User> wrapper,@Param("amount") int amount);
    <update id="updateBalanceByIds">
        UPDATE tb_user SET balance = balance - ${amount} ${ew.customSqlSegment}
    </update>

(六) Iservice基本接口用法

在这里插入图片描述
在这里插入图片描述

public interface IUserService extends IService<User> {
}


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

}


// alt + enter 自动生成单元测试
@SpringBootTest
class UserServiceImplTest {

    @Autowired
    private IUserService userService;

    @Test
    void testInsert() {
        User user = new User();
//        user.setId(5L);
        user.setUsername("LiLei");
        user.setPassword("123");
        user.setPhone("18688990011");
        user.setBalance(200);
        user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
//        userMapper.saveUser(user);
        // mp实现
        userService.save(user);
    }

    @Test
    void testQuery(){
        List<User> users = userService.listByIds(List.of(1L, 2L, 4L));
        users.forEach(System.out::println);

    }



}

在这里插入图片描述

(七) Iservice开发基础业务接口

在这里插入图片描述

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

视频导入的包
在这里插入图片描述

knife4j:
  enable: true
  openapi:
    title: 用户管理接口文档
    description: 用户管理接口文档
    email: 1111111111@qq.com
    concat: llll
    url: https://www.itcast.cn
    version: v1.0.0
    group:
      default:
        group-name: default
        api-rule: package
        api-rule-resources:
          - com.itheima.mp.controller
@Data
@ApiModel(description = "用户表单实体")
public class UserFormDTO {

    @ApiModelProperty("id")
    private Long id;

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("密码")
    private String password;

    @ApiModelProperty("注册手机号")
    private String phone;

    @ApiModelProperty("详细信息,JSON风格")
    private String info;

    @ApiModelProperty("账户余额")
    private Integer balance;
}


@Data
@ApiModel(description = "用户VO实体")
public class UserVO {

    @ApiModelProperty("用户id")
    private Long id;

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("详细信息")
    private String info;

    @ApiModelProperty("使用状态(1正常 2冻结)")
    private Integer status;

    @ApiModelProperty("账户余额")
    private Integer balance;
}

@Data
@TableName("tb_user")
public class User {

    /**
     * 用户id
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 注册手机号
     */
    private String phone;

    /**
     * 详细信息
     */
    private String info;

    /**
     * 使用状态(1正常 2冻结)
     */
    private Integer status;

    /**
     * 账户余额
     */
    private Integer balance;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}
@Api(tags = "用户管理接口")
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {


    private final IUserService userService;

    @ApiOperation("新增用户接口")
    @PostMapping
    public void saveUser(@RequestBody UserFormDTO userDto){
        // 1.把Dto拷贝到po
        User user = BeanUtil.copyProperties(userDto, User.class);
        userService.save(user);
    }


    @ApiOperation("删除用户接口")
    @DeleteMapping("/{id}")
    public void deleteUserById(@ApiParam("用户id") @PathVariable("id") Long id){
        userService.removeById(id);
    }

    @ApiOperation("根据id查询用户接口")
    @GetMapping("/{id}")
    public UserVO queryUserById(@ApiParam("用户id") @PathVariable Long id){
        User user = userService.getById(id);
        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
        return userVO;
    }

    @ApiOperation("根据id批量查询用户接口")
    @GetMapping
    public List<UserVO> queryUserById(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids){
        List<User> users = userService.listByIds(ids);
        return BeanUtil.copyToList(users, UserVO.class);
    }

    @ApiOperation("扣减用户余额接口")
    @DeleteMapping("/{id}/deduction/{money}")
    public void deductMoneyById(@ApiParam("用户id") @PathVariable("id") Long id,
                                @ApiParam("扣减的金额") @PathVariable("money") Integer money){
        userService.deductBalance(id,money);
    }

}

public interface IUserService extends IService<User> {
    void deductBalance(Long id, Integer money);
}


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService{

    @Override
    public void deductBalance(Long id, Integer money) {
        // 1.查询用户
        User user = getById(id);
        // 2.校验用户状态
        if(user == null || user.getStatus() == 2){
            throw new RuntimeException("用户状态异常");
        }
        // 3.校验余额是否充足
        if(user.getBalance() < money){
            throw new RuntimeException("用户余额不足");
        }
        // 4.减扣余额
        baseMapper.deductBalance(id, money);
    }
}

public interface UserMapper extends BaseMapper<User> {

    void saveUser(User user);

    void deleteUser(Long id);

    void updateUser(User user);

    User queryUserById(@Param("id") Long id);

    List<User> queryUserByIds(@Param("ids") List<Long> ids);


    void updateBalanceByIds(@Param("ew") QueryWrapper<User> wrapper,@Param("amount") int amount);

    @Update("update tb_user set balance = balance - #{money} where id = #{id}")
    void deductBalance(@Param("id") Long id,@Param("money") Integer money);
}

http://localhost:8080/doc.html 启动springboot进入这个网址测试接口,测试下来都没问题。

在这里插入图片描述

(八) Iservice的Lambda查询

在这里插入图片描述
在这里插入图片描述

@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery {
    @ApiModelProperty("用户名关键字")
    private String name;
    @ApiModelProperty("用户状态:1-正常,2-冻结")
    private Integer status;
    @ApiModelProperty("余额最小值")
    private Integer minBalance;
    @ApiModelProperty("余额最大值")
    private Integer maxBalance;
}
    @ApiOperation("根据复杂条件批量查询用户接口")
    @GetMapping("/list")
    public List<UserVO> queryUsers(UserQuery userQuery){
        List<User> users = userService.queryUsers(userQuery.getName(),userQuery.getStatus(),
                userQuery.getMinBalance(), userQuery.getMaxBalance());
        return BeanUtil.copyToList(users, UserVO.class);
    }

public interface IUserService extends IService<User> {

    List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance);
}
    @Override
    public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {
        List<User> list = lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .ge(minBalance != null, User::getBalance, minBalance)
                .le(maxBalance != null, User::getBalance, maxBalance)
                .list();
        return list;
    }

在这里插入图片描述
在这里插入图片描述

    @Override
    @Transactional
    public void deductBalance(Long id, Integer money) {
        // 1.查询用户
        User user = getById(id);
        // 2.校验用户状态
        if(user == null || user.getStatus() == 2){
            throw new RuntimeException("用户状态异常");
        }
        // 3.校验余额是否充足
        if(user.getBalance() < money){
            throw new RuntimeException("用户余额不足");
        }
        // 4.减扣余额
//        baseMapper.deductBalance(id, money);
        int remainBalance = user.getBalance() - money;
        lambdaUpdate().set(User::getBalance, remainBalance)
                .set(remainBalance==0,User::getStatus, 2)
                .eq(User::getId, id)
                .eq(User::getBalance, user.getBalance()) // 乐观锁
                .update();
    }

(九) Iservice的批量新增

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更改配置
在这里插入图片描述
在这里插入图片描述

(十) 代码生成器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(十一) 静态工具

在这里插入图片描述

在这里插入图片描述

更改一下mp的版本,新版本支持

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3</version>
        </dependency>

service相互调用可能会出现循环依赖时,利用db

@Data
@ApiModel(description = "收货地址VO")
public class AddressVO{

    @ApiModelProperty("id")
    private Long id;

    @ApiModelProperty("用户ID")
    private Long userId;

    @ApiModelProperty("省")
    private String province;

    @ApiModelProperty("市")
    private String city;

    @ApiModelProperty("县/区")
    private String town;

    @ApiModelProperty("手机")
    private String mobile;

    @ApiModelProperty("详细地址")
    private String street;

    @ApiModelProperty("联系人")
    private String contact;

    @ApiModelProperty("是否是默认 1默认 0否")
    private Boolean isDefault;

    @ApiModelProperty("备注")
    private String notes;
}
@Data
@ApiModel(description = "用户VO实体")
public class UserVO {

    @ApiModelProperty("用户id")
    private Long id;

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("详细信息")
    private String info;

    @ApiModelProperty("使用状态(1正常 2冻结)")
    private Integer status;

    @ApiModelProperty("账户余额")
    private Integer balance;

    @ApiModelProperty("用户的收获地址")
    private List<AddressVO> addresses;
}

@Override
public UserVO queryUserInfoById(Long id) {
    // 1.查询用户
    User user = getById(id);
    if(user == null || user.getStatus() == 2){
        throw new RuntimeException("用户状态异常!");
    }
    // 2.查询地址
    List<Address> addresses = Db.lambdaQuery(Address.class)
            .eq(Address::getUserId, id).list();
    // 3.封装VO
    UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
    if(CollUtil.isNotEmpty(addresses)){
        List<AddressVO> addressVOS = BeanUtil.copyToList(addresses, AddressVO.class);
        userVO.setAddresses(addressVOS);
    }
    return userVO;
}
 @Override
 public List<UserVO> queryUserInfosById(List<Long> ids) {

     List<User> users = listByIds(ids);
     if(CollUtil.isEmpty(users)){
         return Collections.emptyList();
     }

     List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());
     List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();
     List<AddressVO> addressVOS = BeanUtil.copyToList(addresses, AddressVO.class);
     Map<Long, List<AddressVO>> addressMap = new HashMap<>(0);
     if(CollUtil.isNotEmpty(addresses)){
         addressMap = addressVOS.stream().collect(Collectors.groupingBy(AddressVO::getUserId));
     }
     List<UserVO> list = new ArrayList<>(users.size());
     for (User user : users) {
         UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
         userVO.setAddresses(addressMap.get(userVO.getId()));
         list.add(userVO);
     }
     return list;
 }

在这里插入图片描述

(十二) 逻辑删除

在这里插入图片描述

在这里插入图片描述

mybatis-plus:
  type-aliases-package: com.itheima.mp.domain.po
  mapper-locations: classpath*:mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-field: deleted
      logic-not-delete-value: 0
      logic-delete-value: 1
@SpringBootTest
class IAddressServiceTest {

    @Autowired
    private IAddressService addressService;

    @Test
    void testLogicDelete(){
        addressService.removeById(60L);

        Address address = addressService.getById(60L);
        System.out.println("address:" + address);
    }
}

在这里插入图片描述
在这里插入图片描述

(十三) 枚举处理器

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

@Getter
public enum UserStatus {

    NORMAL(1,"正常"),
    FROZEN(2,"冻结"),;

    @EnumValue
    @JsonValue
    private final int value;

    private final String desc;

    UserStatus(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }
}

mybatis-plus:
  type-aliases-package: com.itheima.mp.domain.po
  mapper-locations: classpath*:mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-field: deleted
      logic-not-delete-value: 0
      logic-delete-value: 1
  configuration:
    # 配置枚举处理器(3.5.0+ 版本推荐)
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
    /**
     * 使用状态(1正常 2冻结)
     */
    private UserStatus status;
        // 2.校验用户状态
        if(user == null || user.getStatus() == UserStatus.FROZEN){
            throw new RuntimeException("用户状态异常");
        }
        int remainBalance = user.getBalance() - money;
        lambdaUpdate().set(User::getBalance, remainBalance)
                .set(remainBalance==0,User::getStatus, UserStatus.FROZEN)
                .eq(User::getId, id)
                .eq(User::getBalance, user.getBalance()) // 乐观锁
                .update();

(十四) JSON处理器

在这里插入图片描述

在这里插入图片描述

@Data
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
public class UserInfo {

    private Integer age;

    private String intro;

    private String gender;
}

@Data
@TableName(value = "tb_user",autoResultMap = true)
public class User {

    /**
     * 用户id
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 注册手机号
     */
    private String phone;

    /**
     * 详细信息
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private UserInfo info;

    /**
     * 使用状态(1正常 2冻结)
     */
    private UserStatus status;

    /**
     * 账户余额
     */
    private Integer balance;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}

需要将xml以前使用mybatis创建的部分删干净,不然会报错,大概时info字段转换错误

<?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.itheima.mp.mapper.UserMapper">

    <update id="updateBalanceByIds">
        UPDATE tb_user SET balance = balance - ${amount} ${ew.customSqlSegment}
    </update>

</mapper>

在这里插入图片描述

(十四) 分页插件基本用法

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

@Configuration
public class MybatisPlusConfig {

    /**
     * 添加 MyBatis-Plus 插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        // 添加分页插件
        PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
        paginationInterceptor.setDbType(DbType.MYSQL); // 根据数据库类型设置
        paginationInterceptor.setOverflow(true);       // 溢出总页数后处理(默认false)
        paginationInterceptor.setMaxLimit(500L);       // 单页分页条数限制

        interceptor.addInnerInterceptor(paginationInterceptor);
        return interceptor;
    }
}
    @Test
    void testPageQuery(){
        int pageNo = 1, pageSize = 20;

        Page<User> page = Page.of(pageNo, pageSize);

        page.addOrder(new OrderItem("balance", true));
        page.addOrder(new OrderItem("id",true));
        Page<User> p = userService.page(page);

        long total = p.getTotal();
        System.out.println(total);
        long pages = p.getPages();
        System.out.println(pages);
        List<User> records = p.getRecords();
        records.forEach(System.out::println);


    }

在这里插入图片描述

(十五) 通用分页实体、与MP转换

在这里插入图片描述

@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery  extends  PageQuery{
    @ApiModelProperty("用户名关键字")
    private String name;
    @ApiModelProperty("用户状态:1-正常,2-冻结")
    private Integer status;
    @ApiModelProperty("余额最小值")
    private Integer minBalance;
    @ApiModelProperty("余额最大值")
    private Integer maxBalance;
}

@Data
public class PageQuery {
    @ApiModelProperty("页码")
    private Integer pageNo = 1;
    private Integer pageSize = 5;
    private String sortBy;
    private Boolean isAsc = true;

    public <T>  Page<T> toMpPage(OrderItem ... orders){
        // 1.分页条件
        Page<T> p = Page.of(pageNo, pageSize);
        // 2.排序条件
        // 2.1.先看前端有没有传排序字段
        if (sortBy != null) {
            p.addOrder(new OrderItem(sortBy, isAsc));
            return p;
        }
        // 2.2.再看有没有手动指定排序字段
        if(orders != null){
            p.addOrder(orders);
        }
        return p;
    }

    public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc){
        return this.toMpPage(new OrderItem(defaultSortBy, isAsc));
    }

    public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {
        return toMpPage("create_time", false);
    }

    public <T> Page<T> toMpPageDefaultSortByUpdateTimeDesc() {
        return toMpPage("update_time", false);
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageDTO<V> {
    private Long total;
    private Long pages;
    private List<V> list;

    /**
     * 返回空分页结果
     * @param p MybatisPlus的分页结果
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    public static <V, P> PageDTO<V> empty(Page<P> p){
        return new PageDTO<>(p.getTotal(), p.getPages(), Collections.emptyList());
    }

    /**
     * 将MybatisPlus分页结果转为 VO分页结果
     * @param p MybatisPlus的分页结果
     * @param voClass 目标VO类型的字节码
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    public static <V, P> PageDTO<V> of(Page<P> p, Class<V> voClass) {
        // 1.非空校验
        List<P> records = p.getRecords();
        if (records == null || records.size() <= 0) {
            // 无数据,返回空结果
            return empty(p);
        }
        // 2.数据转换
        List<V> vos = BeanUtil.copyToList(records, voClass);
        // 3.封装返回
        return new PageDTO<>(p.getTotal(), p.getPages(), vos);
    }

    /**
     * 将MybatisPlus分页结果转为 VO分页结果,允许用户自定义PO到VO的转换方式
     * @param p MybatisPlus的分页结果
     * @param convertor PO到VO的转换函数
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    public static <V, P> PageDTO<V> of(Page<P> p, Function<P, V> convertor) {
        // 1.非空校验
        List<P> records = p.getRecords();
        if (records == null || records.size() <= 0) {
            // 无数据,返回空结果
            return empty(p);
        }
        // 2.数据转换
        List<V> vos = records.stream().map(convertor).collect(Collectors.toList());
        // 3.封装返回
        return new PageDTO<>(p.getTotal(), p.getPages(), vos);
    }
}
    @ApiOperation("根据条件分页查询用户接口")
    @GetMapping("/page")
    public PageDTO<UserVO> queryUsersByPage(UserQuery userQuery){

        return userService.queryUsersByPage(userQuery);
    }
    @Override
    public PageDTO<UserVO> queryUsersByPage(UserQuery userQuery) {
        String name = userQuery.getName();
        Integer status = userQuery.getStatus();

        Page<User> page = Page.of(userQuery.getPageNo(), userQuery.getPageSize());
        if(StrUtil.isNotBlank(userQuery.getSortBy())){
            page.addOrder(new OrderItem(userQuery.getSortBy(), userQuery.getIsAsc()));
        }else{
            page.addOrder(new OrderItem("update_time", false));
        }
        Page<User> p = lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .page(page);

        PageDTO<UserVO> pageDTO = new PageDTO<>();
        pageDTO.setPages(p.getPages());
        pageDTO.setTotal(p.getTotal());
        List<User> records = p.getRecords();
        if(CollUtil.isEmpty(records)){
            pageDTO.setList(Collections.emptyList());
            return pageDTO;
        }
        List<UserVO> userVOS = BeanUtil.copyToList(records, UserVO.class);
        pageDTO.setList(userVOS);
        return pageDTO;
    }

在这里插入图片描述
在这里插入图片描述
封装改写。。。

在这里插入图片描述

Windows 11“此应用已被管理员阻止运行”解决方案 通过本文介绍的两种方法,你应该能够解决Windows 11中“此应用已被管理员阻止运行”的问题。无论你选择创建新管理员账户还是禁用管理员批准模式,都请确保了解相关操作的风险,并根据你的实际需求做出选择。通过禁用“用户账户控制:以管理员批准模式运行所有管理员”设置,可以解决因系统安全设置导致的应用程序被阻止运行的问题。这种方法适用于那些希望简化管理员账户操作流程的用户,但需要注意可能带来的安全风险。通过创建并登录具有管理员权限的新账户,可以解决因系统安全设置导致的应用程序被阻止运行的问题。 阅读详情

相关推荐

基于Python大数据的智能交通分析系统

该系统能够实时监测交通状况,分析交通流量,预测交通趋势,为交通管理部门提供决策支持,帮助缓解交通拥堵,提高交通运行效率,减少交通事故发生率,改善市民出行体验。它能够为交通管理部门提供决策支持,帮助缓解交通拥堵,提高交通运行效率,减少交通事故发生率,改善市民出行体验,促进交通产业的健康发展。数据采集层:通过传感器、GPS设备、交通摄像头等数据源,实时采集交通数据,如车辆速度、位置、道路拥堵情况等。数据分析层:运用统计学方法、机器学习算法等,对处理后的数据进行深入分析,挖掘交通规律,预测交通趋势。

qq3828614760的博客 2969

JDK17的Mybatis-Plus报错问题

添加 --add-opens java.base/java.lang=ALL-UNNAMED。

m0_61562689的博客 885

MQTT在智能家居中的实战:用Android手机控制ESP8266设备(基于EMQX)

本文详细介绍了如何利用MQTT协议构建一个完整的智能家居控制系统,通过Android手机App远程操控ESP8266设备。文章提供了从EMQX服务器部署、ESP8266端Arduino固件开发到Android客户端搭建的完整实战指南,并深入探讨了系统联调、稳定性优化与安全加固等关键环节,为物联网开发者提供了一套可复用的解决方案。

ujm567890的博客 456

某马2024SpringCloud微服务开发与实战 bug记录与微服务知识拆解(MybatisPlus、Docker、MQ、ES、Redis)第一章

>我这份文档是对官方文档的补充,比如官方文档没有记载P10的请求参数,这种东西没有什么营养,又容易漏写些东西,因此我记录了下来,您可以通过文字的目录快捷需要的东西

Java、Python、AI、前沿技术等领域的技术总结和经验分享。 1万+

基于51单片机的智能灌溉系统

基于51单片机的智能灌溉系统

jiejiezuishuai的博客 2100

深度解析 Android 开发工程师岗位:技术栈、职责与面试全攻略

本文深度剖析Android开发工程师职位要求,从核心技术栈到面试准备进行全面解读。关键点包括:1)掌握Kotlin语言特性和Jetpack组件;2)具备UI开发、性能优化和逆向分析能力;3)理解MVVM架构和Room数据库;4)熟悉常用工具链和开发流程。文章提供了详细的面试题库及解析,涵盖基础概念、UI优化、架构设计等方向,并给出职业发展建议:夯实基础、拓展技术广度、培养工程素养。旨在帮助开发者系统性地准备Android岗位求职,把握移动开发领域的技术趋势。

郑伟强dev的专栏 172

某马2024SpringCloud微服务开发与实战 bug记录与微服务知识拆解(MybatisPlus、Docker、MQ、ES、Redis)第五章

介绍了使用Sentinel进行请求限流、线程隔离、服务熔断等操作和分布式事务一致性处理方案seata 背景色是愧花黄绿

Java、Python、AI、前沿技术等领域的技术总结和经验分享。 1万+

Allegro如何改变线宽操作指导

用Allegro做pcb设计的时候,改变走线线宽是非常常用的功能,如下图。线宽目前是12mil,需要把线宽改成15mil。如何改变线宽操作指导。

weixin_54787054的博客 4254

某马2024SpringCloud微服务开发与实战 bug记录与微服务知识拆解(MybatisPlus、Docker、MQ、ES、Redis)第三章

2024最新SpringCloud微服务开发与实战bug记录与微服务知识拆解Day3 封面颜色是槐花黄绿

Java、Python、AI、前沿技术等领域的技术总结和经验分享。 1万+

Java 新纪元 — JDK 25 + Spring Boot 4 全栈实战(十九):微服务实战——Boot 4 + Spring Cloud 2026.x,构建高并发电商分布式系统

Component@Slf4j@Autowired// 白名单路径@Override// 白名单放行// 提取Token// 传递用户信息到下游服务.mutate().build();@Override// 最高优先级if (bearer!@Component技术点Boot 3 时代Boot 4 时代提升线程模型平台线程池(200线程上限)虚拟线程(百万级并发)50x+服务通信。

qq_17204557的博客 185

PCL Super4PCS算法实现点云粗配准(版本一)【2025最新版】

Win11系统下实现[Super4PCS: Fast Global Pointcloud Registration via Smart Indexing一文中的配准算法。

点云侠的博客 3377

某马2024SpringCloud微服务开发与实战 bug记录与微服务知识拆解(MybatisPlus、Docker、MQ、ES、Redis)第二章

2024最新SpringCloud微服务开发与实战bug记录与微服务知识拆解Day2

Java、Python、AI、前沿技术等领域的技术总结和经验分享。 7433

48、住宅抵押贷款支持证券的定价、风险评估与结构化设计

本文深入探讨了住宅抵押贷款支持证券(RMBS)的定价、风险评估与结构化设计。内容涵盖提高定价准确性的方差缩减方法,如准蒙特卡罗序列的应用;分析RMBS面临的利率风险、信用风险和模型风险,并提出相应的度量与应对策略;介绍利用动态规划优化CMO分层结构以最大化发行利润的方法。同时总结了RMBS的基本类型、定价流程及市场发展趋势,为投资者和发行人提供全面的决策支持。

quiet的专栏 154

某马2024SpringCloud微服务开发与实战 bug记录与微服务知识拆解(MybatisPlus、Docker、MQ、ES、Redis)第四章重制版

微服务项目的差错、网关概念重制版。精益求精,不看后悔 背景色是为愧花黄绿

Java、Python、AI、前沿技术等领域的技术总结和经验分享。 2万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

某马2024SpringCloud微服务开发与实战 bug记录与微服务知识拆解(MybatisPlus、Docker、MQ、ES、Redis)第四章

2024最新SpringCloud微服务开发与实战bug记录与微服务知识拆解Day4 背景颜色是槐花黄绿

Java、Python、AI、前沿技术等领域的技术总结和经验分享。 8753

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

2024最新SpringCloud微服务开发与实战,java黑马商城项目微服务实战开发(涵盖MybatisPlus、Docker、MQ、ES、Redis高级等)---MybatisPlus笔记分享

快速入门1. 引入MybatisPlus的起步依赖MyBatisPlus官方提供了starter,其中集成了Mybatis和MybatisPlus的所有功能,并且实现了自动装配效果。因此我们可以用MybatisPlus的starter代替Mybatis的starter:2. 定义Mapper自定义的Mapper继承MybatisPlus提供的BaseMapper接口:常见注解常见配置核心功能条件构造器除了新增以外,修改、删除、查询的SQL语句都需要指定where条件。

蓝桉 2895

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

黑马24年微服务课程MybatisPlus篇学习笔记---无图详细版

在演示UpdateWrapper的案例中,我们在代码中编写了更新的SQL语句:(“balance = balance - 200”) ,这种写法在某些企业也是不允许的,因为SQL语句最好都维护在持久层,而不是业务层。就当前案例来说,由于条件是in语句,只能将SQL写在Mapper.xml文件,利用foreach来生成动态SQL。这实在是太麻烦了。假如查询条件更复杂,动态SQL的编写也会更加复杂。

m0_46521733的博客 2386

黑马微服务课程2

我们可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。

2301_81298401的博客 1526

黑马最新MybatisPlus教程!帮你实现快速开发

MybatisPlus是一款开源的Java持久层框架,是基于Mybatis的增强工具,它通过封装底层细节,提供了简单、便捷的数据库操作方法,可以简化数据库操作,提高开发效率!

技术专家 388
上一篇: 【Java八股文总结 — 包学会】(二)计算机网络
下一篇: 【黑马SpringCloud微服务开发与实战】(三)微服务01
夜斗小神社
博客等级 码龄7年 3718粉丝 67原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值