java开发springoot

news2025/1/8 1:42:06

阅读理解

  • 命令之间空一行:表示前面的是配置 
  • 红色背景:表示待验证
  • 蓝色背景:表示常用或推荐
  • 绿色背景:注意/推荐

json 转 对象

import com.fasterxml.jackson.databind.ObjectMapper;
public DebangResp convertJsonToObject(String jsonString) {
     ObjectMapper objectMapper = new ObjectMapper();
    try {
        return objectMapper.readValue(jsonString, DebangResp.class);
    } catch (Exception e) {
        e.printStackTrace();
        // 处理异常,例如返回 null 或抛出自定义异常
        return null;
    }
}

jenkins 

安装 

  • 添加yum 源仓库 

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo 

  •  导入仓库源的key(秘钥) 

 rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key

详细步骤 

  1. 官网地址:Jenkins
  2. 启动:java -jar jenkins.war 

稳定版本 

Redhat提供安装Jenkins长期稳定版本的源,参考下面命令安装: 

sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
sudo yum install jenkins 

报错 

解决方案 

IDEA

idea快捷键

ctrl+h:查看继承关系

structure 查看该类的成员 

idea自定义模板

自定义创建文件模板

  • 在设置窗口中,选择 Editor > File and Code Templates > file
  • 例如编辑class类容

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
/**
 * 客户身体报告(CustomerPhysicalReport)实体类
 *
 * @author zhg
 * @since ${DATE} ${TIME}
 */
public class ${NAME} {

#if 和 #end 是模板引擎的语法,用来控制代码块的条件生成。 

#parse("File Header.java") 从另一个模板文件 "File Header.java" 中解析并插入代码。

  • 特殊变量:

${NAME}: 用于类名。
${PACKAGE_NAME}: 用于包名。
${USER}: 用户名。
${DATE}: 当前日期。:年/月/日
${TIME}: 当前时间。
${YEAR}: 当前年份。
${MONTH}: 当前月份。
${DAY_OF_MONTH}: 当前日期中的天数。
${HOUR}: 当前小时数。
${MINUTE}: 当前分钟数。

  • 自定义变量: 如果您想添加更多自定义变量,可以在模板中使用 ${VAR_NAME} 的形式,并在创建类时 IDEA 会提示您输入这些变量的值。 

自定义 方法 模板

  •  File -> Settings - > Editor -> Live Templates -> 点击"+"号 ->  Template Group

新建组名 

  • 编辑类容

/** @Author zhg

@Description //TODO end

@Date time date

@Param param paramparam

@return return

**/

  •  配置生效位置

  • 应用 

add 

快捷键应用 

  • Windows/Linux: 按 Ctrl + Shift + Doc Comment (或 Ctrl + Shift + /)。
  • macOS: 按 Cmd + Shift + Doc Comment (或 Cmd + Shift + /)。 

IDEA 一键启动配置 

 

获取时间 

LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))

swagger

1.导入依赖

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.8.0</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.8.0</version>
</dependency>

2.配置类

import org.springframework.beans.factory.annotation.Value;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfo(
                "My API",
                "A sample API documentation generated using Springfox",
                "API TOS",
                "Terms of service",
                new Contact("John Doe", "www.example.com", "myeaddress@company.com"),
                "License of API", "API license URL", Collections.emptyList());
    }
}

3.yml

spring:
  mvc:
    pathmatch:
      matching-strategy: ANT_PATH_MAT

4.访问

http://localhost:端口/路径/swagger-ui.html

4.Knife4j增强

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

删除

        <dependency>

                <groupId>io.springfox</groupId>

                <artifactId>springfox-swagger-ui</artifactId>

                <version>2.8.0</version>

        </dependency>

5.添加配置(可选)

knife4j:
 enable: true
 setting:
   enablePathMapping: true

 5.访问

http://localhost:端口/路径/doc.html

6.使用

  • @Api

用于类上,表示这是一个 Swagger 资源。
参数:
        tags:描述该类的作用,参数是一个数组,可以填写多个标签。
        description:描述该类的功能。

 @Api(tags = "用户管理", description = "用户基本信息操作")
   public class UserController {
       // ...
   } 

  • @ApiOperation

用于方法上,描述一个具体的 API 操作。
参数:
        value:描述此操作的简短摘要。
        notes:额外的注意事项。
        response:指定响应对象的类型。
        tags:与 @Api 类似,用于分类。 

  @ApiOperation(value = "获取用户列表", notes = "返回所有用户的列表", response = User.class)
   public List<User> getUsers() {
       // ...
   }

  •  @ApiParam

用于方法参数上,描述一个参数。
参数:
        value:描述此参数的意义。
        required:是否必须。
        defaultValue:默认值。

 @ApiOperation(value = "获取用户详情", notes = "根据 ID 获取用户详情", response = User.class)
   public User getUser(@ApiParam(value = "用户ID", required = true) @PathVariable Long id) {
       // ...
   } 

  •  @ApiResponses

用于方法上,描述可能的 HTTP 响应状态码。
参数:
        value:一个数组,每个元素都是一个 ApiResponse 对象。

  @ApiResponses(value = {
           @ApiResponse(code = 200, message = "成功"),
           @ApiResponse(code = 404, message = "未找到"),
           @ApiResponse(code = 500, message = "内部服务器错误")
   })
   public User getUser(@PathVariable Long id) {
       // ...
   }

 @ApiResponse
描述一个 HTTP 响应的状态码及消息。
参数:
        code:HTTP 状态码。
        message:描述信息。

  • @ApiModel

用于类上,描述一个模型对象。
参数:
        description:描述此模型的作用。

 @ApiModel(description = "用户信息")
   public class User {
       private Long id;
       private String name;
       // ...
   } 

  •  @ApiModelProperty

用于字段上,描述模型对象中的一个属性。
参数:
        value:描述此属性的意义。

        required:是否必须。

        example:示例值。

  @ApiModel(description = "用户信息")
   public class User {
       @ApiModelProperty(value = "用户ID", required = true, example = "1")
       private Long id;
       // ...
   }

mvn 打包

  • mvn install -DskipTests # 跳过测试,但不跳过编译
  • mvn install -Dmaven.test.skip=true # 跳过测试和编译
  • mvn install:install-file -Dfile=path/to/example.jar -DgroupId=com.example -DartifactId=example-jar -Dversion=1.0 -Dpackaging=jar 添加jar包到仓库
    -Dfile .jar包路径
    -DgroupId   组id
    -DartifactId  artifactId
    -Dversion 版本
    -Dpackaging  文件类型

pom.xml

jar包依赖导入

<groupId>com.bianque</groupId>
<artifactId>bianque-common-dop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/libs/dop-sdk-0.0.1-SNAPSHOT.jar</systemPath>

服务调用

Feign

报错 

  • JSON parse error: Illegal character ((CTRL-CHAR, code 31)): only regular white space 
  • 若依框架没有权限。需要登录状态(才能通过Security

解决方案 

位置:调用项目 

1、关闭请求数据压缩

feign.compression.request.enabled: false
feign.compression.response.enabled: false

2、设置请求压缩的最小请求大小 

 feign.compression.request.min-request-size: 8192

git

文件颜色的含义 

蓝色:修改过的文件

红色:冲突文件

粉红:未追踪的文件

绿色:已经追踪文件

暂存

  •  执行暂存

 git stash

apply [stash_key]  不会丢失栈信息

sava ‘描述信息’  有描述信息

push 压栈 没有描述信息

pop 弹栈 会丢失栈信息

  • 查看暂存列表 

git stash list  

  • 应用暂存 

git stash apply [stash-key]

--index [n] windows平台替换  apply [stash-key]

分支 

  • 查看分支

git branch 

-d 删除已经完成合并的分支

-D 强制删除分支 

  • 新建分支

git branch branch_name

  • 切换分支 

git swicth branch_name

  • 合并分支

git merge brash_name   

  • 终止合并分支  

git merge --abort 

合并分支到当前分支 

  • 查看分支图

 git log --graph --oneline --decorate --all

alias git-log='git log --graph --oneline --decorate --all'

git-log

  • 提交 

 git commit -m "描述信息"

  • 与上一个commit合并

git commit --amend -m "描述信息" 

远端仓库

  • 查看远端仓库

git remote

参数解析 

        - v 查看所有远端url

        - get-url 查看特定远端的url

        - set-url 设置远端仓库的url

        - remove local_origion_branch_name

  •  查看特定远端仓库地址
  •  对接远端仓库 

git remote add [local_origin_branch_name] [origin_url] 

  • 推送并合并

git push [local_origin_branch_name] [local_branch_name:origin_branch_name] 

git push --set-upstream local_origin_branch_name [local_branch_name:origin_branch_name] 

git push

-f 强制覆盖 

远端分支与本地分支的关联关系 

git branch -vv 

  • 远端克隆

git clone [origin_url] [loca_file_name]

  • 远端抓取 

git fetch [origin_name] [origin_branch_name] 

git fetch

抓取远端分支,但不会合并 

  • 远端拉取 

git pull local_origion_branch_name origion_branch_name:local_branch_name

git fetch

git merge branch_name

冲突

修改同一个文件,同一行

  • 查看冲突列表

git status

                 both modified: main1.txt

                 both modified: main2.txt

  •  查看冲突的具体内容

git diff 

  • 本地仓库冲突解决方案

1.提交:生成冲突文件

2.修改:冲突文件

3.添加:添加文件到暂存区

3.提交

  • 远程仓库 冲突解决方案

1.pull :生成冲突文件

2.修改:冲突文件

3.添加:添加文件到暂存区

3.commit:提交文件(自动合并分支)

4.push :推送自己的最新修改 

回退

  • 回退版本

git reset id

--soft 保留工作区,暂存区:   可以重新修改,再提交

--mixed 保留工作区,清除暂存区:可以重新修改,再提交(需要重新添加暂存区)

--hard 清除工作区,暂存区 

  • 查看暂存区内容 

git ls-files 

  • 查看操作记录

git reflog 

  • 查看提交记录

git log --oneline  

查看版本信息 

git log --graph

可以回退版本 

CI/CD 还没完成

git安装

gitlab安装

jenkins安装之docker 

1.pull 镜像

docker pull jenkins/jenkins:lts

2.启动

 docker run \
  --name jenkins \
  --restart always \
  -d \
  -p 8080:8080 \
  -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/bin/docker:/usr/bin/docker \
  jenkins/jenkins:lts

3.访问

http://ip:8080

 3.查看密码

# Jenkins容器启动日志 保存密码后面登陆控制台使用。
docker logs -f 容器名 

mybatis

mapper

  • import org.apache.ibatis.annotations.Param; 参数包 

mapper.xml

  • classpath:只会到你的class路径中查找找文件。
  • classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找。
  • <trim> 标签
    prefix:需要在去除之前 添加的前缀。
    suffix:需要在去除之后 添加的后缀。
    prefixOverrides:需要  去除的前缀。
    suffixOverrides:需要  去除的后缀。
    

  •  条件生成sql

<set>特点:
        用于生成 SQL 更新语句中的 SET 子句。
        只有至少一个子元素的值不为 null 时才会输出整个 SET 子句。
        常见于 UPDATE 语句中,用来动态构建需要更新的字段列表。

<update id="updateUser">
    UPDATE user
    <set>
        <if test="username != null">username = #{username}, </if>
        <if test="email != null">email = #{email}, </if>
        <if test="age != null">age = #{age} </if>
    </set>
    WHERE id = #{id}
</update>

<trim>特点:
        可以移除前导或尾随的文本(如逗号、括号等),这对于构建动态 SQL 很有用。
        支持 prefix 和 suffix 属性来添加前缀和后缀。
        支持 prefixOverrides 和 suffixOverrides 属性来移除多余的前缀和后缀。

<select id="selectUsers">
    SELECT * FROM user
    WHERE 1=1
    <trim prefix="AND (" suffix=")" prefixOverrides="AND">
        <if test="username != null"> username = #{username} </if>
        <if test="email != null"> AND email = #{email} </if>
        <if test="age != null"> AND age = #{age} </if>
    </trim>
</select>

  • 循环生成sql 
<foreach collection="entities" item="entity" separator=",">
    (#{entity.uid},#{entity.bannerSetUid}, #{entity.picUrl}, #{entity.linkType}, #{entity.jumpUrl},
    #{entity.sortNum}, #{entity.status}, #{entity.createTime}, #{entity.updateTime})
</foreach>

这个XML函数是一个foreach循环,它的功能是对一个名为entities的集合进行迭代处理。每次迭代时,将集合中的每个元素作为entity进行处理,并用,作为分隔符将处理结果拼接在一起。在迭代过程中,将每个entity的uid、bannerSetUid、picUrl、linkType、jumpUrl、sortNum、status、createTime和updateTime属性按照给定的顺序输出。 

  • 类的属性映射 
<resultMap type="com.apq.sdemo.common.dataobj.ManageDO" id="ManageMap">
    <result property="uid" column="uid" jdbcType="VARCHAR"/>
</resultMap>

 多数据源:动态数据源切换

  • 1.配置多数据源yml
datasource:
  mysql-db:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    jdbc-url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
    username: root
    password: root
  secondary:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    jdbc-url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
    username: root
    password: root
  • 2. DataSourceConfig 类配置
@Configuration
@MapperScan(basePackages = "com.test.mapper", sqlSessionTemplateRef = "mysqlDbSqlSessionTemplate")
public class DataSourceConfig {
    @Bean(name = "datasource1")
    @ConfigurationProperties(prefix = "spring.datasource.mysql-db")
    public DataSource datasource1() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "datasource2")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource datasource2() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "dynamicDataSource")
    @Primary
    public DataSource dynamicDataSource(){
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 设置默认数据源 这个代码有点重复了,因为我们在DataSourceChange类中已经设定了默认数据库
        dynamicDataSource.setDefaultTargetDataSource(datasource1());
        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("datasource1", datasource1());
        objectObjectHashMap.put("datasource2", datasource2());
        dynamicDataSource.setTargetDataSources(objectObjectHashMap);
        return dynamicDataSource;
    }

    @Bean
    public SqlSessionFactory mysqlDbSqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

        bean.setDataSource(dataSource);
        bean.setVfs(SpringBootVFS.class);
        bean.setTypeAliasesPackage("com.test.dao");
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
        return bean.getObject();
    }

//    @Bean
//    public DataSourceTransactionManager mysqlDbTransactionManager(@Qualifier("dynamicDataSource") DataSource dataSource) {
//        return new DataSourceTransactionManager(dataSource);
//    }
    @Bean
    public PlatformTransactionManager transactionManager(){
        return new DataSourceTransactionManager(dynamicDataSource());
    }


    @Bean
    public SqlSessionTemplate mysqlDbSqlSessionTemplate(@Qualifier("mysqlDbSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
  •  3.编写DataSourceContextHolder 
public class DataSourceContextHolder {
    /**
     * 默认数据源
     */
    public static final String DEFAULT_DS = "datasource1";

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    // 设置数据源名
    public static void setDB(String dbType) {
        System.out.println("切换到{"+dbType+"}数据源");
        contextHolder.set(dbType);
    }

    // 获取数据源名
    public static String getDB() {
        return (contextHolder.get());
    }

    // 清除数据源名
    public static void clearDB() {
        contextHolder.remove();
    }
}
  • 3.编写DynamicDataSource
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDB();
    }
}
  • 4.自定义注解DS 
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface DS
{
    String value() default "datasource1";
}
  • 5.编写AOP:DynamicDataSourceAspect

@Aspect
@Component
public class DynamicDataSourceAspect {
    @Before("@annotation(com.annotation.DS)")
    public void beforeSwitchDS(JoinPoint point){
        //获得当前访问的class
        Class<?> className = point.getTarget().getClass();
        //获得访问的方法名
        String methodName = point.getSignature().getName();
        //得到方法的参数的类型
        Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
        String dataSource = DataSourceContextHolder.DEFAULT_DS;
        try {
            // 得到访问的方法对象
            Method method = className.getMethod(methodName, argClass);
            // 判断是否存在@DS注解
            if (method.isAnnotationPresent(DS.class)) {
                DS annotation = method.getAnnotation(DS.class);
                // 取出注解中的数据源名
                dataSource = annotation.value();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 切换数据源
        DataSourceContextHolder.setDB(dataSource);
    }

    @After("@annotation(com.annotation.DS)")
    public void afterSwitchDS(JoinPoint point){
        DataSourceContextHolder.clearDB();
    }
}
  • 6.启动类添加
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
  • 7.DS注解:应用再方法上

mybatis plus

1.pom.xml 

<!-- mybatisplus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3</version> <!-- 使用最新稳定版本 -->
        </dependency>
<!-- mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

2.yml

# datasource
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    username: root
    password: 123456 

# mybatis-plus
mybatis-plus:
  configuration:
    # 显示 SQL 执行语句
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      # 主键类型
      id-type: auto
      # 逻辑删除字段
      logic-delete-field: deleted
      # 逻辑删除值
      logic-not-delete-value: 0
      logic-delete-value: 1

多数据源配置

1.添加DataSourceConfig配置类

@Configuration
public class DataSourceConfig {

    @Bean(name = "dataSource1")
    @ConfigurationProperties(prefix = "spring.datasource1")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dataSource2")
    @ConfigurationProperties(prefix = "spring.datasource2")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }
}

2.事务管理器配置

@Configuration
@EnableTransactionManagement
public class TransactionConfig {

    @Bean(name = "transactionManager1")
    public PlatformTransactionManager transactionManager1(@Qualifier("dataSource1") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "transactionManager2")
    public PlatformTransactionManager transactionManager2(@Qualifier("dataSource2") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

 3.mapper接口加注解

@Repository
@Mapper
@DataSource("dataSource1")
public interface UserMapper1 extends BaseMapper<User> {
}

@Repository
@Mapper
@DataSource("dataSource2")
public interface UserMapper2 extends BaseMapper<User> {
}

事务管理

 @Transactional(rollbackFor = DataAccessException.class)

注解 

  • @PathVariable("storeName") 路径参数

常用lambda

 List 或 Set遍历

 List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

 // 使用Lambda表达式遍历List
 names.stream().forEach(name -> System.out.println(name));

aspect

1.示例

@Aspect
@Component
public class ControllerAspect {

    @Around(value = "execution(* com.x.x.x.x.controller.*.*(..))")
    public Object handleControllerMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        return  joinPoint.proceed();
    }
}
  • 通知 

 @Around 环绕通知

  • 连接点方法

joinPoint.proceed() 执行方法

joinPoint.getArgs() 获取请求参数

异步

1  @EnableAsync 启用异步及config类

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

 @Bean
 public TaskScheduler taskScheduler() {
         ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
         scheduler.setPoolSize(10); // 设置线程池大小
         scheduler.initialize();
         return scheduler;
 }
}

2.写异步类的@Async 异步方法

 @Async
 public void customerLogsAsyncTask() {
        System.out.println("Executing async task on thread: " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000); // 模拟耗时操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        throw new RuntimeException(e);
        }
 }
}

3.调用异步方法

 @Autowired

private MyService myService;

myService.performAsyncTask();

事务 

1.配置类上添加@EnableTransactionManagement注解,以启用Spring的事务管理功能。

@Configuration
@EnableTransactionManagement
public class AppConfig {

         @Bean
            public PlatformTransactionManager transactionManager(DataSource dataSource) {
                return new DataSourceTransactionManager(dataSource);
            }

    // 配置类的其他内容...
}

2. 使用@Transactional注解

@Service
public class UserService {

   
    @Transactional(rollbackFor = Exception.class)
    public void updateUserAndRole(Long userId, Long roleId) {
       
        
        // 业务
  
    }
}
 

常用函数接口 

boolean 一个参数泛型

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

void  一个参数泛型

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
    // 可以有默认方法和静态方法,但核心抽象方法是accept
}

获取请求ip 

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();

// 获取客户端IP地址
final String clientIp = getClientIp(request);
private String getClientIp(HttpServletRequest request) {
    String ip = request.getHeader("X-Forwarded-For");
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("HTTP_CLIENT_IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getRemoteAddr();
    }
    return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
}

请求信息获取

静态获取:RequestContextHolder

AjaxResult 返回值信息

import io.swagger.annotations.ApiModel;
import lombok.Data;

import java.io.Serializable;
import java.util.Objects;
@ApiModel(description = "返回")
@Data
public class AjaxResult<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 是否成功 true or false
     */
    private boolean success;

    /**
     * 状态码
     */
    private int code;

    /**
     * 返回内容
     */
    private String msg;

    /**
     * 数据对象
     */
    private T data;

    /**
     * 状态类型
     */
    public enum Type
    {
        /** 成功 */
        SUCCESS(0),
        /** 警告 */
        WARN(301),
        /** 错误 */
        ERROR(500);
        private final int value;

        Type(int value)
        {
            this.value = value;
        }

        public int value()
        {
            return this.value;
        }
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
     */
    public AjaxResult()
    {
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象
     *
     * @param type 状态类型
     * @param msg 返回内容
     * @param data 数据对象
     */
    public AjaxResult(Type type, String msg, T data) {
        this.code = type.value();
        this.msg = msg;
        if (Objects.nonNull(data)) {
            this.data = data;
        }

        if (type.value == Type.SUCCESS.value) {
            this.success = Boolean.TRUE;
        } else {
            this.success = Boolean.FALSE;
        }
    }

    /**
     * 返回成功消息
     *
     * @return 成功消息
     */
    public static AjaxResult success()
    {
        return AjaxResult.success("操作成功");
    }

    /**
     * 返回成功数据
     *
     * @return 成功消息
     */
    public static <U> AjaxResult<U> success(U data)
    {
        return AjaxResult.success("操作成功", data);
    }

    /**
     * 返回成功消息
     *
     * @param msg 返回内容
     * @return 成功消息
     */
    public static AjaxResult success(String msg)
    {
        return AjaxResult.success(msg, null);
    }

    /**
     * 返回成功消息
     *
     * @param msg 返回内容
     * @param data 数据对象
     * @return 成功消息
     */
    public static <U> AjaxResult<U> success(String msg, U data)
    {
        return new AjaxResult(Type.SUCCESS, msg, data);
    }

    /**
     * 返回警告消息
     *
     * @param msg 返回内容
     * @return 警告消息
     */
    public static AjaxResult warn(String msg)
    {
        return AjaxResult.warn(msg, null);
    }

    /**
     * 返回警告消息
     *
     * @param msg 返回内容
     * @param data 数据对象
     * @return 警告消息
     */
    public static <U> AjaxResult<U> warn(String msg, U data)
    {
        return new AjaxResult(Type.WARN, msg, data);
    }

    /**
     * 返回错误消息
     *
     * @return
     */
    public static AjaxResult error()
    {
        return AjaxResult.error("操作失败");
    }

    /**
     * 返回错误消息
     *
     * @param msg 返回内容
     * @return 警告消息
     */
    public static AjaxResult error(String msg)
    {
        return AjaxResult.error(msg, null);
    }

    /**
     * 返回错误消息
     *
     * @param msg 返回内容
     * @param data 数据对象
     * @return 警告消息
     */
    public static <U> AjaxResult<U> error(String msg, U data)
    {
        return new AjaxResult(Type.ERROR, msg, data);
    }


    /**
     * 方便链式调用
     *
     * @param key   键
     * @param value 值
     * @return 数据对象
     */
    @Deprecated
    public AjaxResult put(String key, Object value) {
        //super.put(key, value);
        return this;
    }

    /**
     * 是否为成功消息
     *
     * @return 结果
     */
    public boolean isSuccess() {
        return success;
    }
    public String getMsg() {
        return msg;
    }
    public Integer getCode() {
        return code;
    }
}

Httpstatus 返回状态码

/**
 * 返回状态码
 * 
 * @author ruoyi
 */
public class HttpStatus
{
    /**
     * 操作成功
     */
    public static final int SUCCESS = 200;

    /**
     * 对象创建成功
     */
    public static final int CREATED = 201;

    /**
     * 请求已经被接受
     */
    public static final int ACCEPTED = 202;

    /**
     * 操作已经执行成功,但是没有返回数据
     */
    public static final int NO_CONTENT = 204;

    /**
     * 资源已被移除
     */
    public static final int MOVED_PERM = 301;

    /**
     * 重定向
     */
    public static final int SEE_OTHER = 303;

    /**
     * 资源没有被修改
     */
    public static final int NOT_MODIFIED = 304;

    /**
     * 参数列表错误(缺少,格式不匹配)
     */
    public static final int BAD_REQUEST = 400;

    /**
     * 未授权
     */
    public static final int UNAUTHORIZED = 401;

    /**
     * 访问受限,授权过期
     */
    public static final int FORBIDDEN = 403;

    /**
     * 资源,服务未找到
     */
    public static final int NOT_FOUND = 404;

    /**
     * 不允许的http方法
     */
    public static final int BAD_METHOD = 405;

    /**
     * 资源冲突,或者资源被锁
     */
    public static final int CONFLICT = 409;

    /**
     * 不支持的数据,媒体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;

    /**
     * 系统内部错误
     */
    public static final int ERROR = 500;

    /**
     * 接口未实现
     */
    public static final int NOT_IMPLEMENTED = 501;

    /**
     * 系统警告消息
     */
    public static final int WARN = 601;
}

stream 流 

数据 收集.collect

数据格式控制  Collectors 

分组:Collectors .groupingBy ()

示例

  .collect(Collectors.groupingBy(String::toLowerCase,Collectors.groupingBy(String::toUpperCase)))

List<Map<Date, BigDecimal>> list = iphmsBraceletDataList.stream()
        .map(iphmsBraceletData -> Collections.singletonMap(
                iphmsBraceletData.getCreateTime(),
                iphmsBraceletData.getKcal()))
        .collect(Collectors.toList());

K8S 

分页 

import com.github.pagehelper.Page;
Page<IphmsTopicsRecordSleepResp> page = new Page<>();
page.addAll(list);
page.add(list);
page.setTotal(new PageInfo(iphmsSleepResultList).getTotal());
Integer t1 = PageUtils.getPageNunSiz().getT1();
Integer t2 = PageUtils.getPageNunSiz().getT2();
Page<IphmsHealthResult> page = new Page<>(t1
        ,t2);

日期时间

常见日期格式字符串

  • Jan 4, 2025 10:45:26 转 MMM d, yyyy HH:mm:ss 
  • 2024-12-27 20:53:57 转  yyyy-MM-dd HH:mm:ss

字符串日期,解析

 format

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  • format(startTime)  Date时间转字符串

 formatter

DateTimeFormatter.ofPattern("yyyy-MM-dd")

  • .parse(dateString) 解析字符串,返回Date

LocalDate 操作

  • .withDayOfMonth(1); 设置天
  • startTime.withDayOfMonth(startTime.lengthOfMonth()); 获取当前月的最后一天的日期
  • .plusMonths(1) 增加 月份
  • .parse(dateString, formatter) 把有格式的字符串转 LocalDate

LocalDateTime 操作 

  • .withYear(Integer.parseInt(year)) 年
    .withMonth(Integer.parseInt(month)) 月
    .withDayOfMonth(Integer.parseInt(day)); 日
  • .withHour(timeToSet.getHour()) 时 

    .withMinute(timeToSet.getMinute()) 分 

    .withSecond(timeToSet.getSecond()); 秒 
    .withNano(0); 纳秒

  • LocalDateTime.parse(dateTimeString, formatter) 字符串转LocalDateTime
  • .atZone() 设置 时区
  • now() 现在的日期时间
  • .atStartOfDay(ZoneId.systemDefault())

LocalTime 操作 

  • .now() 获取现在的时间
  •  .format(formatter); 获取格式时间字符串

YearMonth 年月 操作

  • YearMonth.from(localDateTime) 获取 LocalDateTime 的年月数据
  • .atDay(1) 设置 天
  • .atEndOfMonth() 月份的最后一天
  • parse(dateString, formatter) 把有格式的字符串转 YearMonth

时分秒 操作 

// 获取当前日期和时间

Calendar calendar = Calendar.getInstance();

// 设置时、分、秒

calendar.set(Calendar.HOUR_OF_DAY, 15); // 设置小时(24小时制)

calendar.set(Calendar.MINUTE, 30); // 设置分钟

calendar.set(Calendar.SECOND, 0);

// 转换为Date对象

Date date = calendar.getTime();

Date 操作

  • .getTime()  获取时间戳

  • Date.from() 其他日期对象转Date

  • 时间格式控制 
    import java.text.SimpleDateFormat;

    Date startTime = new Date(); // 假设 startTime 是当前时间
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String formattedDate = sdf.format(startTime);

转换

  • Date 转 LocalDate 

 // 将 Date 转 LocalDate 

// 假设 startTime 是一个 Date 对象
LocalDate localDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

  • Date 转 LocalDateTime 

 // 将 Date 转 LocalDateTime 

// 假设 startTime 是一个 Date 对象
LocalDate localDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

  •  LocalDate 转 Date

// localDate 为LocalDate 对象
Date newStartTime = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

  • localDateTime 转 Date

 // localDateTime 为LocalDateTime 对象
Date newStartTime = Date.from(Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

DateUtil

当月日期获取

// 当月的第一天
startTime = DateUtil.offsetDay(DateUtil.parse(time, "yyyy-MM"), 0);
// 获取 当月数据 最后一天
endTime = DateUtil.offsetDay(DateUtil.parse(time, "yyyy-MM"), -1);

  • DateUtil.parse(time,"yyyy-MM") 字符串 转Date
  • DateUtils.getNowDate() 获取现在的日期时间

TEST

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

 注解

@SpringBootTest(classes = BianQueIphmsApplication.class)
@ExtendWith(SpringExtension.class)

获取对象的值和属性

Class<?> aClass = iphmsAnalysis.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields)
{
    declaredField.setAccessible(true);
    // 属性名
    String name = declaredField.getName();
    System.out.println(name);
    System.out.println(declaredField.getType());
    try {
        // 属性值
        Object o = declaredField.get(iphmsAnalysis);
        System.out.println(o);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

json 处理

 JSON.parseArray(rangeName, String.class)

debug 开启

<logger name="com.bianque" level="debug" />

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

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

相关文章

MLU上使用MagicMind GFPGANv1.4 onnx加速!

文章目录 前言一、平台环境准备二、环境准备1.GFPGAN代码处理2.MagicMind转换修改env.sh修改run.sh参数解析运行 3.修改后模型运行 前言 MagicMind是面向寒武纪MLU的推理加速引擎。MagicMind能将人工智能框架&#xff08;TensorFlow、PyTorch、Caffe与ONNX等&#xff09;训练好…

Nginx——入门介绍、安装与核心配置文件结构(一/五)

目录 1.Nginx 简介1.1.背景介绍1.2.名词解释1.3.常见服务器对比1.3.1.IIS1.3.2.Tomcat1.3.3.Apache1.3.4.Lighttpd1.3.5.其他的服务器 1.4.Nginx 的优点1.4.1.速度更快、并发更高1.4.2.配置简单&#xff0c;扩展性强1.4.3.高可靠性1.4.4.热部署1.4.5.成本低、BSD 许可证 1.5.Ng…

nginx-限流(请求/并发量)

一. 简述&#xff1a; 在做日常的web运维工作中&#xff0c;难免会遇到服务器流量异常&#xff0c;负载过大等情况。恶意攻击访问/爬虫等非正常性请求&#xff0c;会带来带宽的浪费&#xff0c;服务器压力增大&#xff0c;影响业务质量。 二. 限流方案&#xff1a; 对于这种情…

【学Rust开发CAD】1 环境搭建

文章目录 一、搭建C/C编译环境二、安装Rust三、配置 PATH 环境变量四、验证安装结果五、安装编辑工具 一、搭建C/C编译环境 Rust 的编译工具依赖 C 语言的编译工具&#xff0c;这意味着你的电脑上至少已经存在一个 C 语言的编译环境。如果你使用的是 Linux 系统&#xff0c;往…

模型创新、论文复现、科研辅导、论文代码定制

建模先锋团队长期致力于为用户提供优质的代码定制服务。团队提供全网最低价格的服务&#xff0c;同时保证高性价比和高质量的代码交付&#xff0c;为您提供个性化定制的服务。 以下是定制服务范围&#xff1a; 通过深度学习和信号处理技术&#xff0c;我们能够针对不同行业和场…

基于云效 Windows 构建环境和 Nuget 制品仓库进行 .Net 应用开发

作者&#xff1a;陆冬澄、周静 在现代软件研发体系中&#xff0c;.NET 平台由于其强大的功能、灵活性和丰富的开发工具&#xff0c;成为了构建 Windows 应用程序的热门选择。无论是桌面应用、Web 应用还是服务应用&#xff0c;.NET 提供了一系列强大的框架和工具&#xff0c;帮…

用VS C#构建Windows服务【纯操作版,附带项目地址】

1&#xff0e;点击“创建新项目”&#xff0c;选择“Windows 服务&#xff08;.NET Framework&#xff09;” 2、给项目命名 3、双击“Service1.cs”&#xff0c;右键&#xff0c;选择“添加安装程序”&#xff0c;就会生成一个“ProjectInstaller.cs”文件 4、双击“P…

KUKA机器人如何修改程序并下载到机器人控制器中?

KUKA机器人如何修改程序并下载到机器人控制器中? 如下图所示,首先将使用的网卡的IP地址设置为自动获得, 打开workvisual软件,点击搜索,正常情况下可以搜索到项目文件,选中后双击进入, 如下图所示,此时,workvisual会自动从机器人控制器中下载项目文件到电脑上,耐心等待…

L28.【LeetCode笔记】移动零(三种解法)

目录 1.题目 2.向前覆盖法 分析 代码 提交结果 3.优解:双指针 代码 提交结果 4.其他不符合题意的方法:使用队列 代码 提交结果 1.题目 https://leetcode.cn/problems/move-zeroes/description/ 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾…

js逆向实战(1)-- 某☁️音乐下载

下载某云音乐源文件.mp4格式 首先随便点进一首歌&#xff0c;如图所示获取该音乐id&#xff0c;然后点击播放键&#xff0c;打开F12进行查询XHR 由此可知&#xff0c;实际请求网址是 https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token「你的token」url需带…

深入了解 SSL/TLS 协议及其工作原理

深入了解 SSL/TLS 协议及其工作原理 一. 什么是 SSL/TLS?二. SSL/TLS 握手过程三. SSL/TLS 数据加密与传输四. 总结 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱 一. 什么是 SSL/TLS? 安全套接层&am…

Java四大常用JSON解析性能对比:Hutool、Fastjson2、Gson与Jackson测试

1. 引言 JSON 是现代软件开发中常用的数据交换格式&#xff0c;尤其在微服务和前后端分离的架构中更是必不可少。 本文将对 Java 中四大主流 JSON 解析库——Hutool、Fastjson2、Gson 和 Jackson 进行性能测试和对比分析&#xff0c;通过实测 20 万条数据解析&#xff0c;揭示…

【整理集合大全】MySQL(4) 数据库增删改查SQL语句

查看数据库 show databases; 使用数据库 use 数据库名;创建数据库 CREATE DATABASE 数据库名;删除数据库 DROP DATABASE 数据库名;创建表 create table 表名(列名1 类型(长度) [约束],列名2 类型(长度) [约束],…… );长度区别 int类型带长度&#xff1a;不影响存取值&…

升级 Spring Boot 3 配置讲解 —— Spring Boot 3 核心源码专讲

学会这款 &#x1f525;全新设计的 Java 脚手架 &#xff0c;从此面试不再怕&#xff01; Spring Boot 3 是 Spring 生态中的重要里程碑&#xff0c;它不仅全面支持 Java 17&#xff0c;还引入了许多新特性&#xff0c;如对 GraalVM 原生镜像的支持、改进的性能优化以及更灵活的…

vue3中el-table实现多表头并表格合并行或列

1、el-table中添加事件 :span-method"genderSpanCity" <el-table :span-method"genderSpanCity":data"data.tableData":fit"true" table-layout"fixed" header-align"center" stripestyle"width:100%;he…

OpenGL —— 流媒体播放器 - ffmpeg解码rtsp流,opengl渲染yuv视频(附源码,glfw+glad)

效果 说明 FFMpeg和OpenGL作为两大技术巨头,分别在视频解码和图形渲染领域发挥着举足轻重的作用。本文将综合两者实战视频播放器,大概技术流程为:ffmpeg拉取rtsp协议视频流,并经过解码、尺寸格式转换为yuv420p后,使用opengl逐帧循环渲染该yuv实时视频。 核心源码 vertexSh…

Web安全扫盲

1、建立网络思维模型的必要 1 . 我们只有知道了通信原理&#xff0c; 才能够清楚的知道数据的交换过程。 2 . 我们只有知道了网络架构&#xff0c; 才能够清楚的、准确的寻找漏洞。 2、局域网的简单通信 局域网的简单通信&#xff08;数据链路层&#xff09; 一般局域网都通…

HTML 显示器纯色亮点检测工具

HTML 显示器纯色亮点检测工具 相关资源文件已经打包成html等文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Html相关程序案例&#xff0c;秉着开源精神的想法&#xff0c;望大家喜欢&#…

ARM发布Armv9.5架构:迈向更强性能与灵活性的新时代

2024年11月30日&#xff0c;ARM正式发布了其最新的Armv9.5架构&#xff0c;这是Arm技术发展的又一重要里程碑。从表中信息来看&#xff0c;Armv9.5架构的发布标志着该公司的架构系列在性能、灵活性和可扩展性方面取得了进一步突破。本次发布不仅是技术上的提升&#xff0c;更是…

被催更了,2025元旦源码继续免费送

“时间从来不会停下&#xff0c;它只会匆匆流逝。抓住每一刻&#xff0c;我们才不会辜负自己。” 联系作者免费领&#x1f496;源&#x1f496;码。 三联支持&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;亲爱的朋友们&#xff0c;感谢你…