Keep and carry on.
post @ 2023-08-25

GROUP_CONCAT()函数

创建表person_info,并插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

CREATE TABLE `person_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`family` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;


INSERT INTO niffler.person_info (name, family) VALUES('张三', '张三爸');
INSERT INTO niffler.person_info (name, family) VALUES('张三', '张三妈');
INSERT INTO niffler.person_info (name, family) VALUES('李四', '李四爸');
INSERT INTO niffler.person_info (name, family) VALUES('李四', '李四妈');
INSERT INTO niffler.person_info (name, family) VALUES('李四', '李四大哥');
INSERT INTO niffler.person_info (name, family) VALUES('王二', '王二爷爷');
INSERT INTO niffler.person_info (name, family) VALUES('王二', '王二姐姐');
Read More

Integer经典面试问题:两个Integer对象都赋值为128,这两个对象比较是否相同?为什么?

回答这个问题,首先我们要知道,在Java中,当你写Integer a = 1; 实际上是调用了Java的自动装箱功能。这会将整数 1 自动装箱为Integer对象,然后将这个对象赋值给变量a。

自动装箱功能是由编译器自动插入的,实际上它相当于执行了如下的代码:

1
Integer a = Integer.valueOf(1);

这里的valueOf方法是Integer类的一个静态方法,它的作用就是将传入的参数(通常是基本数据类型)自动转换为对应的包装类对象。对于Integer类来说,就是将整数值转换为Integer对象。

Read More

InnoDB is a general-purpose storage engine that balances high reliability and high performance. In MySQL 8.0, InnoDB is the default MySQL storage engine. Unless you have configured a different default storage engine, issuing a CREATE TABLE statement without an ENGINE clause creates an InnoDB table.

InnoDB是一种平衡高可靠性和高性能的通用存储引擎。在MySQL 8.0中,InnoDB是MySQL默认的存储引擎。除非您配置了不同的默认存储引擎,否则发出不带 ENGINE 子句的 CREATE TABLE 语句将创建一个 InnoDB 表。

Read More

GROUP_CONCAT()函数输出的结果,发现被截取了一部分,并没有显示完整,原来GROUP_CONCAT() 默认的输出长度为1024字节,超出的部分会被截掉不显示。

Read More
post @ 2023-07-14

1. SpringBoot

1.1 SpringBoot的作用

SpringBoot是一个快速构建项目并简化项目配置的工具,内部集成了Tomcat及大多数第三方应用和Spring框架的默认配置。与我们学习的SpringMVC和SpringCloud并无冲突,SpringBoot提供的这些默认配置,大大简化了SpringMVC、SpringCloud等基于Spring的Web应用的开发。

1.2.SpringBoot的自动配置原理(如何实现)?

SpringBoot的自动配置是如何实现的?

一般我们的SpringBoot项目启动类都会添加@SpringBootApplication注解,而这个注解的其中一个二级注解是@EnableAutoConfiguration注解。而@EnableAutoConfiguration注解通过@Import注解,以ImportSelector接口的方法来导入classpath下的META-INF/spring.factories文件,这些文件中会指定需要加载的一些类名称。

这些类一般都加了@Configuration注解,并且完成了对某框架(例如Redis、SpringMVC)的默认配置,当这些类符合条件时,就会被实例化,其中的配置生效,那么自动配置自然生效了。

Read More

执行update更新操作

1
2
3
4
5
6
7
8
9
10
11
<update id="batchUpdate" parameterType="java.util.List">
<foreach collection="list" item="item" separator=";" open="" close="">
update test_table
<set>
<if test="item.a != null">output_amount = #{item.a},</if>
<if test="item.b!= null">invoice_amount = #{item.b},</if>
<if test="item.c!= null">payment_amount = #{item.c},</if>
</set>
where id = #{item.id}
</foreach>
</update>

执行报错:

1
2
3
4
Error updating database.  
Cause: java.sql.SQLSyntaxErrorException:
You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use near 'update test_table set a = 1, ' at line 14

刚开始出现这个错误,以为是update语句写的有问题,但是检查了很多遍都没有问题。奇怪的是,同样的代码,同样的数据,本地启的环境不行,测试环境却可以。经过同事提醒了一下,于是检查了一下配置文件,果然发现配置文件上的jdbc配置,测试环境比开发环境多了个allowMultiQueries=true

1
jdbc:mysql://127.0.0.1:3306/db?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true

MyBatis默认情况下不允许批量插入或更新数据的原因是出于安全考虑。在许多情况下,数据的插入和更新都需要经过验证和控制,以确保数据的完整性和一致性。如果允许默认的批量操作,可能会导致不正确的数据插入或更新,从而影响应用程序的正常运行。

通过配置allowMultiQueries=true可以开启MyBatis的批量操作功能。这个配置项告诉MyBatis允许在单个数据库连接中执行多个SQL语句,从而实现批量插入或更新数据的功能。但是要注意,在开启批量操作之前,确保你已经了解并理解了可能引发的安全风险,并且在使用批量操作时要进行适当的验证和控制,以确保数据的完整性和安全性。

Read More

使用HistoryService接口来查询历史流程实例

在Flowable中,已终止的流程实例不能通过RuntimeService接口直接查询到。相反,你需要使用HistoryService接口来查询历史流程实例,并从中筛选出已终止的实例。以下是正确的步骤:

  1. 确保你的应用程序连接到正确的Flowable流程引擎实例。你需要使用Flowable的API来执行后续的操作。

  2. 使用HistoryService接口的createHistoricProcessInstanceQuery()方法构建查询,设置适当的条件来筛选已终止的流程实例。

1
2
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery()
.finished();
  1. 执行查询并获取已终止的流程实例列表。
1
List<HistoricProcessInstance> terminatedInstances = query.list();
  1. 根据需要选择要重启的流程实例。你可以根据流程实例的ID或其他属性进行选择。

  2. 如果你需要将已终止的流程实例重新激活,可以创建一个新的流程实例,或者使用历史流程实例中的数据进行修复。请注意,这取决于你的业务需求和流程定义的复杂性。

请注意,已终止的流程实例是历史数据,因此无法直接重新激活。你需要根据业务需求进行相应的处理。使用HistoryService接口可以提供有关已终止流程实例的详细信息,但不能直接操作它们。

Read More
1
2
List<String> list = new ArrayList<>();
Long[] item = list.toArray(new Long[0]);

List<String>直接以toArray的方式转换Long数组是错误的,运行后报错:

1
Exception in thread "main" java.lang.ArrayStoreException

查看java.util.List.toArray(T[])方法,注释中明确写到:

@throws ArrayStoreException if the runtime type of the specified array is not a supertype of the runtime type of every element in this list 如果指定数组的运行时类型不是此列表中每个元素的运行时类型的超类型

明显Long类型不是String类型的超类。

可以通过下面的方式实现

1
2
List<String> stringList = Arrays.asList("1", "2", "3");
Long[] item = list.stream().map(Long::valueOf).toArray(Long[]::new);
Read More

背景描述:SpringBoot项目构建打包生成的jar包,在资源文件夹下有个普通txt文件,路径:/templates/content.txt

方式一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
File file = new File(ResourceUtils.getURL("classpath:").getPath());
File templateFile = new File(file, "/templates/content.txt");
BufferedReader reader = null;
StringBuffer sbf = new StringBuffer();
try {
reader = new BufferedReader(new FileReader(file));
String tempStr;
while ((tempStr = reader.readLine()) != null) {
sbf.append(tempStr);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return sbf.toString();
Read More

Add Maven Dependency

1
2
3
4
5
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>

Image File Convert Base64 String

1
2
3
byte[] fileContent = FileUtils.readFileToByteArray(new File(filePath));
String encodedString = Base64.getEncoder().encodeToString(fileContent);

Base64 String Convert Image File

1
2
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
FileUtils.writeByteArrayToFile(new File(outputFileName), decodedBytes);
Read More
⬆︎TOP