mybatis-plus自动填充时间的配置类实现

news2025/1/1 21:41:03

mybatis-plus自动填充时间的配置类实现

在实际操作过程中,我们并不希望创建时间、修改时间这些来手动进行,而是希望通过自动化来完成,而mybatis-plus则也提供了自动填充功能来实现这一操作,接下来,就来了解一下mybatis-plus的自动填充功能是如何进行操作的。

文章目录

  • mybatis-plus自动填充时间的配置类实现
    • 1. 目标
    • 2. 上代码
      • 2.1. 代码目录
      • 2.2. pom文件
      • 2.4. MyMetaObjectHandler(重点)
      • 2.5. MybatisAutoConfiguration
      • 2.6. UserContextHolder
      • 2.7. BaseEntity
      • 2.8. User
    • 3. 测试
      • 3.1. insert(User)
      • 3.2. update(User)
      • 3.3. updateUpdateWrapper()更新失败
      • 3.4. updateUpdateWrapper()更新失败
      • 3.5. userServiceUpdateUpdateWrapper() 更新失败
      • 3.6. userServiceUpdateLambdaUpdateWrapper() 更新失败
    • 4. 改造上面测试更新失败的
      • 4.1. 增加UpdateWapperAspect切面(重点)
      • 4.2. 测试updateUpdateWrapper()更新成功
      • 4.3. 测试updateUpdateWrapper()更新成功
      • 4.4. userServiceUpdateUpdateWrapper() 更新成功
      • 3.6. userServiceUpdateLambdaUpdateWrapper() 更新成功
    • 5.总结

1. 目标

  • 实现默认设置创建者id,创建者用户名,更新者id,更新者用户名,创建时间,更新时间
  • 实现自定义字段birth_day 没有设置值的时候设置当前时间
  • 实现自定义字段login_time没有设置值的时候更新设置当前时间

sql信息如下

drop table if exists liu_user;
CREATE TABLE `liu_user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`username` varchar(255) DEFAULT NULL COMMENT '名字',
`password` varchar(255) DEFAULT NULL COMMENT '密码',
`phone` varchar(255) DEFAULT NULL COMMENT '电话号码',
`birth_day` timestamp NULL COMMENT '出生时间',
`login_time` timestamp NULL COMMENT '登录时间',
`create_by` varchar(20) DEFAULT NULL COMMENT '创建者id',
`create_by_name` varchar(100) DEFAULT NULL COMMENT '创建者账号名',
`update_by` varchar(20) DEFAULT NULL COMMENT '更新者id',
`update_by_name` varchar(100) DEFAULT NULL COMMENT '更新者账号名',
`create_time` timestamp NULL COMMENT '创建时间',
`update_time` timestamp NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) COMMENT='用户表';

2. 上代码

2.1. 代码目录

在这里插入图片描述

2.2. pom文件

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Tag-单元测试 junit-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!-- aop切面 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>transmittable-thread-local</artifactId>
            <version>2.14.3</version>
        </dependency>

        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.14.3</version>
        </dependency>
        <!-- Tag-单元测试 junit-->
        <!-- Tag-mybatis plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>
        <!-- Tag-mybatis plus-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

2.3. yml配置

spring:
  datasource:
    # mysql
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://192.168.0.154:3306/bigdata_src1?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
mybatis-plus:
  mapper-locations: classpath*:com/liuhm/dao/mysqlmapper/*Mapper.xml
  # 实体扫描,多个package用逗号或者分号分隔
  type-aliases-package: com.liuhm.entity
  global-config:
    db-config:
      id-type: auto
      field-strategy: not_null
      logic-delete-value: 0
      logic-not-delete-value: 0
    banner: false
  configuration:
    #sql日志打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    cache-enabled: false

server:
  port: 9099

2.4. MyMetaObjectHandler(重点)

常规实现MetaObjectHandler

package com.liuhm.config;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.liuhm.config.context.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @ClassName:SmMetaObjectHandler
 * @Description: 全局处理基本字段
 * @Author: liuhaomin
 * @Date: 2023/11/29 15:25
 */
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private final List<String> userIdFieldList = new ArrayList<>(Arrays.asList("createBy", "updateBy"));

    private final List<String> userNameFieldList = new ArrayList<>(Arrays.asList("createByName", "updateByName"));

    private final String updateBy = "updateBy";

    private final String updateByName = "updateByName";
    private final static String JAVA_LANG_OBJECT = "java.lang.object";

    @Override
    public void insertFill(MetaObject metaObject){
        try {
            setDefaultValue(metaObject, Arrays.asList(FieldFill.INSERT, FieldFill.INSERT_UPDATE));
        } catch (Exception e) {
            log.warn("设置默认参数失败 {}");
        }
    }

    @Override
    public void updateFill(MetaObject metaObject){
        try {
            setDefaultValue(metaObject, Arrays.asList(FieldFill.INSERT_UPDATE, FieldFill.UPDATE));
        } catch (Exception e) {
            log.warn("设置默认参数失败 {}");
        }
    }

    public void setDefaultValue(MetaObject metaObject, List<FieldFill> fieldFills){
        List<Field> declaredFields = new ArrayList<>();
        Class tempClass = metaObject.getOriginalObject().getClass();
        while(tempClass != null && !tempClass.getName().toLowerCase().equals(JAVA_LANG_OBJECT)){
            declaredFields.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            tempClass = tempClass.getSuperclass();
        }
        String userId = UserContextHolder.getUserId();
        String userName = UserContextHolder.getUserName();
        Date date = new Date();
        String fieldName = null;
        Object val = null;
        for(Field declaredField : declaredFields){
            fieldName = declaredField.getName();
            val = getFieldValByName(fieldName, metaObject);
            TableField annotation = declaredField.getAnnotation(TableField.class);
            if (Objects.nonNull(annotation) && (fieldFills.contains(annotation.fill()))) {
                if (Objects.isNull(val)) {
                    if (userIdFieldList.contains(fieldName) && Objects.nonNull(userId)) {
                        val = userId;
                    }
                    if (userNameFieldList.contains(fieldName) && Objects.nonNull(userName)) {
                        val = userName;
                    }
                    // 插入的时候符合条件的 为空设置值
                    // 设置符合条件的默认时间
                    if ("Date".equals(declaredField.getType().getSimpleName())) {
                        val = date;
                    }
                } else {
                    // 更新
                    if (updateBy.equals(fieldName) && Objects.nonNull(userId)) {
                        val = userId;
                    }
                    if (updateByName.equals(fieldName) && Objects.nonNull(userName)) {
                        val = userName;
                    }
                }


                if(fieldFills.contains(FieldFill.INSERT_UPDATE) && fieldFills.contains(FieldFill.UPDATE)){
                    // 设置符合条件的默认时间
                    if ("Date".equals(declaredField.getType().getSimpleName())) {
                        val = date;
                    }
                }

                setFieldValByName(fieldName, val, metaObject);
            }
        }
    }

}

2.5. MybatisAutoConfiguration

package com.liuhm.config;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;


/**
 * mybatis 自动配置类
 *
 * @author liuhaomin
 * @date  2023.11.16
 */
@Configuration
@MapperScan("com.liuhm.dao.mapper*")
public class MybatisAutoConfiguration {
}

2.6. UserContextHolder

package com.liuhm.config.context;

import com.alibaba.ttl.TransmittableThreadLocal;

/**
 * 模拟用户获取用户名和用户信息 上下文 Holder
 */
public class UserContextHolder {
    /**
     * 当前用户编号
     */
    private static final ThreadLocal<String> USER_ID = new TransmittableThreadLocal<>();
    private static final ThreadLocal<String> USER_NAME = new TransmittableThreadLocal<>();
    /**
     * 获得用户编号。
     *
     * @return 用户编号
     */
    public static String getUserId() {
        return USER_ID.get();
    }
    public static void setUserId(String userId) {
        USER_ID.set(userId);
    }

    public static void clear() {
        USER_ID.remove();
        USER_NAME.remove();
    }

    public static String getUserName() {
        return USER_NAME.get();
    }
    public static void setUserName(String userName) {
        USER_NAME.set(userName);
    }
}

2.7. BaseEntity

package com.liuhm.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * @ClassName:BaseEntity
 * @Description: 基础的类
 * @Author: liuhaomin
 * @Date: 2023/11/29 15:17
 */

@Data
public class BaseEntity implements Serializable {

    private static final long serialVersionUID = -995832545980280226L;

    /**
     * 创建时间
     */
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    /**
     * 最后更新时间
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

    /**
     * 创建者,目前使用 User 的 id 编号
     */
    @TableField(fill = FieldFill.INSERT)
    private String createBy;

    @TableField(fill = FieldFill.INSERT)
    private String createByName;

    /**
     * 更新者,目前使用 User 的 id 编号
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updateBy;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updateByName;

    /**
     * 是否删除
     */
    // @TableLogic
    // private Boolean deleted;

}

2.8. User

package com.liuhm.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @ClassName:User
 * @Description: User
 * @Author: liuhaomin
 * @Date: 2024/12/23 13:50
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "liu_user")
public class User extends BaseEntity {

    private static final long serialVersionUID = -1L;

    private Integer id;
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 电话号码
     */
    private String phone;

    /**
     * 出生时间
     */
    @TableField(fill = FieldFill.INSERT)
    private Date birthDay;

    /**
     * 登录时间
     */
    @TableField(fill = FieldFill.UPDATE)
    private Date loginTime;
}

2.9. 其余简单的类

public interface UserService extends IService<User>
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService
public interface UserMapper extends BaseMapper<User>

3. 测试

3.1. insert(User)

  • 实现默认设置创建者id,创建者用户名,更新者id,更新者用户名,创建时间,更新时间,birth_day 默认有数据
	@Test
	public void insert(){
		String userId = "1";
		String userName = "admin";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);
		User user = new User();
		user.setUsername("admin");
		user.setPassword("123456");
		user.setPhone("15723219655");
		userMapper.insert(user);

		List<User> users = userMapper.selectList(null);
		log.info("users:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

3.2. update(User)

  • 更新者id,更新者用户名,更新时间,login_time 默认有数据
	@Test
	public void update(){
		String userId = "2";
		String userName = "admin2";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, "admin"));
		user.setPassword("123456789");
		userMapper.updateById(user);

		List<User> users = userMapper.selectList(null);
		log.info("users:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

3.3. updateUpdateWrapper()更新失败

  • 更新者id,更新者用户名,更新时间,Password
  • 更新失败
	@Test
	public void updateUpdateWrapper(){
		String userId = "3";
		String userName = "admin3";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		userMapper.update(null, new UpdateWrapper<User>().lambda()
				.set(User::getPassword,"963852741")
				.eq(User::getUsername, "admin"));

		List<User> users = userMapper.selectList(null);
		log.info("updateUpdateWrapper:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

3.4. updateUpdateWrapper()更新失败

  • 更新者id,更新者用户名,更新时间,Password
  • 更新失败
	@Test
	public void updateLambdaUpdateWrapper(){
		String userId = "4";
		String userName = "admin4";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		userMapper.update(null, new LambdaUpdateWrapper<User>()
				.set(User::getPassword,"963852741123465")
				.eq(User::getUsername, "admin"));

		List<User> users = userMapper.selectList(null);
		log.info("updateLambdaUpdateWrapper:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

3.5. userServiceUpdateUpdateWrapper() 更新失败

  • 更新者id,更新者用户名,更新时间,Password
  • 更新失败
	@Test
	public void userServiceUpdateUpdateWrapper(){
		String userId = "5";
		String userName = "admin5";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		userService.update( new UpdateWrapper<User>().lambda()
				.set(User::getPassword,"963852741")
				.eq(User::getUsername, "admin"));

		List<User> users = userMapper.selectList(null);
		log.info("userServiceUpdateUpdateWrapper:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

3.6. userServiceUpdateLambdaUpdateWrapper() 更新失败

  • 更新者id,更新者用户名,更新时间,Password
  • 更新失败
@Test
	public void userServiceUpdateLambdaUpdateWrapper(){
		String userId = "6";
		String userName = "admin6";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		userService.update( new LambdaUpdateWrapper<User>()
				.set(User::getPassword,"963852741123465")
				.eq(User::getUsername, "admin"));

		List<User> users = userMapper.selectList(null);
		log.info("userServiceUpdateLambdaUpdateWrapper:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

4. 改造上面测试更新失败的

4.1. 增加UpdateWapperAspect切面(重点)

package com.liuhm.config.acpect;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.liuhm.config.context.UserContextHolder;
import com.liuhm.entity.BaseEntity;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;

/**
 * @ClassName:UpdateWapperAspect
 * @Description: 解决update(Wrapper updateWrapper),自动填充不生效问题
 * @Author: liuhaomin
 * @Date: 2024/2/19 9:19
 */
@Aspect
@Component
@Slf4j
public class UpdateWapperAspect{


    @Pointcut("execution(* com.baomidou.mybatisplus.core.mapper.BaseMapper.update(..))")
    public void pointcut(){

    }
    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint pjp){
        updateEntity(pjp);
        try {
            return pjp.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 重写update(Wrapper<T> updateWrapper), 更新时自动填充不生效问题
     *
     * @param pjp
     *
     * @return
     */
    private void updateEntity(ProceedingJoinPoint pjp){
        Object[] args = pjp.getArgs();
        if (args != null && args.length == 2) {
            if(args[0] != null){
                return;
            }
            Object arg = args[1];
            String userId = UserContextHolder.getUserId();
            String userName = UserContextHolder.getUserName();
            if (arg instanceof UpdateWrapper) {
                UpdateWrapper updateWrapper = (UpdateWrapper) arg;
                String sqlSet = updateWrapper.getSqlSet();
                if(!sqlSet.contains("update_time")){
                    updateWrapper.set("update_time", new Date());
                }
                if (Objects.nonNull(userId) && !sqlSet.contains("update_by")) {
                    updateWrapper.set("update_by", userId);
                }
                if (Objects.nonNull(userName) && !sqlSet.contains("update_by_name")) {
                    updateWrapper.set("update_by_name", userName);
                }
            }
            if (arg instanceof LambdaUpdateWrapper) {
                LambdaUpdateWrapper<BaseEntity> updateWrapper = (LambdaUpdateWrapper) arg;
                String sqlSet = updateWrapper.getSqlSet();
                if(!sqlSet.contains("update_time")){
                    updateWrapper.set(BaseEntity::getUpdateTime, new Date());
                }
                if (Objects.nonNull(userId) && !sqlSet.contains("update_by")) {
                    updateWrapper.set(BaseEntity::getUpdateBy, userId);
                }
                if (Objects.nonNull(userName) && !sqlSet.contains("update_by_name")) {
                    updateWrapper.set(BaseEntity::getUpdateByName, userName);
                }
            }
        }
    }
}

4.2. 测试updateUpdateWrapper()更新成功

  • 更新者id,更新者用户名,更新时间,Password
	@Test
	public void updateUpdateWrapper(){
		String userId = "3";
		String userName = "admin3";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		userMapper.update(null, new UpdateWrapper<User>().lambda()
				.set(User::getPassword,"963852741")
				.eq(User::getUsername, "admin"));

		List<User> users = userMapper.selectList(null);
		log.info("updateUpdateWrapper:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

4.3. 测试updateUpdateWrapper()更新成功

  • 更新者id,更新者用户名,更新时间,Password
	@Test
	public void updateLambdaUpdateWrapper(){
		String userId = "4";
		String userName = "admin4";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		userMapper.update(null, new LambdaUpdateWrapper<User>()
				.set(User::getPassword,"963852741123465")
				.eq(User::getUsername, "admin"));

		List<User> users = userMapper.selectList(null);
		log.info("updateLambdaUpdateWrapper:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

4.4. userServiceUpdateUpdateWrapper() 更新成功

  • 更新者id,更新者用户名,更新时间,Password
	@Test
	public void userServiceUpdateUpdateWrapper(){
		String userId = "5";
		String userName = "admin5";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		userService.update( new UpdateWrapper<User>().lambda()
				.set(User::getPassword,"963852741")
				.eq(User::getUsername, "admin"));

		List<User> users = userMapper.selectList(null);
		log.info("userServiceUpdateUpdateWrapper:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

3.6. userServiceUpdateLambdaUpdateWrapper() 更新成功

  • 更新者id,更新者用户名,更新时间,Password
	@Test
	public void userServiceUpdateLambdaUpdateWrapper(){
		String userId = "6";
		String userName = "admin6";
		// 设置上下文模拟请求中的用户信息
		UserContextHolder.setUserId(userId);
		UserContextHolder.setUserName(userName);

		userService.update( new LambdaUpdateWrapper<User>()
				.set(User::getPassword,"963852741123465")
				.eq(User::getUsername, "admin"));

		List<User> users = userMapper.selectList(null);
		log.info("userServiceUpdateLambdaUpdateWrapper:{}", users);
	}

在这里插入图片描述

在这里插入图片描述

5.总结

实现默认设置创建者id,创建者用户名,更新者id,更新者用户名,创建时间,更新时间

自定义mapperXml sql暂时不会默认更新上述字段

博客地址

代码下载

下面的mybatis-plus-fieldfill

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

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

相关文章

一、Hadoop概述

文章目录 一、Hadoop是什么二、Hadoop发展历史三、Hadoop三大发行版本1. Apache Hadoop2. Cloudera Hadoop3. Hortonworks Hadoop 四、Hadoop优势1. 高可靠性2. 高扩展性3. 高效性4. 高容错性 五、Hadoop 组成1. Hadoop1.x、2.x、3.x区别2. HDFS 架构概述3. YARN 架构概述4. Ma…

深度学习笔记(9)——神经网络和反向传播

神经网络和反向传播 神经网络架构&#xff1a; 更多的神经元,更大的模型容量,使用更强的正则化进行约束。 神经网络的分层计算 f W 2 m a x ( 0 , W 1 x b 1 ) b 2 fW_2max(0,W_1xb_1)b_2 fW2​max(0,W1​xb1​)b2​,其中max函数体现了非线性,如果想要加深网络的层次,必须…

大模型辅助测试的正确打开方式?

测试的基本目的之一&#xff0c;是对被测对象进行质量评估。换言之&#xff0c;是要提供关于被测对象质量的“确定性”。因此&#xff0c;我们很忌讳在测试设计中引入“不确定性”&#xff0c;比如采用不可靠的测试工具、自动化测试代码逻辑复杂易错、测试选择假设过于主观等等…

ipad如何直连主机(Moonlight Sunshine)

Windows 被连接主机&#xff08;Windows&#xff09; 要使用的话需要固定ip&#xff0c;不然ip会换来换去&#xff0c;固定ip方法本人博客有记载Github下载Sunshine Sunshine下载地址除了安装路径需要改一下&#xff0c;其他一路点安装完成后会打开Sunshine的Web UI&#xff…

sentinel集成nacos启动报[check-update] get changed dataId error, code: 403错误排查及解决

整合nacos报403错误 因为平台写的一个限流代码逻辑有问题&#xff0c;所以准备使用sentinel来限流。平台依赖里面已经引入了&#xff0c;之前也测试过&#xff0c;把sentinel关于nacos的配置加上后&#xff0c;启动一直输出403错误 [fixed-10.0.20.188_8848-test] [check-upda…

紫光同创-盘古200pro+开发板

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 一、开发系统介绍 开发系统概述 MES2L676-200HP 开发板采用紫光同创 logos2 系列 FPGA&#xff0c;型号&#xff1a;…

Vue开发环境搭建上篇:安装NVM和NPM(cpnm、pnpm)

文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II NPM永久使用淘宝源安装 cnpm安装pnpm【推荐】see also: vscode常用插件引言 淘宝镜像:http://npm.taobao.org 和 http://registry.npm.taobao.org 已在 2022.06.3…

【AI大模型】探索GPT模型的奥秘:引领自然语言处理的新纪元

目录 &#x1f354; GPT介绍 &#x1f354; GPT的架构 &#x1f354; GPT训练过程 3.1 无监督的预训练语言模型 3.2 有监督的下游任务fine-tunning &#x1f354; 小结 学习目标 了解什么是GPT.掌握GPT的架构.掌握GPT的预训练任务. &#x1f354; GPT介绍 GPT是OpenAI公…

正则表达式(三剑客之sed)

1.sed工具的使用 1.1 sed工具 1&#xff09;命令格式&#xff1a;sed -n ‘n’ p filename 1.2 打印某行 1&#xff09;打印第二行 [rootlocalhost ~]# sed -n 2p /etc/passwd 2&#xff09;第二行重复打印 [rootlocalhost ~]# sed 2p /etc/passwd 3&#xff09;所有行全部…

细说STM32F407单片机IIC总线基础知识

目录 一、 I2C总线结构 1、I2C总线的特点 2、I2C总线通信协议 3、 STM32F407的I2C接口 二、 I2C的HAL驱动程序 1、 I2C接口的初始化 2、阻塞式数据传输 &#xff08;1&#xff09;函数HAL_I2C_IsDeviceReady() &#xff08;2&#xff09;主设备发送和接收数据 &#…

Android笔试面试题AI答之Android基础(7)

Android入门请看《Android应用开发项目式教程》&#xff0c;视频、源码、答疑&#xff0c;手把手教 文章目录 1.Android开发如何提高App的兼容性&#xff1f;**1. 支持多版本 Android 系统****2. 适配不同屏幕尺寸和分辨率****3. 处理不同硬件配置****4. 适配不同语言和地区**…

《机器学习》线性回归模型实现

目录 一、一元线性回归模型 1、数据 2、代码 3、结果 二、多元线性回归模型 1、数据 2、代码 3、结果 一、一元线性回归模型 1、数据 2、代码 # 导入所需的库 import pandas as pd # 用于数据处理和分析 from matplotlib import pyplot as plt # 用于数据可视化 fr…

基于DIODES AP43781+PI3USB31531+PI3DPX1207C的USB-C PD Video 之全功能显示器连接端口方案

随着USB-C连接器和PD功能的出现&#xff0c;新一代USB-C PD PC显示器可以用作个人和专业PC工作环境的电源和数据集线器。 虽然USB-C PD显示器是唯一插入墙壁插座的交流电源输入设备&#xff0c;但它可以作为数据UFP&#xff08;上游接口&#xff09;连接到连接到TCD&#xff0…

QWidget应用封装为qt插件,供其他qt应用调用

在之前的文章中,有介绍通过QProcess的方式启动QWidget应用,然后将其窗口嵌入到其他的qt应用中,作为子窗口使用.这篇文章主要介绍qt插件的方式将QWidget应用的窗口封装为插件,然后作为其他Qt应用中的子窗口使用. 插件优点: 与主程序为同一个进程,免去了进程间繁琐的通信方式,…

关于 覆铜与导线之间间距较小需要增加间距 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144776995 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

ArcGIS教程(009):ArcGIS制作校园3D展示图

文章目录 数据下载校园3D展示图制作创建要素类矢量化【楼】要素矢量化【绿地】矢量化【范围】矢量化处理打开ArcScene添加动画数据下载 https://download.csdn.net/download/WwLK123/90189025校园3D展示图制作 创建要素类 添加底图: 新建【文件地理数据库】,并修改名称为【…

权限注解+AOP切面+额外工具(UUID生成id,JWT,Servlet客户端,字符串String工具类,Redis序列化,ip工具类)

权限功能和注解的关系 ①、定义三个注解 //角色认证&#xff0c;必须具有指定角色标识才能进入该方法 Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD,ElementType.TYPE}) public interface RequiresRoles{//需要校验的角色标识String[] value() default {}…

RGB、HSV颜色模型及MATLAB互换应用实例

一、前言 RGB和HSV模型是数字图像处理中颜色空间中的两种重要表示方式&#xff0c;RGB和HSV都是描述颜色的数学模型&#xff0c;可以用于表示和处理图像中的颜色信息。 RGB模型是一种基于光的颜色模型&#xff0c;由红&#xff08;Red&#xff09;、绿&#xff08;Green&#x…

MySQL基础-常见的增删改查操作语句总结

1.数据库操作 查看所有数据库 show databases;创建数据库 create database db_stu; --如果数据库已经存在就不创建 create database if not exists db_stu; --添加默认字符集 create database db_stu default charset utf8mb4;删除数据库 drop database db_stu; --如果存在…

【运维】部署MKDocs

部署MKDocs obsidian 记录笔记&#xff0c;通过 mkdocs 私有化部署。 1 使用MKDocs创建笔记 创建仓库&#xff0c;安装 Material for MkDocs 和 mkdocs-minify-plugin mkdir tmp cd tmp git initpip install mkdocs-material pip install mkdocs-minify-pluginmkdocs new .2 …