Mybatis-Plus学习:快速入门、核心功能、扩展功能、插件功能

news2024/10/6 4:05:25

文章目录

  • MybatisPlus
    • 快速入门
      • 快速开始
      • 常见注解
      • 常见配置
    • 核心功能
      • 条件构造器(Wrapper)
      • 自定义SQL
      • Service接口
        • 基本用法
        • 基础业务接口
        • 复杂业务接口
        • Lamda查询
        • Lamda更新
        • 批量新增
    • 扩展功能
      • 代码生成
        • 代码生成器
        • 快速开发插件
      • 静态工具
      • 逻辑删除
      • 枚举处理器
      • JSON处理器
    • 插件功能
      • 分页插件
        • 通用分页实体
      • 乐观锁插件
        • 示例

MybatisPlus

快速入门

快速开始

  1. 引入依赖
<!--引入MP后,自然替代原Mybatis-->
<dependency>
	<groupId>com.baomidou</groudId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.5.3.1</version>
</dependency>
  1. Mapper继承
//自定义Mapper继承MP提供的BaseMapper接口
public interface UserMapper extends BaseMapper<User> {...}
  1. 实体类中添加注解声明表信息
  2. application.yml中添加配置
  3. 根据需求选择对应方法
    在这里插入图片描述

常见注解

MyBatisPlus通过扫描实体类,并基于反射获取实体类信息作为数据库表信息

  1. 约定大于配置
  • 类名驼峰转下划线作为表名(eg. UserInfo—>user_info)
  • 名为id的字段作为主键
  • 变量名驼峰转下划线作为表的字段名(eg. LocalDataTime—>local_data_time)
  1. 常用注解
  • @TableName:用于指定表名(eg. @TableName(“表名”)
  • @TableId:用于指定表中主键字段,可通过类型指定实现:
  • 自增:AUTO (eg. @TableId(“id”, type = IdType.AUTO)
  • set注入:INPUT
  • 自动分配:ASSIGN_ID,默认设置,使用雪花算法随机分配
  • @TableField:用于指定表中普通字段
  • 成员变量名与数据库字段名不一致
  • 成员变量名以is开头,但为布尔值(eg. @TableField(“is_graduate”)
  • 成员变量名与数据库关键词冲突(eg. @TableField(" ‘order’ ")
  • 成员变量名不是数据库字段(eg. @TableField(exist = false)
  1. 全部注解
    MabatisPlus注解

常见配置

在这里插入图片描述
MybatisPlus使用配置

核心功能

条件构造器(Wrapper)

  1. MP通过Wrapper支持复杂where条件,满足常用开发需求
    在这里插入图片描述
    子类AbstractWrapper
    在这里插入图片描述
    子类QueryWrapper
    在这里插入图片描述
    子类UpdateWrapper
    在这里插入图片描述
  2. 示例
/*
*查询名称带'o'的,且存款大于1000的id、username、info、balance
*select id, username, info, balance from user where username like '%o%' and balance >= 1000
*/
@Test
void testQueryWrapper() {
	//1.condition
	QueryWrapper<User> wrapper = new QueryWrapper<User>()
		.select("id", "username", "info", "balance")
		.like("username", "o")
		.ge("balance", 1000);
	//2.query
	List<User> users = userMapper.selectList(Wrapper);
	user.forEach(System.out.println);
}
/*
*更新用户名为`jack`的用户的余额为2000
*update user set balance = 2000 where (username = 'jack')
*/
@Test
void testUpdateByQueryWrapper() {
	//1.data
	User user = new User();
	user.setBalance(2000);
	//2.condition
	QueryWrapper<User> wrapper = new QueryWrapper<User>()
		.eq("username", "jack");
	//3.update
	userMapper.update(user, wrapper);
}
/*
*更新id为`1` `2` `4`的用户的余额,扣除200
*update user set balance = balance - 200 where id in (1, 2, 4)
*/
@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) ;
}
/*
*使用LamdaQueryWrapper替代第一个示例
*/
@Test
void testLamdaQueryWrapper() {
	//1.condition
	QueryWrapper<User> wrapper = new QueryWrapper<User>()
		.select(user::getId, User::getUsername, User::getInfo, User::getBalance)
		.like(User::getUsername, "o")
		.ge(User::getBalance, 1000);
	//2.query
	List<User> users = userMapper.selectList(Wrapper);
	user.forEach(System.out.println);
}
  1. 用法:
  • QueryWrapperLamdaQueryWrapper构建select delete updatewhere条件部分
  • UpdateWrapperLamdaUpdateWrapper通常只在set语句使用
  • 尽量使用LamdaQueryWrapperLamdaUpdateWrapper来避免硬编码

自定义SQL

  1. 使用Wrapper构建where条件后,自定义SQL语句补充在这里插入图片描述2. 示例
/*
*基于Wrapper构建where条件
*/
List<Long> ids = List.of(1L, 2L, 4L);
int amount = 200;
//1.condition
LamdaQueryWrapper<User> wrapper = new LamdaQueryWrapper<User>.
	.in(User::getId, ids);
//2.custom
userMapper.updateBalanceByIds(wrapper, amount);
/*
*mapper方法参数中用Param注解声明wrapper变量名,必须为ew
*/
void updateBalanceByIds(@Param("ew") LamdaQueryWrapper<User> wrapper, @Param("amount") int amount);
<!--自定义SQL,并使用Wrapper条件-->
<update id="updateBalanceByIds>
	UPDATE user SET balance = balance - #{amount} ${ew.customSqlSegment}
</update>

Service接口

在这里插入图片描述

基本用法

在这里插入图片描述

  1. 自定义接口继承IService接口
//指定实体类型
public interface IUserService extend IService<User> {...}
  1. 自定义实现类继承ServiceImpl实现类
@Service
//指定泛型类型和实体类型,通过反射获取对应内容
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {...}
基础业务接口
  1. 基于Restful风格实现下面接口
    在这里插入图片描述

  2. 引入依赖

<!--swagger-->
<dependency>
	<groupId>com.github.xiaoymin</groupId>
	<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
	<version>4.1.0</version>
<dependency>
<!--web-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
<dependency>
  1. 配置swagger
knife4j:
  enable:true
  openapi:
    title:用户管理接口文档
    description:"用户管理接口文档"
    contact:jobs
    version:v1.0.0
    group:
     default:
       group-name:default
       api-rule:package
       api-rule-resource:
         - com.jobs.mp.controller
  1. 创建对应DTO、PO、VO实体
  2. 创建Controller类
@Api(tags = "用户管理接口")
@RequestMapping("/user")
@RestController
@RequiredArgsConstructor//必要参数构造方法,结合下列 final 关键字,使IUserService能够完成必要参数的构造后注入,不需要处理其中到底有多少个参数
public class UserController {
	private final IUserService userService;
	
	@ApiOperation("新增用户接口")
	@PostMapping
	public void savaUser(@RequestBody UserFormDTO userDTO) {
		//1.copy DTO to PO
		User user = BeanUtil.copyProperties(userDTO, User.class);
		//2.save
		userService.save(user);
	}
	
	@ApiOperation("删除用户接口")
	@DeleteMapping("{id}")
	public void queryUserById(@ApiParam("用户id") @PathVariable("id") Long id) {
		userService.removeById(id);
	}
	
	@ApiOperation("根据id查询用户接口")
	@GetMapping("{id}")
	public UserVo lamdaQueryUserById(@ApiParam("用户id") @PathVariable("id") Long id) {
		//1.get
		User user = userService.getById(id);
		//2.copy PO to VO
		return BeanUtil.copyProperties(User, UserVO.class);
	}

	@ApiOperation("根据id批量查询用户接口")
	@GetMapping
	public List<User> lamdaQueryUserById(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids) {
		//1.get
		List<User> users = userService.listByIds(ids);
		//2.copy PO to VO
		return BeanUtil.copyToList(Users, UserVO.class);
	}
}
复杂业务接口

在这里插入图片描述

  1. UserMapper接口中声明方法
public interface UserMapper extends BaseMapper<User> {
	@Update("UPDATE user SET balance = balance - #{money} WHERE id = #{id}")
	void deductBalance(@Param("id") Long id, @Param("money") Integer money);
}
  1. Service接口中声明方法
public interface IUserService extends IService<User> {
	public void deductBalance(Long id, Integer money);
}
  1. Service实现类中定义方法
@Service
public class UserServiceImpl extends ServiceImpl implements IUserService {
	@Override
	public void deductBalance(Long id, Integer money) {
		//1.query
		User user = getById(id);
		//2.check status
		if (user == null || user.getStatus() == 2) {
			throw new RuntimeException("用户状态异常!");
		}
		//3.check balance
		if (user.getBalance() < money) {
			throw new RuntimeException("用户余额不足!");
		}
		//4. deduct
		baseMapper.deductBalance(id, money);
	}
}
  1. Controller类中完成接口
@ApiOperation("扣减用户余额接口")
@PutMapping("/{id}/deduction/{money}")
public void deductBalance(@ApiParam("用户id") @PathVariable("id") Long id,
	@ApiParam("扣减金额") @PathVariable("money") Integer money) {
	userService.deductBalance(id, money);
}
Lamda查询

在这里插入图片描述

  1. 定义查询类
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery {
	@ApiModelProperty("用户名关键字")
	private String name;
	@ApiModelProperty("用户状态:1-正常,2-冻结")
	private Integer status;
	@ApiModelProperty("余额最小值")
	private Integer minBalance;
	@ApiModelProperty("余额最大值")
	private Integer maxBalance;
}
  1. Service接口声明方法
public interface IUserService extends IService<User> {
	public void deductBalance(Long id, Integer money);
	
	List<User> queryUser(String name, Integer status, Integer minBalance, Integer maxBalance);
}
  1. Service实现类定义方法
@Service
public class UserServiceImpl extends ServiceImpl implements IUserService {
	@Override
	public void deductBalance(Long id, Integer money) {...}

	@Override
	public List<User> queryUser(String name, Integer status, Integer minBalance, Integer maxBalance) {
		return lamdaQuery()
			.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();
	}
}
  1. Controller类中完成接口
@ApiOperation("根据复杂条件查询用户接口")
@GetMapping("/list")
public List<UserVO> queryUsers(UserQuery query) {
	//1. query
	List<User> users = userService.queryUsers(
		query.getName(),
		query.getStatus(),
		query.getMinBalance(),
		query.getMaxBalance());
	//2. copy PO to VO
	return BeanUtil.copyToList(users, UserVO.class);
}
Lamda更新

在这里插入图片描述

  1. Service实现类中更改扣除流程
@Override
@Transactional
public void deductBalance(Long id, Integer money) {
	//1.query
	User user = getById(id);
	//2.check status
	if (user == null || user.getStatus() == 2) {
		throw new RuntimeException("用户状态异常!");
	}
	//3.check balance
	if (user.getBalance() < money) {
		throw new RuntimeException("用户余额不足!");
	}
	//4. deduct
	int remainBalance = user.getBalance() - money;
	lamdaUpdate()
		.set(User::getBalance, remainBalance)
		.set(remainBalance == 0, User::getStatuse, 2)
		.eq(User::getId, id)
		.eq(User::getBalance, user.getBalance())//乐观锁
		.update();
}
批量新增

在这里插入图片描述

  1. 普通for循环逐条插入,性能极差
@Test
void testSaveOneByOne() {
	long startTime = System.currentTimeMillis();
	for (int i = 1; i <= 100000; i++) {
		userService.save(buildUser(i));
	}
	long endTime = System.currentTimeMillis();
	System.out.println(endTime - startTime;
}

// 10^5 ms
  1. MP批量新增,基于预编译的批处理,性能较好
@Test
void testSaveBatch() {
	//1000 per time, 100 times
	//create list
	List<User> list = new ArrayList<>(1000);
	long startTime = System.currentTimeMillis();
	for (int i = 1; i <= 100000; i++) {
		//insert object
		list.add(buildUser(i));
		//each time insert once
		if (i % 1000 == 0) {
			userService.saveBatch(list);
			//clear
			list.clear();
		}
	}
	long endTime = System.currentTimeMillis();
	System.out.println(endTime - startTime);
}

// 10^4 ms
  1. 配置jdbc参数,性能最佳
rewriteBatchedStatements = true

# 10^3 ms
  1. 优化策略
  • 网络请求耗时多,减少网络请求(1—>2)
  • SQL语句多条耗时多,减少为一条(2—>3)

扩展功能

代码生成

代码生成器

引入官方依赖,在配置文档中设定生成代码
较复杂

快速开发插件
  • MyBatisX官方插件
  • MyBatisPlus插件
  1. 安装插件
  2. 连接数据库
  3. 选择要生成代码的表(可多选)
  4. 按照选填项完成设置
  5. 生成PO **Mapper I**Service **ServiceImpl **Controller等内容

静态工具

为了避免表间循环调用的情况,可使用静态Db方法代替复杂注入
在这里插入图片描述

  1. Service接口声明方法
public interface IUserService extends IService<User> {
	public void deductBalance(Long id, Integer money);
	
	List<User> queryUser(String name, Integer status, Integer minBalance, Integer maxBalance);

	List<User> queryUserAndAddressByIds(List<Long> ids);
}
  1. Service实现类中定义方法
@Override
public List<User> queryUserAndAddressByIds(List<Long> ids) {
	//1.user query
	List<User> users = listByIds(ids);
	if (CollUtil.isEmpty(user)) {
		return Collections.emptyList();
	}
	//2.address query
	//2.1.get user list
	List<Long> userIds = users.stream().map(User::getId).collect(Collections.toList());
	//2.2.get address list by userId
	List<Address> addresses = Db.lamdaQuery(Address.class).in(Address::getUserId, userIds).list());
	//2.3.transfer addressPO to VO
	List<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);
	//2.4.grouping user`s address, one user`s address put into same collection
	Map<Long, List<AddressVO> addressMap = new HashMap<>(0);
	if (collUtil.isNotEmpty(addressVOList)) {
		addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));
	}
	//3.transfer User to UserVO
	List<UserVO> list = new ArrayList<>(users.size());
	for (User user : user) {
		//3.1.transfer UserPO to VO
		UserVO vo = BeanUtil.copyProperties(user, UserVO.class);
		list.add(vo);
		//3.2.transfer addressPO to VO
		vo.setAddresses(addressMap.get(user.getId());
	}
	return list;
}
  1. Controller类中实现接口
@ApiOperation("根据id批量查询用户接口")
@GetMapping
public List<User> lamdaQueryUserById(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids) {
	return userService.queryUserAndAddressByIds(ids);
}

逻辑删除

  1. 基于代码逻辑模拟删除效果,但并不真正删除数据
eg.
UPDATE user SET deleted = 1 WHERE id = 1 AND deleted = 0
  1. 配置方式
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag # 全局逻辑删除的实体字段名,可以为boolean、integer
      logic-delete-value: 1 # 逻辑已删除值(默认为1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为0)
  1. 问题
  • 数据库表垃圾数据增加,影响查询效率
  • SQL使用全都需要对逻辑删除字段做判断,影响查询效率
  1. 可通过数据迁移弥补逻辑删除的缺陷
  2. 失效原因及解决
  • MP依赖与代码生成器依赖版本不一致
  • 切换相同版本依赖

枚举处理器

  1. 配置
mybatis-plus:
  configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
  1. 状态类
@Getter
public enum UserStatus {
	NORMAL(1, "正常"),
	FROZEN(2, "冻结"),
	;
	@EnumValue
	private final int value;
	@JsonValue //返回时传输该注解标记的值
	private final String desc;

	UserStatus(int value, String desc) {
		this.value = value;
		this.desc = desc;
	}
}
  1. 使用
eg.
if (user == null || user.getStatus() == UserStatus.FROZEN) {...}

JSON处理器

eg.

#名称数据类型注释长度
5infoJSON详细信息
  1. 对应字段创建实体类
@Data
public class UserInfo {
	private Integer age;
	private String intro;
	private String gender;
}
  1. 字段标注注解,并指定类型处理器
...
@TableField(typeHandler = JacksonTypeHandler.class)
private UserInfo info;
...
  1. 向表类添加注解,开启映射
@Data
@TableName(value="user", autoResultMap=true)
public class User {...}

插件功能

拦截器描述
TenantLineInnerInterceptor多租户插件
DynamicTableNameInnerInterceptor动态表名插件
PaginationInnerInterceptor分页插件
OptimisitcLockerInnerInterceptor乐观锁插件
IllegalSQLInnerInterceptorSQL性能规范插件(检测并拦截垃圾SQL)
BlockAttackInnerInterceptor防止全表更新和删除的插件

分页插件

  1. 配置类中注册MP核心插件,添加分页插件
@Configuration
public class MybatisConfig {
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		//初始化核心插件
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		//添加分页插件
		PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
		pageInterceptor.setMaxLimit(1000L);//设置分页上限
		interceptor.addInnerInterceptor(pageInterceptor);
		return interceptor;
	}
}
  1. ServiceTest类中使用分页插件
@Test
void testPageQuery() {
	int pageNo = 1, pageSize = 2;
	//1.prepare pagination
	//1.1.page condition
	Page<User> page = Page.of(pageNo, pageSize);
	//1.2.sort condition
	page.addOrder(new OrderItem("balance", true));
	page.addOrder(new OrderItem("id", true));
	//2.pagination query
	Page<User> p = userService.page(page);
	//3.analysis
	long total = p.getTotal();
	System.out.println("total = " + total);
	long pages = p.getPages();
	System.out.println("pages = " + pages);
	List<User> users = p.getRecords();
	users.forEach(System.out::println);
}
通用分页实体

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

  1. 分页查询实体UserQuery.java
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description="用户查询条件实体")
public cl ass UserQuery extends PageQuery {
	@ApiModelProperties("用户名关键字")
	private String name;
	@ApiModelProperties("用户状态:1-正常,2-冻结")
	private Integer status;
	@ApiModelProperties("余额最小值")
	private Integer minBalance;
	@ApiModelProperties("余额最大值")
	private Integer maxBalance;
}
  1. PageDTO.java
@Data
@ApiModel(description="分页结果")
public class PageDTO<T> {
	@ApiModelProperties("总条数")
	private Integer total;
	@ApiModelProperties("总页数")
	private Integer pages;
	@ApiModelProperties("集合")
	private Integer list;
}
  1. Service接口声明
...
PageDTO<UserVO> queryUsersPage(UserQuery query);
...
  1. Service实现类定义
@Override
public PageDTO<UserVO> queryUsersPage(UserQuery query) {
	String name = query.getName();
	Integer status = query.getStatus();
	//1.condition
	//1.1.page condition
	Page<User> page = Page.of(query.getPageNo(), query.getPageSize());
	//1.2.sort condition
	if (StrUtil.isNotBlank(query.getSortBy())) {
		//not null
		page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));
	}else {
		//null, sory by update time
		page.addOrder(new OrderItem("update_time", false));
	}
	//2.pagination query
	Page<User> p = lamdaQuery()
		.like(name != null, User::getUsername, name)
		.eq(status != null, User::getStatus, status)
		.page(page);
	//3.pack VO
	PageDTO<UserVO> dto = new PageDTO<>();
	//3.1.total records
	dto.setTotal(p.getTotal());
	//3.2.total pages
	dto.setPages(p.getPages());
	//3.3.current page
	List<User> records = p.getRecords();
	if (CollUtil.isEmpty(records)) {
		dto.setList(Collections.emptyList());
		return dto;
	}
	//3.4.copy user`s VO
	dto.setList(BeanUtil.copyToList(records, UserVO.class));
	//4.return
	return dto
}
  1. Controller类中实现
@ApiOperation("根据条件分页查询用户接口")
@GetMapping("/List")
public PageDTO<UserVO> queryUsersPage(UserQuery query) {
	return userService.queryUsersPage(query);
}

乐观锁插件

  1. 定义
  • 乐观锁:认为操作数据时始终处于乐观状态,不会有他人同时修改数据。因此乐观锁不会上锁,只在执行更新时判断他人是否在此期间修改过该数据,若修改则放弃本次操作,否则执行;
  • 悲观锁:认为操作始终处于悲观状态,存在他人同时修改数据。因此悲观锁操作时直接锁定数据,操作结束后才会释放,期间他人无法修改该数据
  1. 实现方式
  • 取出记录时,获取当前version
  • 更新时附带此version
  • 执行更新时,判定SET version = newVersion WHERE version = oldVersion
  • 如果version不对,则更新失败
示例
  1. 表实体中加上version
@Data
@TableNmae("user")
public class User {
	...
	//数据库表中也应有此字段
	@Version
	@TableField(value = "version")
	private Integer version;
}
  1. 启动类加上注解@MapperScan(basePackages = "com.kaven.mybatisplus.dao")
  2. 添加插件
@Configuration
public class MybatisConfig {
	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		//初始化核心插件
		MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
		//添加分页插件
		PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
		pageInterceptor.setMaxLimit(1000L);//设置分页上限
		interceptor.addInnerInterceptor(pageInterceptor);
		//添加乐观锁插件
		interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
		
		return interceptor;
	}
}
  1. 测试
@SpringBootTest
public class LockerTest {
	@Autowired
	private UserMapper userMapper;
	@Test
	public void updateById() {
		User user = userMapper.selectById("1");
		int version = user.getVersion();
		user.setPassword("new password");
		user.setVersion(version);
		int rows = userMapper.updateById(user);
		System.out.println("infect: " + rows);
	}
}
  1. 说明
  • 支持的数据类型有:int Integer long Long Date Timestamp LocalDateTime
  • 整数类型下newVersion = oldVersion + 1
  • newVersion会写回到entity
  • 仅支持updateById(entity)update(entity, wrapper)方法
  • update(entity, wrapper)方法下,wrapper无法复用

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

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

相关文章

机器人系统ros2-开发实践04-ROS 2 启动文件管理大型项目的最佳实践

机器人上的大型应用通常涉及多个互连的节点&#xff0c;每个节点可以有许多参数。海龟模拟器中模拟多只海龟就是一个很好的例子。海龟模拟由多个海龟节点、世界配置以及 TF 广播器和监听器节点组成。在所有节点之间&#xff0c;存在大量影响这些节点的行为和外观的 ROS 参数。 …

【C++】哈希的应用---位图

目录 1、引入 2、位图的概念 3、位图的实现 ①框架的搭建 ②设置存在 ③设置不存在 ④检查存在 ​4、位图计算出现的次数 5、完整代码 1、引入 我们可以看一道面试题 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数…

罗宾斯《管理学》第15版笔记/课后习题/考研真题答案

第Ⅰ篇 管理导论 第1章 工作场所中的管理者和你 1.1 知识结构导图 1.2 考点难点归纳 1.3 课后习题详解 1.4 考研真题详解 附加模块一 管理史 知识结构导图 考点难点归纳 课后习题详解 考研真题详解 第2章 决 策 2.1 知识结构导图 2.2 考点难点归纳 2.3 课后习题详解…

C++string类使用大全

目录 温馨提示&#xff1a;这篇文章有约两万字 什么是string类&#xff1f; 一. 定义和初始化string对象 1.string的构造函数的形式&#xff1a; 2.拷贝赋值运算符 3.assign函数 二.string对象上的操作 1.读写string对象 2.读取未知数量的string对象 3.使用getline …

STM32中断系统详解

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 中断基本概念 2. STM32中断 3. NVIC的基本组件 3.1 NVIC的基本组件 3.2 NVIC的优先级 4. EXTI外部中断 4.1 基本概念 4.2 基本结构 5. AFIO 1. 中断基本概念 中断&#xff08;Interrupt&…

信息技术内涵及意义

一、信息技术及其演进趋势 &#xff08;一&#xff09;信息技术概况概念 信息技术&#xff08;Information Technology&#xff0c;IT&#xff09;指“应用在信息加工和处理中的科学、技术与工程的训练方法与管理技巧&#xff1b;上述方法和技巧的应用&#xff1b;计算机及其…

mac idea 下载spring 源码遇到的问题

一、Kotlin: warnings found and -Werror specified 这个问题网上看了很多文章多说是缺少cglib、objenesis包。然后执行了 实际还是没有什么用 解决&#xff1a; 最后自己看了一下前面一个警告。说的就是版本太低。所以我觉得是这个前置问题导致的 然后搜索了改这个Kotlin版本…

《ElementUI 基础知识》el-tabs header 监听鼠标中键滚动时左右滑动(ElementPlus同样适用)

前言 收到需求&#xff0c;可监听 el-tabs 头在鼠标 hover 时。滑动鼠标中键&#xff0c;可左右滑动&#xff01; 效果 鼠标中键上下滑动时&#xff1b;向上滑&#xff0c;向左移动&#xff1b;向下滑&#xff0c;向右移动&#xff1b; 实现 代码56 - 60行&#xff0c;添加…

前端开发框架Vue

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Vue概述 Vue.js&#xff08;简称Vue&#xff09;是由尤雨溪&#xff08;Evan You&#xff09;创建并维护的一款开源前端开发框架。Vue以其轻量级、易上手和高度灵活的特点&…

【Transformer系列(1)】self-attention自注意力

一、self-attention流程 自注意力机制和注意力机制的区别在于&#xff0c;注意力机制中的Q&#xff08;查询向量&#xff09;&#xff0c;K&#xff08;键向量&#xff09;&#xff0c;V&#xff08;值向量&#xff09;是同源的&#xff0c;而一般的注意力机制&#xff0c;Q和…

【MATLAB】GUI初步设计

MATLAB界面设计 前言一、基本步骤1.1 创建GUI文件1.2 界面设计 总结 前言 为了完成图像处理的作业&#xff0c;简直就是生活不易啊 找到一个很棒的教学视频 基于MATLAB的GUI界面设计流程讲解 一、基本步骤 1.1 创建GUI文件 由于在写博文之前我已经创建好文件了&#xff0c;…

Istio基础知识

一、什么是Istio Istio 提供⼀种简单的⽅式来为已部署的服务建⽴⽹络&#xff0c;该⽹络具有 负载均衡、服务间认证、监控等功能&#xff0c;只需要对服务的代码进⾏⼀点或不需要做任何改动。想要让服务⽀持 Istio&#xff0c;只需要在您的环境中部署⼀个特殊的 sidecar 代 理&…

【Linux驱动】USB协议

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux驱动》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; USB协议 &#x1f63c;认识USB&#x1f640;USB的电气信号低速和全速信号电平低速和全速的数据信…

2024-5-1我把QQ群聊天记录分析工具重写了一下

【下载地址】 https://www.lanzoub.com/b00rn0g47e 密码:9hww 【项目背景】 2020年我用Tkinter写过一个QQ群聊天记录分析的工具exe&#xff0c;后续也写过一个纯JS前端的版本&#xff0c;前阵子有个用户反馈不能用了&#xff0c;顺便看能不能加入一个分析关键词的功能&…

基于Python的在线学习与推荐系统设计与实现(论文+源码)-kaic

题目&#xff1a;在线学习与推荐系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本在线学习与推荐系统就是在这样的大环境下诞生&#xff0…

安装库后JupyterLab一直报ModuleNotFoundError问题解决

背景&#xff1a; 先安装的Python3.10&#xff0c;安装在默认路径&#xff1a; C:\Users\#用户名省略#\AppData\Local\Programs\Python\Python310\ 后安装的Anaconda&#xff0c;更改过路径在D盘&#xff1a; D:\ProgramData\anaconda3 此时C盘Python安装路径下Scripts文件…

十二、视觉内容生成模型

1 判别式模型和生成式模型 1. 判别式模型 学习策略函数 Y f ( X ) Yf(X) Yf(X)或者条件概率 P ( Y ∣ X ) P(Y|X) P(Y∣X)不能反映训练数据本身的特性学习成本低&#xff0c;需要的训练样本少无法转为生成式 2. 生成式模型 学习联合概率密度分布 P ( X ∣ Y ) P(X|Y) P(X∣…

【通信中间件】Fdbus HellWorld实例

Fdbus实例教程 Fdbus简介 Fdbus 全称 Fast Distributed Bus&#xff08;高速分布式总线&#xff09;&#xff0c;提供IPCRPC功能。适用于多种OS&#xff1a; LinuxQNXAnroidOSWindow Fdbus本质是Socket&#xff0c;IPC基于Unix domain socket&#xff0c;RPC基于TCP。使用G…

Elasticsearch 索引 blocks:深入探讨数据保护

Elasticsearch 作为搜索和分析数据的首选分布式引擎在技术领域脱颖而出&#xff0c;尤其是在处理日志、事件和综合文本搜索时。 它的与众不同之处在于它如何让你使用各种块选项调整对其索引的访问。 这对于那些负责技术项目的人&#xff08;比如管理员和编码员&#xff09;来说…