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

微服务-MybatisPlus下

微服务-MybatisPlus下

文章目录

  • 微服务-MybatisPlus下
    • 1 MybatisPlus扩展功能
      • 1.1 代码生成
      • 1.2 静态工具
      • 1.3 逻辑删除
      • 1.4 枚举处理器
      • 1.5 JSON处理器
        • **1.5.1.定义实体**
        • **1.5.2.使用类型处理器**
      • **1.6 配置加密(选学)**
        • 1.6.1.生成秘钥
        • **1.6.2.修改配置**
        • **1.6.3.测试**
    • 2 插件功能
      • 2.1 分页插件
      • 2.2 通用分页实体
        • 2.2.1 简单分页查询
        • 2.2.2 通用分页查询

1 MybatisPlus扩展功能

1.1 代码生成

自己从头开始,则步骤如下图所示


在这里插入图片描述

在这里插入图片描述

1.2 静态工具

有的时候Service之间也会相互调用,为了避免出现循环依赖问题,MybatisPlus提供一个静态工具类:Db,其中的一些静态方法IService中方法 签名基本一致。主要差别就是由于是静态的,之前没有指定过实体对象,所以除save、update以外的函数几乎都要传入实体类,让底层调用反射机制,得到实体类。而save、update由于本身参数就需要传入一个实体类对象,此对象就可通过反射得到实体类,所以不需要再传入实体类。

实现CRUD功能:

案例:静态工具查询

需求:

  1. 改造根据id查询用户的接口,查询用户的同时,查询出用户对应的所有地址
  2. 改造根据id批量查询用户的接口,查询用户的同时,查询出用户对应的所有地址
  3. 实现根据用户id查询收货地址功能,需要验证用户状态,冻结用户抛出异常(练习)

可以看到以上需求一般都需要在注入了userService之后,再注入addressService才能实现(当然你用多表联合或者注入mapper当我没说)。那这就涉及到了多个Service的相互调用,出现循环依赖问题,这种情况下就可以使用静态工具来解决。而且静态工具不需要注入,这样就避免了循环依赖

第一题:

  • controller层
    @GetMapping("{id}")@ApiOperation(value = "根据id查询用户接口")public UserVO queryUserById(@ApiParam("用户id") @PathVariable("id") Long id){
//        User user = userService.getById(id);
//        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
//        return userVO;return userService.queryUserAndAddressById(id);}
  • service层
    @Overridepublic UserVO queryUserAndAddressById(Long id) {//1. 查询用户User user = getById(id);if(user == null || user.getStatus() == 2){throw new RuntimeException("用户状态异常");}//2. 查询地址//这里本来可以直接用本service的lambdaQuery函数 单位了避免循环依赖,就使用静态工具List<Address> list = Db.lambdaQuery(Address.class).eq(Address::getUserId, user.getId()).list();//3. 封装vo//3.1 转User的PO为VoUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);//3.2 转地址VOif(CollUtil.isNotEmpty(list)){userVO.setAddressList(BeanUtil.copyToList(list, AddressVO.class));}return userVO;}

第二题:

    @Overridepublic List<UserVO> queryUserAndAddressByIds(List<Long> ids) {//1. 查询用户List<User> users = listByIds(ids);if(CollUtil.isEmpty(users)){return Collections.emptyList();}//2. 查询地址//2.1 获取用户id集合List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());//2.2 根据用户id查询地址List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();//2.3 转换地址VOList<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);//2.4 用户地址集合分组处理、相同用户的放入一个集合(组)中Map<Long, List<AddressVO>> addressMap = new HashMap<>(0);if(CollUtil.isNotEmpty(addressVOList)) {addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));}//3. 转换为VO返回List<UserVO> list = new ArrayList<>(users.size());for(User user:users){//3.1 转换user的PO为VOUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);list.add(userVO);//3.2 转换为VOuserVO.setAddressList(addressMap.get(user.getId()));}return list;}

也就是静态工具的使用和IService一样,只不过多了个实体类传入。当一个serivice中需要多个service时,就是用静态工具,用法类似,也有普通函数以及复杂条件查询函数,比如Db.lambdaQuery,Db.Db.lambdaUpdate。

1.3 逻辑删除

逻辑删除就是基于代码逻辑模拟删除效果,但并不会真正删除数据。思路如下:

  • 在表中添加一个字段标记数据是否被删除
  • 当删除数据时把标记置为1
  • 查询时只查询标记为0的数据

在这里插入图片描述

MybatisPlus提供了逻辑删除技能,无需改变方法调用的方法,而是在底层帮我们自动修改CRUD的语句。我们要做的就是在applicaiton.yaml文件中配置逻辑删除的字段名称和值即可。

在这里插入图片描述

    @Autowiredprotected AddressService addressService;@Testvoid testLogicDelete(){//1. 删除addressService.removeById(59L);//2. 查询Address address = addressService.getById(59L);System.out.println("address = " + address);}

虽然使用的remove方法,但是实际执行的是update方法。且在数据库中还存在,只不过deleted变成了true

在这里插入图片描述

1.4 枚举处理器

User类中有一个用户状态字段:

在这里插入图片描述

使用枚举表示状态,可以提高可读性。但是问题来了

在这里插入图片描述

数据库中status仍然是int类型,这就需要一个枚举类型到int类型的转化。

在这里插入图片描述

幸运的是Mybatis和mp帮我们解决了,如上图所示。只需要在枚举类中对应的字段上加上@EnumValue注释 mp就会自动把对应的字段值与数据库中列匹配

在这里插入图片描述

在applicaiton.yml中配置全局枚举类处理器

在这里插入图片描述

@JsonValue //用于枚举的返回值 数据库返回显示的值,比如此处是返回desc的值 也可以返回value的值 否则默认返回的是枚举的对象名 比如此处的NORMAL FROZEN

@Getter
public enum UserStatus {NORMAL(1,"正常"),FROZEN(2,"冻结"),;@EnumValueprivate final int value;@JsonValue  //用于枚举的返回值 数据库返回显示的值private final String desc;UserStatus(int value,String desc){this.value = value;this.desc = desc;}}

在这里插入图片描述

1.5 JSON处理器

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

在这里插入图片描述

格式像这样:

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

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

在这里插入图片描述

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

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

意思就是对象的String字段可以被mp自动转换为数据库中的JSON,但是数据库中的JSON不能被mp自动帮我们转换为String或者相应的对象

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

在这里插入图片描述

1.5.1.定义实体

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

在这里插入图片描述

代码如下:

package com.itheima.mp.domain.po;import lombok.Data;@Data
public class UserInfo {private Integer age;private String intro;private String gender;
}
1.5.2.使用类型处理器

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

在这里插入图片描述

测试可以发现,所有数据都正确封装到UserInfo当中了:

在这里插入图片描述

同时,为了让页面返回的结果也以对象格式返回,我们要修改UserVO中的info字段:

在这里插入图片描述

此时,在页面查询结果如下:

在这里插入图片描述

注意: 由于User类中嵌套了UserInfo类,出现了类的嵌套,那么就需要定义复杂的ResultMap,但是我们又不想定义,那么就直接在User类上加注释,autoResultMap = true 如下图所示

在这里插入图片描述

1.6 配置加密(选学)

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

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

1.6.1.生成秘钥

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

package com.itheima.mp;import com.baomidou.mybatisplus.core.toolkit.AES;
import org.junit.jupiter.api.Test;class MpDemoApplicationTests {@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==
1.6.2.修改配置

修改application.yaml文件,把jdbc的用户名、密码修改为刚刚加密生成的密文:

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:开头
1.6.3.测试

在启动项目的时候,需要把刚才生成的秘钥添加到启动参数中,像这样:

–mpw.key=6234633a66fb399f

单元测试的时候不能添加启动参数,所以要在测试类的注解上配置:

在这里插入图片描述

然后随意运行一个单元测试,可以发现数据库查询正常。

2 插件功能

MyBatisPlus提供的内置拦截器有下面这些

2.1 分页插件

在未引入分页插件的情况下,MybatisPlus是不支持分页功能的,IServiceBaseMapper中的分页方法都无法正常起效。 所以,我们必须配置分页插件。

  • 首先,要在配置类中注册MyBatisPlus的核心插件,同时添加分页插件

  • 接着,就可以使用分页的API了

在这里插入图片描述

在这里插入图片描述

    void testPageQuery(){int pageNo = 1;int pageSize = 2;//1. 准备分页条件//1.1 分页条件Page<User> page = Page.of(pageNo, pageSize);//1.2 排序条件  可以指定多个 比如下面 余额相同则按id排序page.addOrder(new OrderItem("balance",true));page.addOrder(new OrderItem("id",true));//2. 分页查询Page<User> p = userService.page(page);//3. 解析long total = p.getTotal();  //总条数System.out.println("total = " + total);long pages = p.getPages();  //总页数System.out.println("pages = " + pages);List<User> records = p.getRecords();    //分页数据records.forEach(System.out::println);}

2.2 通用分页实体

2.2.1 简单分页查询

案例:简单分页查询案例

需求:遵循下面的接口规范,编写一个UserController接口,实现User的分页查询

在这里插入图片描述

  • 实体类
public class PageQuery {@ApiModelProperty("页码")private Integer pageNo;@ApiModelProperty("页大小")private Integer pageSize;@ApiModelProperty("排序字段")private String sortBy;@ApiModelProperty("是否升序")private Boolean isAsc;
}@Data
@EqualsAndHashCode(callSuper = true)
@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;
}
  • controller
    @GetMapping("/page")@ApiOperation(value = "根据条件分页查询用户接口")public PageDTO<UserVO> queryUsersPage(UserQuery query){return userService.queryUsersPage(query);}
  • impl层
    @Overridepublic PageDTO<UserVO> queryUsersPage(UserQuery query) {String name = query.getName();Integer status = query.getStatus();//1. 构建查询条件Page<User> page = Page.of(query.getPageNo(), query.getPageSize());if(StrUtil.isNotBlank(query.getSortBy())){//不为空page.addOrder(new OrderItem(query.getSortBy(),query.getIsAsc()));}else {//为空 默认按照更新时间排序page.addOrder(new OrderItem("update_time",false));}//2. 分页查询Page<User> p = 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).page(page);//3. 封装VO结果PageDTO<UserVO> userVOPageDTO = new PageDTO<>();userVOPageDTO.setTotal(p.getTotal());userVOPageDTO.setPages(p.getPages());List<User> records = p.getRecords();if(CollUtil.isEmpty(records)){userVOPageDTO.setList(Collections.emptyList());}else {List<UserVO> userVOS = BeanUtil.copyToList(records, UserVO.class);userVOPageDTO.setList(userVOS);}//4. 返回return userVOPageDTO;}
2.2.2 通用分页查询

在这里插入图片描述

  • 改造PageQuery类
@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {@ApiModelProperty("页码")private Integer pageNo = 1;@ApiModelProperty("页大小")private Integer pageSize = 5;@ApiModelProperty("排序字段")private String sortBy;@ApiModelProperty("是否升序")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);}
}
  • 改造PageDTO类
@Data
@ApiModel(description = "分页结果")
@AllArgsConstructor
@NoArgsConstructor
public class PageDTO<T> {@ApiModelProperty("总条数")private Long total;@ApiModelProperty("总页数")private Long pages;@ApiModelProperty("总数据")private List<T> 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);}}
  • impl层
    @Overridepublic PageDTO<UserVO> queryUsersPage(UserQuery query) {String name = query.getName();Integer status = query.getStatus();//1. 构建查询条件Page<User> page = query.toMpPageDefaultSortByUpdateTimeDesc();Page<User> p = lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).page(page);return PageDTO.of(page, UserVO.class);}

相关文章:

微服务-MybatisPlus下

微服务-MybatisPlus下 文章目录 微服务-MybatisPlus下1 MybatisPlus扩展功能1.1 代码生成1.2 静态工具1.3 逻辑删除1.4 枚举处理器1.5 JSON处理器**1.5.1.定义实体****1.5.2.使用类型处理器** **1.6 配置加密&#xff08;选学&#xff09;**1.6.1.生成秘钥**1.6.2.修改配置****…...

【python_将一个列表中的几个字典改成二维列表,并删除不需要的列】

def 将一个列表中的几个字典改成二维列表(original_list,headersToRemove_list):# 初始化一个列表用于存储遇到的键&#xff0c;保持顺序ordered_keys []# 遍历data中的每个字典&#xff0c;添加其键到ordered_keys&#xff0c;如果该键还未被添加for d in original_list:for …...

IDEA的pom.xml显示ignored 的解决办法

问题&#xff1a; idea中创建Maven module时&#xff0c;pom.xml出现ignored。 原因&#xff1a; 相同名称的module在之前被创建删除过&#xff0c;IDEA会误以为新的同名文件是之前删除掉的&#xff0c;将这个新的module的pom.xml文件忽略掉显示ignored. 解决&#xff1a; 在…...

2. 卷积神经网络无法绕开的神——LeNet

卷积神经网络无法绕开的大神——LeNet 1. 基本架构2. LeNet 53. LeNet 5 代码 1. 基本架构 特征抽取模块可学习的分类器模块 2. LeNet 5 LeNet 5: 5 表示的是5个核心层&#xff0c;2个卷积层&#xff0c;3个全连接层.核心权重层&#xff1a;卷积层、全连接层、循环层&#xff…...

【区块链】JavaScript连接web3钱包,实现测试网络中的 Sepolia ETH余额查询、转账功能

审核看清楚了 &#xff01; 这是以太坊测试网络&#xff01;用于学习的测试网络&#xff01;&#xff01;&#xff01; 有关web3 和区块链的内容为什么要给我审核不通过&#xff1f; 别人凭什么可以发&#xff01; 目标成果&#xff1a; 实现功能分析&#xff1a; 显示账户信…...

关于珞石机器人二次开发SDK的posture函数的算法RX RY RZ纠正 C#

在珞石SDK二次开发的函数钟&#xff0c;获取当前机器人位姿的函数posture函数在输出时会发现数据不正确&#xff0c;与示教器数据不一致。 其中第一个数据正确 第二三各数据为相反 第四五六各数据为弧度制 转换方法为(弧度/PI)*180度 然后发现第四个数据还要加上180度 第五…...

【Three.js基础学习】17.imported-models

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 课程回顾&#xff1a; 如何在three.js 中引入不同的模型&#xff1f; 1. 格式 &#xff08;不同的格式&#xff09; https://en.wikipedia.org/wiki/List_of_file_form…...

Spring Bean - xml 配置文件创建对象

类型&#xff1a; 1、值类型 2、null &#xff08;标签&#xff09; 3、特殊符号 &#xff08;< -> < &#xff09; 4、CDATA <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/bea…...

uniapp map组件自定义markers标记点

需求是根据后端返回数据在地图上显示标记点&#xff0c;并且根据数据状态控制标记点颜色&#xff0c;标记点背景通过两张图片实现控制 <mapstyle"width: 100vw; height: 100vh;":markers"markers":longitude"locaInfo.longitude":latitude&…...

Windows:批处理脚本学习

目录 一、第一个批处理文件 1. &&和 | | 2. | 和 & 二、变量 1.传参变量%name 2.初始化变量set命令 3.变量的使用 4.局部变量与全局变量 5.使用环境变量 6.扩充变量语法 三、注释REM和 &#xff1a;&#xff1a; 四&#xff1a;函数 1.定义函数 2.…...

Dav_笔记10:Using SQL Plan Management之4

SQL管理库 SQL管理库(SMB)是驻留在SYSAUX表空间中的数据字典的一部分。它存储语句日志,计划历史记录,SQL计划基准和SQL配置文件。为了允许每周清除未使用的计划和日志,SMB使用自动空间管理。 您还可以手动将计划添加到SMB以获取一组SQL语句。从Oracle Database 11g之前的…...

通过json传递请求参数,如何处理动态参数和接口依赖

嗨&#xff0c;大家好&#xff0c;我是兰若姐姐&#xff0c;今天给大家讲一下如何通过json传递请求参数&#xff0c;如何处理动态参数和接口依赖 1. 使用配置文件和模板 在 test_data.json 中&#xff0c;你可以使用一些占位符或模板变量&#xff0c;然后在运行测试之前&…...

[240727] Qt Creator 14 发布 | AMD 推迟 Ryzen 9000芯片发布

目录 Qt Creator 14 发布Qt Creator 14 版本发布&#xff0c;带来一系列新功能和改进终端用户可通过命令行方式查看此新闻终端用户可通过命令行方式安装软件&#xff1a; AMD 推迟 Ryzen 9000芯片发布 Qt Creator 14 发布 Qt Creator 14 版本发布&#xff0c;带来一系列新功能…...

PLSQL Developer工具查询数据,报错(动态性能表不可访问)

解决的问题&#xff1a; 解决方案&#xff1a; 在配置-首选项-选项&#xff0c;取消勾选“自动统计”&#xff0c;保存之后即可查询数据...

基于 HTML+ECharts 实现智慧交通数据可视化大屏(含源码)

构建智慧交通数据可视化大屏&#xff1a;基于 HTML 和 ECharts 的实现 随着城市化进程的加快&#xff0c;智慧交通系统已成为提升城市管理效率和居民生活质量的关键。通过数据可视化&#xff0c;交通管理部门可以实时监控交通流量、事故发生率、道路状况等关键指标&#xff0c;…...

探索 IT 领域的新宠儿:量子计算

目录 引言&#xff1a;从经典到量子的飞跃 量子计算的基本概念 量子计算的独特优势 量子计算的深度剖析 量子计算的最新进展 量子计算的行业应用前景 面临的挑战与未来展望 结语&#xff1a;迎接量子计算的新时代 引言&#xff1a;从经典到量子的飞跃 在信息技术飞速发…...

TSPNet代码分析

论文《Realigning Confidence with Temporal Saliency Information for Point-Level Weakly-Supervised Temporal Action Localization》的official code分析 论文解读 代码分析 先看看训练过程,执行main if __name__ == __main__:exp = Exp()if exp.config.mode == eval:…...

Ubuntu上安装anaconda创建虚拟环境(各种踩坑版)

之前都是在Windows桌面版进行深度学习的环境部署及训练&#xff0c;今天尝试了一下在Ubuntu上进行环境部署&#xff0c;踩了不少坑&#xff0c;提供一些解决办法给大家避雷。 目录 一、下载和安装anaconda 1. 下载 2. 安装 二、创建虚拟环境 一、下载和安装anaconda 1. …...

DC-5靶机通关

今天我们来学习DC-5靶机&#xff01;&#xff01;&#xff01; 1.实验环境 攻击机&#xff1a;kali2023.2 靶机&#xff1a;DC-5 2.1扫描网段 2.2扫描端口 这里后面这俩端口有点似曾相识啊&#xff0c;在dc3里面好像见过&#xff0c;那咱们给这两个端口来个更详细的扫描&…...

AI学习记录 -使用react开发一个网页,对接chatgpt接口,附带一些英语的学习prompt

实现了如下功能&#xff08;使用react实现&#xff0c;原创&#xff09; 实现功能&#xff1a; 1、对接gpt35模型问答&#xff0c;并实现了流式传输&#xff08;在java端&#xff09; 2、在实际使用中&#xff0c;我们的问答历史会经常分享给他人&#xff0c;所以下图的 copy …...

MongoDB多数据源配置与切换

在MongoDB中配置和使用多数据源主要涉及以下几个步骤&#xff1a; 定义多个数据源的配置&#xff1a; 在应用程序的配置文件中&#xff0c;定义多个MongoDB的数据源&#xff0c;例如在Spring Boot中可以通过application.yml或application.properties文件进行配置。 创建多个Mo…...

Mongodb入门介绍

文章目录 1、Mongodb&#xff1a;NoSQL数据库&#xff0c;分布式的文档型数据库2、适合场景&#xff1a;3、不适合场景&#xff1a;4、概念5、总结 1、Mongodb&#xff1a;NoSQL数据库&#xff0c;分布式的文档型数据库 2、适合场景&#xff1a; 1、web网站数据存储&#xff…...

docker前端部署

挂载&#xff0c;把自己的目录位置&#xff0c;挂载到容器内的HTML...

指标体系建设的方法论

一、分析痛点 了解当前数仓侧与业务应用方对指标到不到、难使用的痛点及日常指标使用习惯&#xff0c;制定指标中心所需功能并设计指标中心样式。 二、指定指标规范 定义指标类型、指标使用方、确定指标域(这里是数据域)、指标要具备的属性(业务/技术口径、负责人、类型等)。 …...

乐鑫ESP32-H2设备联网芯片,集成多种安全功能方案,启明云端乐鑫代理商

在数字化浪潮的推动下&#xff0c;物联网正以前所未有的速度融入我们的日常生活。然而&#xff0c;随着设备的激增&#xff0c;安全问题也日益成为公众关注的焦点。 乐鑫ESP32-H2致力于为所有开发者提供高性价比的安全解决方案&#xff0c;这款芯片经过专门设计以集成多种安全…...

C++调用Java接口

一、配置Java环境 安装jdk&#xff0c;我这里使用jdk1.8 32位版本&#xff0c;下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads/#java8-windows 下载安装后&#xff0c;设置环境变量&#xff1a; JAVA_HOME C:\Program Files (x86)\Java\jdk-1.…...

C# datetimePicker

1. 直接把控件拉到设计器中&#xff0c;此时不要调整控件的values属性&#xff0c;这样就可以 打开后每次默认显示当天日期。 2. 属性Format long长日期格式默认值short短日期格式Time时间格式custom自定义时间格式在customFormat这个属性设置&#xff0c;比如yyyy-MM-dd HH…...

AI有关的学习和python

一、基本概念 AIGC&#xff08;AI Generated content AI 生成内容&#xff09; AI生成的文本、代码、图片、音频、视频。都可以成为AIGC。 Generative AI&#xff08;生成式AI&#xff09;所生成的内容就是AIGC AI指代计算机人工智能&#xff0c;模仿人类的智能从而解决问题…...

前端node.js入门

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 Node.js 入门概览 什么是Node.js&#xff1f; 为什么选择Node.js&#xff1f; 基础安装与环境配置 安装…...

无需标注的数据集

0&#xff1a;人 1&#xff1a;自行车 2&#xff1a;汽车 3&#xff1a;摩托车 4&#xff1a;飞机 5&#xff1a;公交车 6&#xff1a;火车 7&#xff1a;卡车 8&#xff1a;船 9&#xff1a;交通信号灯 10&#xff1a;消火栓 11&#xff1a;停车标志 12&#xff1a;停车计时器…...