项目已上传:https://codechina.csdn.net/qq_36286039/javaee 注意本项目是包含后文JPA 查询用法内容的,若您想看只有本文内容的项目,请下载: https://download.csdn.net/download/qq_36286039/21941623?spm=1001.2014.3001.5501
先看下效果:
id是自动生成的,跳数了是因为之前删过数据 删除后
一些术语、概念
entity-dao-service-web层
准备工作
- 新建 Spring Boot 项目:jpademo2
- MySQL数据库:还是testdb user表
- 添加相关依赖:
- pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>Eonasdan-bootstrap-datetimepicker</artifactId>
<version>4.17.47</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
<version>0.31</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
不仅要添加 Lombok 依赖,idea 还要安装 Lombok 插件
安装 Lombok 插件方法:
Lombok 插件需要开启 Enable Annotation Processing
#自动生成数据库表(关键)
spring.jpa.hibernate.ddl-auto=update
#mysql数据库连接配置(非常重要)
spring.datasource.url = jdbc:mysql://localhost:3306/testdb?serverTimezone=Asia/Shanghai
spring.datasource.username = root
spring.datasource.password = root
#mysql数据库驱动程序(重要)
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
#jpa配置:在控制台显示Hibernate的sql(可选)
spring.jpa.show-sql = true
#其他配置:关闭Thymeleaf 的缓存
spring.thymeleaf.cache = false
项目实践
- 创建实体类
- 在新建 entity 包中新建 User 类:映射数据库表
user.java
package com.example.jpademo2.entity;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
@Entity
@Data
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false,unique = true,length = 20)
private String username;
@Column(nullable = false,length = 20)
private String password;
@Column(nullable = false)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date regdate;
@Column(nullable = false)
private int status;
}
- 创建数据接口访问层(Repository仓库)
- 在新建 repository 包中新建 UserRepository 接口。
- Repository 接口要继承 JpaRepository<User, Long> 接口。
package com.example.jpademo2.repository;
import com.example.jpademo2.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User,Long> {
}
- 创建服务层接口
- 在新建 service 包中新建 UserService 接口。
- UserService 接口中声明业务相关方法(根据业务需要)。
package com.example.jpademo2.service;
import com.example.jpademo2.entity.User;
import java.util.List;
public interface UserService {
public List<User> getUserList();
public User findUserById(Long id);
public void save(User user);
public void edit(User user);
public void delete(Long id);
}
- 实现服务层接口
- 在 service 包中新建 UserServiceImp 类(实现UserService接口)。
- 服务实现类调用 UserRepository 实现具体业务。
这段代码里注意不要掉了@Service
package com.example.jpademo2.service;
import com.example.jpademo2.entity.User;
import com.example.jpademo2.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImp implements UserService{
@Autowired
private UserRepository userRepository;
@Override
public List<User> getUserList(){
return userRepository.findAll();
}
@Override
public User findUserById(Long id){
return userRepository.findById(id).get();
}
@Override
public void edit(User user){
userRepository.save(user);
}
@Override
public void save(User user){
userRepository.save(user);
}
@Override
public void delete(Long id){
userRepository.deleteById(id);
}
}
- 调用服务层完成业务控制
- 在新建 controller 包中新建 UserController 控制器。
- 上面的
@Service 要是掉了,这里会报错的
package com.example.jpademo2.controller;
import com.example.jpademo2.entity.User;
import com.example.jpademo2.service.UserService;
import com.example.jpademo2.service.UserServiceImp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/")
public String index() {
return "redirect:/list";
}
@RequestMapping("/list")
public String list(Model model) {
List<User> users = userService.getUserList();
model.addAttribute("users", users);
return "user/list";
}
@RequestMapping("/add")
public String add() {
return "user/add";
}
@PostMapping("/add")
public String add(User user) {
user.setRegdate(new Date());
user.setStatus(0);
userService.save(user);
return "redirect:/list";
}
@RequestMapping("/edit/{id}")
public String edit(Model model, @PathVariable Long id) {
User user=userService.findUserById(id);
model.addAttribute("user", user);
return "user/edit";
}
@PostMapping("/edit")
public String edit(User user) {
userService.edit(user);
return "redirect:/list";
}
@RequestMapping("/delete/{id}")
public String delete(Model model,@PathVariable Long id) {
User user=userService.findUserById(id);
model.addAttribute("user", user);
return "user/delete";
}
@PostMapping("/delete/{id}")
public String delete(@PathVariable Long id) {
userService.delete(id);
return "redirect:/list";
}
}
- 视图层:
- 在 templates 中新建 user 文件夹,添加相关页面文件。
list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
</head>
<body>
<div class="container">
<h2>用户列表</h2>
<div class="with:80%">
<div style="margin: 20px;">
<a href="/add" th:href="@{/add}" class="btn btn-info">添加用户</a>
</div>
<table class="table table-hover">
<tr>
<th>用户id</th>
<th>用户名</th>
<th>密码</th>
<th>创建时间</th>
<th>用户状态</th>
<th>操作</th>
<th>操作</th>
</tr>
<tr th:each="user : ${users}">
<th scope="row" th:text="${user.id}">1</th>
<td th:text="${user.username}">neo</td>
<td th:text="${user.password}">123456</td>
<td th:text="${#dates.format(user.regdate,'yyyy/MM/dd HH:mm:ss')}">2020/11/11</td>
<td th:text="${user.status}">0</td>
<td><a th:href="@{/edit/{id}(id=${user.id})}">编辑</a></td>
<td><a th:href="@{/delete/{id}(id=${user.id})}">删除</a></td>
</tr>
</table>
</div>
</div>
</body>
</html>
add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>add</title>
<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
</head>
<body>
<div class="container">
<h3 class="col-sm-offset-1">添加用户</h3>
<div>
<form class="form-horizontal" th:action="@{/add}" method="post">
<div class="form-group">
<label for="username" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="username" id="username" placeholder="用户名"/>
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码</label>
<div class="col-sm-6">
<input type="password" class="form-control" name="password" id="password" placeholder="密码"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-6">
<input type="submit" value="保存" class="btn btn-info"/>
<input type="reset" value="重填" class="btn btn-info col-sm-offset-1"/>
<a th:href="@{/list}" class="btn btn-info col-sm-offset-1">返回</a>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
delete.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
</head>
<body>
<div class="container">
<h3 class="col-sm-offset-1">确认删除用户</h3>
<div>
<form class="form-horizontal" th:action="@{/delete/{id}(id=${user.id})}" th:object="${user}" method="post">
<input type="hidden" name="id" th:value="*{id}"/>
<div class="form-group">
<label class="col-sm-2 control-label">编号</label>
<div class="col-sm-6">
<label class="control-label" th:text="*{id}">id</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">用户名</label>
<div class="col-sm-6">
<label class="control-label" th:text="*{username}">username</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">密码</label>
<div class="col-sm-6">
<label class="control-label" th:text="*{password}">password</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">注册日期</label>
<div class="col-sm-6">
<label class="control-label" th:text="*{#dates.format(regdate,'yyyy-MM-dd HH:mm:ss')}">regdate</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">状态</label>
<div class="col-sm-6">
<label class="control-label" th:text="*{status}">status</label>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-6">
<input type="submit" value="确认删除" class="btn btn-info"/>
<a href="/list" th:href="@{/list}" class="btn btn-info col-sm-offset-1">返回</a>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
edit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>user</title>
<script th:src="@{/webjars/jquery/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
<link th:href="@{/webjars/bootstrap/css/bootstrap.min.css}" rel="stylesheet">
<script th:src="@{/webjars/momentjs/min/moment-with-locales.js}"></script>
<link th:href="@{/webjars/Eonasdan-bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css}" rel="stylesheet">
<script th:src="@{/webjars/Eonasdan-bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js}"></script>
</head>
<body class="container">
<br/>
<h1>修改用户</h1>
<br/><br/>
<div class="with:80%">
<form class="form-horizontal" th:action="@{/edit}" th:object="${user}" method="post">
<input type="hidden" name="id" th:value="*{id}"/>
<div class="form-group">
<label for="username" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="username" id="username" th:value="*{username}"
placeholder="用户名"/>
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="password" id="password" th:value="*{password}"
placeholder="密码"/>
</div>
</div>
<div class="form-group">
<label for="regdate" class="col-sm-2 control-label">注册日期</label>
<div class="col-sm-6">
<div class="input-group" id='datetimepicker'>
<input type='text' class="form-control" id="regdate" name="regdate"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class="form-group">
<label for="status" class="col-sm-2 control-label">用户状态</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="status" id="status" th:value="*{status}"
placeholder="用户状态"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-6">
<input type="submit" value="保存" class="btn btn-info"/>
<a href="/list" th:href="@{/list}" class="btn btn-info col-sm-offset-1">返回</a>
</div>
</div>
</form>
</div>
<script th:inline="javascript">
$(function () {
$('#datetimepicker').datetimepicker({
format: 'YYYY-MM-DD HH:mm:ss',
locale: moment.locale('zh-cn'),
defaultDate: "1990-1-1"
});
});
</script>
</body>
</html>
至此,你已经可以运行了,访问localhost:8080/list 试试吧!
|