接上一节,SpringBoot数据库API

数据库事务

TestTransController.java

  • 事务,要么完全执行,要么完全不执行。
  • 添加@Transactional注解,表明操作为事务。

当不加注解运行时,第一条记录会被添加至表中,但第二条记录会报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.mysqlapi.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.mysqlapi.entity.User;
import com.mysqlapi.repository.UserRepository;

import jakarta.transaction.Transactional;
@RestController
@Transactional
public class TestTransController {
//实例化接口
@Autowired
private UserRepository repository;
//注意:数据库要改为InnoDB引擎
@GetMapping("/create2Users")

public void create2Users(){
User user1 = new User();
user1.setUserName("test1");
user1.setRole("3");
repository.save(user1);

User user2 = new User();
user1.setUserName("test2");
user2.setRole("10"); //此操作会报错
repository.save(user2);
}
}

单元测试

对软件最小可测试单元(Java,即类)进行测试。

添加依赖工具

1
2
3
4
5
6
7
<dependency>
<groupId>junit</groupId>
<artifactId>
junit
</artifactId>
<scope>test</scope>
</dependency>

进入单元测试

eclipse进入单元测试

在我们写好一个类时,我们可以使用单元测试对里面的方法进行测试。

可以借助junit中的Assert类,提供的方法。

image-20230311093458113

执行单元测试类

class <classname> {}前添加注解

  • @RunWith(SpringRunner.class)
  • @SpringBootTest

权限管理

不同的用户拥有不同的角色,不同角色的权限不同,可以执行的操作也不一样。如何在SpringBoot中实现对权限的控制呢?

实现简单的权限管理,我们可以使用cookie、session、线程存储、数据库等。

示例:线程本地存储

CurrentUserHolder.java

这个类创建了两个方法:

  1. get(),用户获取线程存储中的数据
  2. set(),设置线程存储中的数据
1
2
3
4
5
6
7
8
9
10
11
package com.mysqlapi.holder;

public class CurrentUserHolder {
public static final ThreadLocal<String> holder = new ThreadLocal<>();
public static String get() {
return holder.get()==null?"null":holder.get();
}
public static void set(String username) {
holder.set(username);
}
}

CheckUserService.java

service层

  • 进行身份的检查,若不匹配则抛出异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.mysqlapi.service;

import org.springframework.stereotype.Service;

import com.mysqlapi.holder.CurrentUserHolder;

@Service
public class CheckUserService {
public void check() throws Exception {
String user=CurrentUserHolder.get();
if(!user.equals("admin")) {
throw new Exception("[异常]你不是管理员");
}
}
}

UserService.java

service层

  • 实例化CheckUserService
  • 在每个UserService的方法中(以findAll()为例),加入CheckUserService检查(调用check()方法),设置抛出异常(throws Exception)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.mysqlapi.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
@Autowired
private CheckUserService checkUserService;
public void findAll() throws Exception {
checkUserService.check();
System.out.println("查找成功!");
}
public void addUser() {
System.out.println("插入成功!");
}
}

使用这种方法进行权限管理,我们会发现在UserService.java中,每有一个方法需要权限都要添加check()throws Exception这样使得我们的代码显得冗余、低效。如何解决呢?这就需要我们学习AOP面向切面编程。在下一节将进行学习。