# Java 常用代码片段
# 1. JSON
# 1.1. JSON字符串 转 对象列表
ObjectMapper mapper = new ObjectMapper();
String userListStr = "[ { \"name\": \"张三\", \"age\": 18 } ]";
List<User> userList = mapper.readValue(
userListStr,
mapper.getTypeFactory().constructCollectionType(List.class, User.class)
);
class User {
private String name;
private Integer age;
}
# 2. 类型
# 2.1. 判断字符串是不是日期
String dateString = "2023-04-01";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 转化失败会抛异常
LocalDate date = LocalDate.parse(dateString, formatter);
System.out.println(date);
String dateTimeString = "2023-04-01T15:30:00";
// 使用 单引号 包裹特殊字符
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime);
# 2.2. 字符串 转 数字
import org.apache.commons.lang3.math.NumberUtils;
private static Double objectToDouble(Object obj) {
if (obj == null) {
return null;
}
String valueStr = obj.toString();
if (!NumberUtils.isCreatable(valueStr)) {
return null;
}
double value = NumberUtils.toDouble(valueStr);
return value;
}
# 3. 字节数组与流
字符串 转 字节数组:
String content = "MinIO, 你好!";
byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
InputStream 转 byteArray:
byte[] byteArray = IOUtils.toByteArray(byteArrayInputStream);
String content = new String(byteArray, StandardCharsets.UTF_8);
byteArray 转 InputStream:
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
# 4. 列表
# 4.1. 列表 转 Map
/*
[
{ id: 1, age: 18 },
{ id, 2, age: 18 }
]
=>
{
1: { id: 1, age: 18 },
2: { id: 2, age: 18 }
}
*/
Map<Long, User> map = list.stream().collect(Collectors.toMap(User::getId, Function.identity()));
/*
[
{ id: 1, age: 18 },
{ id, 2, age: 18 }
]
=>
{
1: 18 ,
2: 18
}
*/
Map<Long, User> map = list.stream().collect(Collectors.toMap(User::getId, User::getAge));
# 4.2. 列表 分组
/*
[
{ id: 1, age: 18 },
{ id, 2, age: 18 },
{ id, 3, age: 20 }
]
=>
{
18: [{ id: 1, age: 18 }, { id, 2, age: 18 }],
20: [{ id, 3, age: 20 }]
}
*/
Map<Long, List<User>> collect = list.stream().collect(Collectors.groupingBy(User::getAge));
# 5. 定时任务
# 5.1. 在 SpringBoot 中使用定时任务
步骤1: 在引导类上添加 @EnableScheduling 注解
@SpringBootApplication
@EnableScheduling
public class LabWindApplication extends SpringBootServletInitializer { /* ... */ }
步骤2: 在 bean 的方法上添加 @Scheduled(cron = "0 0/1 * * * ? ")
@Service
public class BookServiceImpl implements BookService {
// 该方法是 public
@Scheduled(cron = "0 0/1 * * * ? ") // 每分钟执行一次
public void setInterval() {
System.out.println("run ...");
}
@Scheduled(fixedRate = 1000) // 每分钟执行一次
@Scheduled(fixedRate = 1, timeUnit = TimeUnit.MINUTES) // 每分钟执行一次
}
@Scheduled 的参数:
- cron: 基于 cron 表达式定义执行周期,参考 Cron在线表达式生成器 (opens new window)
- fixedDelay: 任务执行结束后间隔固定时间再次执行(毫秒)
- fixedRate: 任务间隔固定时间执行(毫秒),若当前任务未完成,后续执行将等待当前任务完成
- timeUnit: 时间单位。TimeUnit.MILLISECONDS (默认) | TimeUnit.MINUTES | ...
注意:
- 该任务需要等待 SpringBook 完全启动后,(有些项目要好几分钟才会开始执行)才会执行定时任务。
# 6. 资源目录
# 6.1. 获取 resource 目录下的资源
import org.apache.shiro.io.ResourceUtils;
InputStream inputStream = ResourceUtils.getInputStreamForPath("classpath:application.yml");
# 7. 字符串
# 7.1. 字符串模板
import java.text.MessageFormat;
String name = "张三";
int age = 18;
String pattern = "我是 {0},今年 {1} 岁";
String result = MessageFormat.format(pattern, name, age);
System.out.println(result); //=> "我是 张三,今年 18 岁"
# 8. 事务
# 8.1. 回滚
回滚所有:
@Transactional(rollbackFor = Exception.class)
public void doStep_1() {
try {
// ......
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
@Transactional(rollbackFor = Exception.class)
public void doStep_2() {
try {
// ......
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
// doStep_1() 或 doStep_2() 抛异常,会导致 doStep_1 、doStep_2 都回滚
@Transactional(rollbackFor = Exception.class)
public void doSomething() {
doStep_1();
doStep_2();
}
回滚部分:
@Transactional(rollbackFor = Exception.class)
public void doStep_1() {
// 回滚点
Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
try {
// ......
} catch (Exception e) {
// 回滚到指定 回滚点
TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
}
}
@Transactional(rollbackFor = Exception.class)
public void doStep_2() {
// 回滚点
Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
try {
// ......
} catch (Exception e) {
// 回滚到指定 回滚点
TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
}
}
// doStep_1() 或 doStep_2() 抛异常,只会回滚 step 方法本身涉及的 增删改,不会导致其他 step 方法回滚
@Transactional(rollbackFor = Exception.class)
public void doSomething() {
doStep_1();
doStep_2();
}
参考:
# 9. Spring
# 9.1. 在 非事务方法 里调用 事务方法
获取事务代理对象
步骤 1. 显式引入 aspectj 依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
步骤 2. 在启动类上通过注解暴露代理对象
@EnableAspectJAutoProxy(exposeProxy = true)
@SpringBootApplication
public class XyzApplication {
public static void main(String[] args) {
SpringApplication.run(XyzApplication.class, args);
}
}
步骤 3. 获取事务代理对象
@Service
public class UserServiceImpl implements IUserService {
// 非事务方法
public void deleteUser() {
IUserService userServiceProxy = (IUserService) AopContext.currentProxy();
userServiceProxy.doDeleteUser();
}
// 事务方法
@Transactional
public void doDeleteUser() {
// ...
}
}
# 9.2. 基于 lombok 做构造函数的依赖注入
// 针对加了 final 的成员变量,会添加到构造函数的形参中,进而会被 spring 注入依赖
@RequiredArgsConstructor
@Controller
public class UserController {
private final IUserService userService;
}
// 等价于:
@Controller
public class UserController {
@Autowire
private IUserService userService;
}
上一篇: 下一篇:
本章目录