学习java后端,最重要的就是要与数据库进行交互,用户可以通过前端页面可以对指定的数据进行增删改查,而今天我就要说一下数据交互,当然,这一章是不涉及数据库,也就是说用户所需要存储的数据我们暂时会存储在内存中,关闭浏览器数据便会丢失,而与数据库交互的博客也会不久发出。
要与数据交互(不管有无涉及数据库),现如今都有固定的编程模式,也就是说,先建立实体类,再建立service层,在设计controller层,数据库的话在实体类后要有一个与数据库交互的类进行处理数据库操作。
这次我建立的实体类是个用户,内含自增id,用户名,邮箱,还有构造函数,get和set函数,即实体类为:
public class User {
private Long id; // 实体一个唯一标识
private String name;
private String email;
public User() { // 无参构造函数
}
public User(Long id, String name, String email) { //有参构造函数
this.id = id;
this.name = name;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
然后就是service层,由于是不与数据库交互,所以我们就是要对数据进行内存的操作,而一般我会将数据存储在HashMap中,然后读取增删操作。
而service层一般的格式都是先建立接口,再建立实现接口的方法,首先我们建立接口:
public interface UserRepository{
/**
* 创建或者修改用户
*/
User saveOrUpdateUser(User user);
/**
* 删除用户
*/
void deleteUser(Long id);
/**
* 根据id查询用户
*/
User getUserById(Long id);
/**
* 获取用户列表
*/
List<User> listUsers();
}
而下面就是service接口的实现,实现是ConcurrentMap来实现,因为其中封装了简单的函数通过id可以查询删除修改等操作,而又使用AtomicLong来实现id的自增,所以实现类为:
@Repository
public class UserRepositoryImpl implements UserRepository {
//为了实现id的自增而引入
private static AtomicLong counter = new AtomicLong();
//使用ConcurrentMap的函数实现增删改查
//其中ConcurrentMap<>括号中,第一个long型指id类型,User指实体类型
private final ConcurrentMap<Long, User> userMap = new ConcurrentHashMap<>();
//保存或修改,其中检查id是否为空,id为空即保存新值,否则修改
@Override
public User saveOrUpdateUser(User user) {
Long id = user.getId();
if (id == null) { // 新建
id = counter.incrementAndGet();
user.setId(id);
}
this.userMap.put(id, user);
return user;
}
//通过id修改
@Override
public void deleteUser(Long id) {
this.userMap.remove(id);
}
//通过id查询
@Override
public User getUserById(Long id) {
return this.userMap.get(id);
}
//打印所有用户
@Override
public List<User> listUsers() {
return new ArrayList<User>(this.userMap.values());
}
}
而下面就是controller层了,与数据交互一定要牢记一个表:
请求类型 | 请求路径 | 功能 |
GET | /mysql | 获取数据库列表 |
POST | /mysql | 创建一个对象 |
GET | /mysql/{id} | 通过id查询一个对象 |
PUT | /mysql/{id} | 通过id修改一个对象 |
DELETE | /mysql/{id} | 通过id删除一个对象 |
查询对象查询列表都是使用get方法,而添加对象就是Post请求,修改对象就是Put请求,删除对象是Delete请求,但是由于thymeleaf对put和delete请求不支持,为了简单,我对put和delete都是直接使用get请求,在与数据库交互中我会使用put和delete请求方式:
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
/**
* 查询所有用户
*/
@GetMapping
public ModelAndView list(Model model) {
model.addAttribute("userList", userRepository.listUsers());
model.addAttribute("title", "用户管理");
return new ModelAndView("users/list","userModel",model);
}
/**
* 根据 id 查询用户
*/
@GetMapping("{id}")
public ModelAndView view(@PathVariable("id") Long id, Model model) {
User user = userRepository.getUserById(id);
model.addAttribute("user", user);
model.addAttribute("title", "查看用户");
return new ModelAndView("users/view","userModel",model);
}
/**
* 获取创建表单页面
*/
@GetMapping("/form")
public ModelAndView createForm(Model model) {
model.addAttribute("user", new User());
model.addAttribute("title", "创建用户");
return new ModelAndView("users/form","userModel",model);
}
/**
* 保存或者修改用户
*/
@PostMapping
public ModelAndView saveOrUpdateUser(User user) {
userRepository.saveOrUpdateUser(user);
return new ModelAndView("redirect:/users");// 重定向到 list页面
}
/**
* 删除用户
*/
@GetMapping("/delete/{id}")
public ModelAndView delete(@PathVariable("id") Long id) {
userRepository.deleteUser(id);
return new ModelAndView("redirect:/users"); // 重定向到 list页面
}
/**
* 获取修改用户的界面
*/
@GetMapping("/modify/{id}")
public ModelAndView modify(@PathVariable("id") Long id, Model model) {
User user = userRepository.getUserById(id);
model.addAttribute("user", user);
model.addAttribute("title", "修改用户");
return new ModelAndView("users/form","userModel",model);
}
}
而前端的页面中的模板是靠thymeleaf实现的,其中分为三个页面,一个是list页面,也就是说,该页面打印所有用户,同时,可以通过该界面访问个人数据页面和添加用户;而个人数据页面是查询个体,同时可以对该个体进行修改删除操作;通过添加或修改用户都要使用form表单,则这时候进入添加表单的页面。
List页面:
<body>
<h3 th:text="${userModel.title}">waylau</h3>
<div>
<a href="/users/form.html" th:href="@{/users/form}">创建用户</a>
</div>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>Email</td>
<td>Name</td>
</tr>
</thead>
<tbody>
<tr th:if="${userModel.userList.size()} eq 0">
<td colspan="3">没有用户信息!</td>
</tr>
<tr th:each="user : ${userModel.userList}">
<td th:text="${user.id}"></td>
<td th:text="${user.email}"></td>
<td ><a th:href="@{'/users/'+${user.id}}" th:text="${user.name}"></a></td>
</tr>
</tbody>
</table>
</body>
查询个体页面:
<body>
<h3 th:text="${userModel.title}">waylau</h3>
<div>
<P><strong>ID:</strong><span th:text="${userModel.user.id}"></span></P>
<P><strong>Name:</strong><span th:text="${userModel.user.name}"></span></P>
<P><strong>Email:</strong><span th:text="${userModel.user.email}"></span></P>
</div>
<div>
<a th:href="@{'/users/delete/'+${userModel.user.id}}">删除</a>
<a th:href="@{'/users/modify/'+${userModel.user.id}}">修改</a>
</div>
</body>
form表单:
<body>
<h3 th:text="${userModel.title}">waylau</h3>
<form action="/users" th:action="@{/users}" method="POST" th:object="${userModel.user}">
<input type="hidden" name="id" th:value="*{id}">
名称:<br>
<input type="text" name="name" th:value="*{name}">
<br>
邮箱:<br>
<input type="text" name="email" th:value="*{email}">
<input type="submit" value="提交">
</form>
</body>
然后就实现了基本的数据交互