mybatis-plus 用法总结

MyBatis-Plus(简称 MP)是 MyBatis 的增强工具,旨在简化开发者的 CRUD 操作。它在 MyBatis 的基础上提供了更多的功能和便利性,如代码生成器、分页插件、性能分析插件等,使开发者能够更高效地进行数据库操作。MyBatis-Plus 保持了 MyBatis 原有的灵活性和易用性,同时通过一些约定和默认实现减少了重复的代码编写。

1.常见注解

MybatisPlus会根据PO实体的信息来推断出表的信息,从而生成SQL的。默认情况下:

  • MybatisPlus会把PO实体的类名驼峰转下划线作为表名

  • MybatisPlus会把PO实体的所有变量名驼峰转下划线作为表的字段名,并根据变量类型推断字段类型

  • MybatisPlus会把名为id的字段作为主键

但很多情况下,默认的实现与实际场景不符,因此MybatisPlus提供了一些注解便于我们声明表信息。

1.1.@TableName

描述:表名注解,标识实体类对应的表

@TableName("user")
public class User {private Long id;private String name;
}

1.2@TableId

主键注解,标识实体类中的主键字段

属性

类型

必须指定

默认值

描述

value

String

""

表名

type

Enum

IdType.NONE

指定主键类型

@TableName("user")
public class User {@TableIdprivate Long id;private String name;
}

IdType支持的类型有:

描述

AUTO

数据库 ID 自增

NONE

无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)

INPUT

insert 前自行 set 主键值

ASSIGN_ID

分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)

ASSIGN_UUID

分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)

1.3@TableField

普通字段注解

@TableName("user")
public class User {@TableIdprivate Long id;private String name;private Integer age;@TableField("isMarried")private Boolean isMarried;@TableField("concat")private String concat;
}

一般情况下我们并不需要给字段添加@TableField注解,一些特殊情况除外:

  • 成员变量名与数据库字段名不一致

  • 成员变量是以isXXX命名,按照JavaBean的规范,MybatisPlus识别字段时会把is去除,这就导致与数据库不符。

  • 成员变量名与数据库一致,但是与数据库的关键字冲突。使用@TableField注解给字段名添加转义字符。

2.常见配置

大多数的配置都有默认值,因此我们都无需配置。但还有一些是没有默认值的,例如:

实体类的别名扫描包

2.1全局id类型

mybatis-plus:type-aliases-package: com.itheima.mp.domain.poglobal-config:db-config:id-type: auto # 全局id类型为自增长

2.2手写SQL

需要注意的是,MyBatisPlus也支持手写SQL的,而mapper文件的读取地址可以自己配置,默认值是classpath*:/mapper/**/*.xml,也就是说我们只要把mapper.xml文件放置这个目录下就一定会被加载。

mybatis-plus:mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mp.mapper.UserMapper"></mapper>

 3.Mapper 接口

mapper提供了一些常见的crud方法,继承于BaseMapper后可直接使用

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;public interface UserMapper extends BaseMapper<User> {
}

3.1条件构造器

除了新增以外,修改、删除、查询的SQL语句都需要指定where条件。因此BaseMapper中提供的相关方法除了以id作为where条件以外,还支持更加复杂的where条件。

Wrapper的子类AbstractWrapper提供了where中包含的所有条件构造方法

QueryWrapper在AbstractWrapper的基础上拓展了一个select方法,允许指定查询字段:

UpdateWrapper在AbstractWrapper的基础上拓展了一个set方法,允许指定SQL中的SET部分:

3.2新增

    @Testvoid 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.insert(user);}

3.3通过id查询

   @Testvoid testQueryById() {User user = userMapper.selectById(5L);System.out.println("user = " + user);}

 3.4通过id批量查询

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

 3.5查询一行数据

若实际上有多行数据,会报错

@Testvoid testSelectOne() {QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "特定用户名");User user = userMapper.selectOne(wrapper);System.out.println("user = " + user);}

3.6查询记录数

   @Testvoid testCount() {QueryWrapper<User> wrapper = new QueryWrapper<User>().like("username", "o");long count = userMapper.selectCount(wrapper);System.out.println("符合条件的用户数量: " + count);}

3.7Map查询

 @Testvoid testSelectByMap() {Map<String, Object> map = new HashMap<>();map.put("username", "Jack");map.put("phone", "13900112224");List<User> users = userMapper.selectByMap(map);users.forEach(System.out::println);}

3.8多条件构造查询

    @Testvoid testQueryWrapper() {// 1.构建查询条件 where name like "%o%" AND balance >= 1000QueryWrapper<User> wrapper = new QueryWrapper<User>().select("id", "username", "info", "balance").like("username", "o").ge("balance", 1000);// 2.查询数据List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}@Testvoid testLambdaQueryWrapper() {// 1.构建条件 WHERE username LIKE "%o%" AND balance >= 1000QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.lambda().select(User::getId, User::getUsername, User::getInfo, User::getBalance).like(User::getUsername, "o").ge(User::getBalance, 1000);// 2.查询List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}

3.9分页查询

  @Testvoid testPageQuery() {Page<User> page = new Page<>(1, 10); // 第一页,每页10条记录QueryWrapper<User> wrapper = new QueryWrapper<User>().orderByDesc("id");IPage<User> result = userMapper.selectPage(page, wrapper);result.getRecords().forEach(System.out::println);System.out.println("总记录数: " + result.getTotal());}

 3.10通过id更新

user中必须设置id,不然更新不了,没有设置默认为null。以为没有id=null的值,故不更新

其他参数没有设置,不会进行修改

   @Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}

 3.11构造条件更新

    @Testvoid testUpdateByQueryWrapper() {// 1.构建查询条件 where name = "Jack"QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "Jack");// 2.更新数据,user中非null字段都会作为set语句User user = new User();user.setBalance(2000);userMapper.update(user, wrapper);}

3.12自定义SQL更新

  @Testvoid testUpdateWrapper() {List<Long> ids = List.of(1L, 2L, 4L);// 1.生成SQLUpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance - 200") // SET balance = balance - 200.in("id", ids); // WHERE id in (1, 2, 4)// 2.更新,注意第一个参数可以给null,也就是不填更新字段和数据,// 而是基于UpdateWrapper中的setSQL来更新userMapper.update(null, wrapper);}

 3.13通过id删除

    @Testvoid testDeleteUser() {userMapper.deleteById(5L); //删除}

3.14通过id批量删除

    @Testvoid testDeleteUsers() {userMapper.deleteBatchIds(List.of(1L, 2L, 3L, 4L)); //批量删除}

4.Service 接口

mybatis-plus在service接口中同样也提供了基础的crud方法,在接口在需要继承IService类

import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.po.User;public interface IUserService extends IService<User> {// 拓展自定义方法
}

 实现IUserService接口,并指定mapper接口

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.po.service.IUserService;
import com.itheima.mp.mapper.UserMapper;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>implements IUserService {
}

4.1save新增

  • save是新增单个元素

  • saveBatch是批量新增

  • saveOrUpdate是根据id判断,如果数据存在就更新,不存在则新增

  • saveOrUpdateBatch是批量的新增或修改

4.2remove删除:

  • removeById:根据id删除

  • removeByIds:根据id批量删除

  • removeByMap:根据Map中的键值对为条件删除

  • remove(Wrapper<T>):根据Wrapper条件删除

  • removeBatchByIds

4.3update修改:

  • updateById:根据id修改

  • update(Wrapper<T>):根据UpdateWrapper修改,Wrapper中包含setwhere部分

  • update(T,Wrapper<T>):按照T内的数据修改与Wrapper匹配到的数据

  • updateBatchById:根据id批量修改

4.4查询一条Get:

  • getById:根据id查询1条数据

  • getOne(Wrapper<T>):根据Wrapper查询1条数据

  • getBaseMapper:获取Service内的BaseMapper实现,某些时候需要直接调用Mapper内的自定义SQL时可以用这个方法获取到Mapper

4.5批量查询List:

  • listByIds:根据id批量查询

  • list(Wrapper<T>):根据Wrapper条件查询多条数据

  • list():查询所有

4.6计数Count

  • count():统计所有数量

  • count(Wrapper<T>):统计符合Wrapper条件的数据数量

4.7分页

@Service
public class UserService extends ServiceImpl<UserMapper, User> {/*** 根据用户名获取用户列表的分页数据** @param currentPage 当前页码* @param pageSize 每页大小* @param username 用户名* @return 分页后的用户列表*/public IPage<User> getUserPageByName(int currentPage, int pageSize, String username) {// 创建分页对象Page<User> page = new Page<>(currentPage, pageSize);// 创建查询条件QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.like("username", username); // 使用 like 进行模糊匹配// 执行分页查询,带条件return this.page(page, queryWrapper);}
}

5.静态工具

有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法与IService中方法签名基本一致,也可以帮助我们实现CRUD功能。Db中的静态方法,必须

示例:

User.class表示查询user表中,id为1的值

@Test
void testDbGet() {User user = Db.getById(1L, User.class);System.out.println(user);
}

利用Db实现复杂条件查询

@Test
void testDbList() {List<User> list = Db.lambdaQuery(User.class).like(User::getUsername, "o").ge(User::getBalance, 1000).list();list.forEach(System.out::println);
}

我们采用了Db的静态方法,因此避免了注入其他service,减少了循环依赖的风险。

6.逻辑删除

用户注销账号后,我们往往不会真正的删除该用户,而是通过一个字段表示用户在逻辑上已经删除了。但是这样的操作,在以后业务查询上,都需要确认用户有没有删除,造成不必要的麻烦。假如deleted(1删除,0未删除)字段,我们仅需要在配置文件中进行下述配置,mybatis-plus就会自动进行判断

mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

注意,只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除。

7.定义枚举

import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;@Getter
public enum UserStatus {NORMAL(1, "正常"),FREEZE(2, "冻结");@EnumValue //标记枚举属性private final int value;@JsonValue //标记JSON序列化时展示的字段private final String desc;UserStatus(int value, String desc) {this.value = value;this.desc = desc;}
}

要让MybatisPlus处理枚举与数据库类型自动转换,我们必须告诉MybatisPlus,枚举中的哪个字段的值作为数据库值。 MybatisPlus提供了@EnumValue注解来标记枚举属性,并且在UserStatus枚举中通过@JsonValue注解标记JSON序列化时展示的字段

 配置枚举处理

mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

8.JSON类型处理器

数据库的user表中有一个info字段,是JSON类型:

{"age": 20, "intro": "佛系青年", "gender": "male"}

而目前User实体类中却是String类型:

这样一来,我们要读取info中的属性时就非常不方便。如果要方便获取,info的类型最好是一个Map或者实体类。

而一旦我们把info改为对象类型,就需要在写入数据库时手动转为String,再读取数据库时,手动转换为对象,这会非常麻烦。

因此MybatisPlus提供了很多特殊类型字段的类型处理器,解决特殊字段类型与数据库类型转换的问题。例如处理JSON就可以使用JacksonTypeHandler处理器。

接下来,我们就来看看这个处理器该如何使用。

定义实体

首先,我们定义一个单独实体类来与info字段的属性匹配:

import lombok.Data;@Data
public class UserInfo {private Integer age;private String intro;private String gender;
}

3.4.2.使用类型处理器

接下来,将User类的info字段修改为UserInfo类型,并声明类型处理器:

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

9.配置加密

目前我们配置文件中的很多参数都是明文,如果开发人员发生流动,很容易导致敏感信息的泄露。所以MybatisPlus支持配置文件的加密和解密功能。

我们以数据库的用户名和密码为例。

生成秘钥

首先,我们利用AES工具生成一个随机秘钥,然后对用户名、密码加密:

    @Testvoid contextLoads() {// 生成 16 位随机 AES 密钥String randomKey = AES.generateRandomKey();System.out.println("randomKey = " + randomKey);// 利用密钥对用户名加密String username = AES.encrypt("root", randomKey);System.out.println("username = " + username);// 利用密钥对用户名加密String password = AES.encrypt("MySQL123", randomKey);System.out.println("password = " + password);}

randomKey = 6234633a66fb399f

username = px2bAbnUfiY8K/IgsKvscg==

password = FGvCSEaOuga3ulDAsxw68Q==

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=truedriver-class-name: com.mysql.cj.jdbc.Driverusername: mpw:QWWVnk1Oal3258x5rVhaeQ== # 密文要以 mpw:开头password: mpw:EUFmeH3cNAzdRGdOQcabWg== # 密文要以 mpw:开头

 10.分页插件

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MybatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 初始化核心插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 添加分页插件interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}
@Test
void testPageQuery() {// 1.分页查询,new Page()的两个参数分别是:页码、每页大小Page<User> p = userService.page(new Page<>(2, 2));// 2.总条数System.out.println("total = " + p.getTotal());// 3.总页数System.out.println("pages = " + p.getPages());// 4.数据List<User> records = p.getRecords();records.forEach(System.out::println);
}

这里用到了分页参数,Page,即可以支持分页参数,也可以支持排序参数。

int pageNo = 1, pageSize = 5;
// 分页参数
Page<User> page = Page.of(pageNo, pageSize);
// 排序参数, 通过OrderItem来指定
page.addOrder(new OrderItem("balance", false));userService.page(page);

分页实体PageDTO

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.List;@Data
@ApiModel(description = "分页结果")
public class PageDTO<T> {@ApiModelProperty("总条数")private Long total;@ApiModelProperty("总页数")private Long pages;@ApiModelProperty("集合")private List<T> list;
}

定义分页查询时,查询的页号。用于前端的参数

@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {@ApiModelProperty("页码")private Long pageNo;@ApiModelProperty("页面大小")private Long pageSize;@ApiModelProperty("排序字段")private String sortBy;@ApiModelProperty("是否升序")private Boolean isAsc;
}

11.自动填充

我们在设计表时,一般都需要保存数据的创建时间和更新时间,为了不必要的麻烦,每次都需要设置,我们可以使用mybatis-plus提供的进行自动填充

 构造抽象类

后续所有的实体类,都可以继承这个基础的实体类,以提高代码的复用性

在需要自动创建更新的属性上,加上@TableField注解

public abstract class BasePojo {//文件创建,自动填充。需要实现MetaObjectHandle接口,进行处理@TableField(fill = FieldFill.INSERT)private Date created;//文件更新,自动填充@TableField(fill = FieldFill.INSERT_UPDATE)private Date updated;
}

实现MetaObjectHandle接口

package com.tanhua.sso.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {// 使用严格模式插入填充,如果字段为null则进行填充this.strictInsertFill(metaObject, "created", Date.class, new Date()); // 创建时间this.strictInsertFill(metaObject, "updated", Date.class, new Date()); // 更新时间}@Overridepublic void updateFill(MetaObject metaObject) {// 使用严格模式更新填充,总是设置更新时间this.strictUpdateFill(metaObject, "updated", Date.class, new Date());}
}

版本兼容性问题

若业务中mybatis-plus版本较低,可能不含strict方法,可以采用以下写法

package com.tanhua.sso.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {//字段为空,自动填充字段Object created = getFieldValByName("created", metaObject);if(null==created){setFieldValByName("created",new Date(),metaObject);}Object updated = getFieldValByName("updated", metaObject);if(null==updated){setFieldValByName("updated",new Date(),metaObject);}}@Overridepublic void updateFill(MetaObject metaObject) {//更新数据时,更新字段setFieldValByName("updated",new Date(),metaObject);}
}

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

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

相关文章

【ETCD】【实操篇(十五)】etcd集群成员管理:如何高效地添加、删除与更新节点

etcd 是一个高可用的分布式键值存储&#xff0c;广泛应用于存储服务发现、配置管理等场景。为了确保集群的稳定性和可扩展性&#xff0c;管理成员节点的添加、删除和更新变得尤为重要。本文将指导您如何在etcd集群中处理成员管理&#xff0c;帮助您高效地维护集群节点。 目录 …

前端 学习

vue结构 package.json 作用&#xff1a;记录项目的元信息&#xff0c;包括依赖包、脚本命令、项目名称、版本号等。 常见字段&#xff1a; dependencies&#xff1a;运行时依赖的 npm 包。 devDependencies&#xff1a;开发时使用的依赖包。 scripts&#xff1a;定义 npm 脚本…

网易企业邮箱登陆:保障数据安全

网易企业邮箱是一款为企业提供安全可靠的电子邮件服务的工具。通过网易企业邮箱&#xff0c;企业可以实现员工之间的高效沟通和信息共享&#xff0c;同时保障数据的安全性。 企业邮箱的安全性是企业信息保护的重要组成部分。网易企业邮箱采用了多层加密技术&#xff0c;确保邮件…

王佩丰24节Excel学习笔记——第二十二讲:制作甘特图与动态甘特图

【以 Excel2010 系列学习&#xff0c;用 Office LTSC 专业增强版 2021 实践】 【本章技巧】 插入图表&#xff0c;针对每一个图表上的元素&#xff0c;都可以选中选右键进行修改数据&#xff1b;本章中的向两端延伸&#xff0c;设置数据的原理&#xff1b;数据格式的显示方式&…

Kubernetes之NodeSelector与NodeName实战

目录 目标 版本 官网 概述 实战 NodeName实战 NodeSelector实战 目标 通过配置NodeSelector与NodeName实现Pod运行&#xff08;或优先运行&#xff09;在我们期望的节点之上。了解这两种实现方法的区别。 版本 Kubernets v1.25.0 官网 将Pod分配给节点https://kubernet…

【docker系列】打造个人私有网盘zfile

1. 介绍 是一个适用于个人的在线网盘(列目录)程序&#xff0c;可以将你各个存储类型的存储源&#xff0c;统一到一个网页中查看、预览、维护&#xff0c;再也不用去登录各种各样的网页登录后管理文件 2. 需要环境 2.1 硬件需求 CPU&#xff1a;至少1核 内存&#xff1a;推荐…

系统思考—冰山模型

“卓越不是因机遇而生&#xff0c;而是智慧的选择与用心的承诺。”—— 亚里士多德 卓越&#xff0c;从来不是一次性行为&#xff0c;而是一种习惯。正如我们在日常辅导中常提醒自己&#xff1a;行为的背后&#xff0c;隐藏着选择的逻辑&#xff0c;而选择的根源&#xff0c;源…

麒麟信安参展南京软博会,支持信创PC的新一代云桌面及全行业解决方案备受瞩目

12月20日至22日&#xff0c;由中国软件行业协会、江苏省软件行业协会等单位联合主办的2024中国&#xff08;南京&#xff09;软件产业博览会在南京国际博览中心隆重开幕。本届博览会以“软件驱动未来&#xff0c;数字闪耀金陵”为主题&#xff0c;吸引了各界目光&#xff0c;省…

【PLL】电荷泵锁相环各个环路参数意义

电荷泵锁相环(CPPLL)在模拟锁相环占据主导&#xff0c; 因为在环路中实现了积分器&#xff0c;而没有有缘放大器即&#xff1a;type 2锁相环可以使用无源RC滤波器实现&#xff0c;简化了PLL设计。 简单CPPLL 与C1串联电阻R1形成零点。 电容累积相位误差&#xff0c;提供积分路…

Java 网络原理 ①-IO多路复用 || 自定义协议 || XML || JSON

这里是Themberfue 在学习完简单的网络编程后&#xff0c;我们将更加深入网络的学习——HTTP协议、TCP协议、UDP协议、IP协议........... IO多路复用 ✨在上一节基于 TCP 协议 编写应用层代码时&#xff0c;我们通过一个线程处理连接的申请&#xff0c;随后通过多线程或者线程…

考研互学互助系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库…

SpringBoot使用外置的Servlet容器(详细步骤)

嵌入式Servlet容器&#xff1a;应用打成可执行的jar 优点&#xff1a;简单、便携&#xff1b; 缺点&#xff1a;默认不支持JSP、优化定制比较复杂.&#xff1b; 外置的Servlet容器&#xff1a;外面安装Tomcat---应用war包的方式打包&#xff1b; 操作步骤&#xff1a; 方式一&…

Unity中的LayoutGroup与LayoutElement的实战应用

在开发中遇到过一个问题&#xff0c;首先我们是在4k分辨率下开发的&#xff0c;界面要求如下 我们以第二行为例子&#xff0c;第二行有3个界面&#xff0c;其中中间的界面是比较长的 面板中使用Vertical和Horizontal排列&#xff0c;并且勾选了ControlChildSize和ChildForceEx…

反应力场的生成物、反应路径分析方法

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…

“自动驾驶第一股” 图森未来退市转型:改名 CreateAI、发布图生视频大模型 “Ruyi”

12 月 19 日&#xff0c;自动驾驶公司图森未来&#xff08;TuSimple&#xff09;宣布启用全新品牌 CreateAI&#xff0c;并发布多项在生成式 AI 领域的进展。 CreateAI 宣布获著名武侠 IP《金庸群侠传》正版授权&#xff0c;将开发一款大型武侠开放世界 RPG 游戏。 新的 Creat…

FreeRTOS实战——一、基于HAL库项目的FreeRTOS移植步骤

FreeRTOS实战——一、基于HAL库项目的移植步骤 文章目录 FreeRTOS实战——一、基于HAL库项目的移植步骤前言一、下载和移植FreeRTOS二、系统文件配置2.1 FreeRTOSConfig.h中添加如下3个配置&#xff1a;2.2 修改stm32f1xx_it.c 前言 废话不多说&#xff0c;在FreeRTOS基础&…

编程初学者使用 MariaDB 数据库反射生成

编程初学者使用 MariaDB 数据库反射生成 数据库反射生成&#xff0c;是动词算子式通用代码生成器提供的高级功能&#xff0c;可以利用已有的数据库&#xff0c;反射生成相应数据库的前端和后端项目。此功能自动化程度很高&#xff0c;并且支持完善的元数据和数据编辑&#xff…

yolov6算法及其改进

yolov6算法及其改进 1、YOLOV6简介2、RepVGG重参思想3、YOLOv6架构改进3.1、Backbone方面3.2、SPP改进3.3、Neck改进3.4、Head改进 4、正负样本匹配与损失函数4.1、TaskAligned样本匹配4.2、VFL Loss分类损失函数4.3、SIOU损失函数4.4、DFL损失函数 1、YOLOV6简介 YOLOv6设计主…

面试241228

面试可参考 1、cas的概念 2、AQS的概念 3、redis的数据结构 使用场景 不熟 4、redis list 扩容流程 5、dubbo 怎么进行服务注册和调用&#xff0c;6、dubbo 预热 7如何解决cos上传的安全问题kafka的高并发高吞吐的原因ES倒排索引的原理 spring的 bean的 二级缓存和三级缓存 spr…

小程序配置文件 —— 13 全局配置 - window配置

全局配置 - window配置 这里讲解根目录 app.json 中的 window 字段&#xff0c;window 字段用于设置小程序的状态栏、导航条、标题、窗口背景色&#xff1b; 状态栏&#xff1a;顶部位置&#xff0c;有网络信号、时间信息、电池信息等&#xff1b;导航条&#xff1a;有一个当…