依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jpa_sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jpa_sample</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.example.jpa_sample.JpaSampleApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
实体类:
@Entity
@Data
@Accessors(chain = true)
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true,length =20,nullable =true)
@NotBlank(message ="账号不能为空")
@Pattern(regexp = "[a-z|A-Z]\\w{2,9}",message ="账号必须字母开头,且3-10")
private String username;
@Column(nullable =true,length = 20)
@NotBlank(message ="密码不能为空!")
private String password;
private Integer sex;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
@Column(length =100)
private String pic;
}
dao:
import com.example.jpa_sample.pojo.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
public interface UserDao extends JpaRepository<User,Integer> {
User findOneByUsernameAndPassword(@Param("username")String username,@Param("password")String password);
Page<User> findUsersByUsernameContaining(@Param("username")String username, Pageable pageable);
}
service:
@Service
public class UserService {
@Resource
private UserDao userDao;
public Page<User> findPage(String username, Pageable pageable){
return this.userDao.findUsersByUsernameContaining(username,pageable);
}
public boolean saveUser(User user){
//返回刚刚添加的对象在数据库的id
return this.userDao.saveAndFlush(user).getId()>=1;
}
public User findUserById(int id){
return this.userDao.getOne(id);
//return this.userDao.findById(id).get();
}
public void deleteUser(int id){
// User user=this.findUserById(id);
// if(user!=null) {
// this.userDao.delete(user);
// }
this.userDao.deleteById(id);
}
public List<User> findAllUsers(){
return this.userDao.findAll();
}
public User login(User user){
return this.userDao.findOneByUsernameAndPassword(user.getUsername(),user.getPassword());
}
}
控制器:
@Controller
public class UserController {
@Resource
private UserService userService;
@GetMapping("/")
public String index(){
return "redirect:login";
}
@GetMapping("/logout")
public String logout(HttpSession session){
if(session.getAttribute("logUser")!=null){
session.removeAttribute("logUser");
}
return "redirect:login";
}
@GetMapping("/update")
public String toupdate(Model model,int id){
model.addAttribute(this.userService.findUserById(id));
return "update";
}
@PostMapping("/update")
public String update(@Valid User user, BindingResult br, MultipartFile photo){
if(br.hasErrors()){
br.getAllErrors().forEach(error -> {
System.out.println(error.getDefaultMessage());
});
return "update";
}
String path=System.getProperty("user.dir")+"\\src\\main\\resources\\static\\upload";
System.out.println(path);
String new_name= UUID.randomUUID().toString().substring(0 ,7)+photo.getOriginalFilename();
File file=new File(path+File.separator+new_name);
if(!photo.getOriginalFilename().isEmpty()) {
user.setPic(new_name);//重新修改头像
try {
photo.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
}
}
if(this.userService.saveUser(user)){
return "redirect:list";
}
return "update";
}
@GetMapping("/add")
public String toadd(@ModelAttribute("user")User user){
return "add";
}
@PostMapping("/add")
public String add(@Valid User user, BindingResult br, MultipartFile photo){
if(br.hasErrors()){
br.getAllErrors().forEach(error -> {
System.out.println(error.getDefaultMessage());
});
return "add";
}
String path=System.getProperty("user.dir")+"\\src\\main\\resources\\static\\upload";
System.out.println(path);
String new_name= UUID.randomUUID().toString().substring(0 ,7)+photo.getOriginalFilename();
File file=new File(path+File.separator+new_name);
user.setPic(new_name);
try {
photo.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
}
if(this.userService.saveUser(user)){
return "redirect:list";
}
return "add";
}
@GetMapping("/list")
public String list(Model model,
@RequestParam(name="mohu",defaultValue="",required=false) String mohu,
@RequestParam(name = "offset",defaultValue ="0")Integer offset,
@RequestParam(name="pagesize",defaultValue ="2")Integer pagesize){
Page<User> pager=this.userService.findPage(mohu, PageRequest.of(offset, pagesize));
// pager.getTotalPages();//总页数
// pager.isLast();
// pager.isFirst();
// pager.getNumber();
// pager.getTotalElements();//
// pager.getContent();
model.addAttribute("pager",pager);
model.addAttribute("mohu",mohu);
return "list";
}
@GetMapping("/delete/{id}")
@ResponseBody
public boolean delete(@PathVariable("id")int id){
try {
this.userService.deleteUser(id);
return true;
}catch (Exception e){
e.printStackTrace();
}
return false;
}
@GetMapping("/login")
public String tologin(@ModelAttribute("user") User user){
return "login";
}
@PostMapping("/login")
public String login(@Valid User user, BindingResult br, HttpSession session,Model model){
User logUser= this.userService.login(user);
if(logUser!=null){
session.setAttribute("logUser",logUser);
return "redirect:list";
}else{
model.addAttribute("mess","<font color='red'>登录失败,错误的账号或密码!</font>");
return "login";
}
}
}
页面:
静态资源:include.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<span th:fragment="myjs">
<script th:src="@{js/jquery-3.6.0.min.js}"></script>
<script th:src="@{js/bootstrap.min.js}"></script>
<link rel="stylesheet" th:href="@{css/bootstrap.min.css}">
</span>
</head>
</html>
列表:list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<span th:include="~{include::myjs}"></span>
<script>
$(function () {
$(".btn-warning").click(function () {
if(confirm("??")){
$.get(
"delete/"+$(this).val(),
function (obj) {
if(obj){
alert("OK");
location.reload();
}else{
alert("Sorry");
}
}
)
}
})
$(".btn-primary").click(function () {
location="update?id="+$(this).val();
})
})
</script>
</head>
<body>
<div class="container">
<h4>欢迎<span th:text="${session.logUser.username}"></span>登录。
<a th:href="@{logout}">注销</a>
</h4>
<form>
<input placeholder="请输入账号" type="text" title="请输入要搜索的账号名称" name="mohu" th:value="${mohu}">
<button class="btn btn-info">搜索</button>
</form>
<table class="table table-bordered table-hover">
<tr>
<td>序号</td>
<td>编号</td>
<td>账号</td>
<td>密码</td>
<td>性别</td>
<td>生日</td>
<td>头像</td>
<td>
<a th:href="@{add}">添加</a>
</td>
</tr>
<tr th:each="user,index:${pager.content}" th:object="${user}">
<td th:text="${index.count}"></td>
<td th:text="*{id}"></td>
<td th:text="*{username}"></td>
<td th:text="*{password}"></td>
<td th:text="*{sex==0 ? '男':'女'}"></td>
<td th:text="*{#dates.format(birthday,'yyyy-MM-dd')}"></td>
<td>
<img th:src="@{'/upload/'+*{pic}}" width="50px" height="50px">
</td>
<td>
<button th:value="*{id}" class="btn btn-warning">删除</button>
<button th:value="*{id}" class="btn btn-primary">修改</button>
</td>
</tr>
<tr>
<td colspan="10" align="center">
共<span th:text="${pager.totalPages}"></span>页,当前第<span th:text="${pager.number+1}"></span>页,
共<span th:text="${pager.totalElements}"></span>条数据。
<a th:href="@{list(offset=0,mohu=${mohu})}">首页</a>
<a th:href="@{list(offset=${pager.number-1},mohu=${mohu})}" th:if="${not pager.isFirst()}">上页</a>
<a th:href="@{list(offset=${pager.number+1},mohu=${mohu})}" th:if="${not pager.isLast()}">下页</a>
<a th:href="@{list(offset=${pager.totalPages},mohu=${mohu})}">末页</a>
</td>
</tr>
</table>
</div>
</body>
</html>
添加:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<span th:include="~{include::myjs}"></span>
<title>Title</title>
</head>
<body>
<div class="container">
<form enctype="multipart/form-data" method="post" th:object="${user}">
账号:<input type="text" name="username">
<span th:errors="*{username}" th:if="${#fields.hasErrors('username')}"></span><br>
密码:<input type="text" name="password">
<span th:errors="*{password}" th:if="${#fields.hasErrors('password')}"></span><br>
性别:<input type="radio" name="sex" value="0">男
<input type="radio" name="sex" value="1">女<br>
生日:<input type="text" name="birthday"><font>yyyy-MM-dd</font><br>
头像:<input type="file" name="photo" ><br>
<button class="btn btn-success">提交</button>
</form>
</div>
</body>
</html>
修改:update.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<span th:include="~{include::myjs}"></span>
<title>Title</title>
</head>
<body>
<div class="container">
<form enctype="multipart/form-data" method="post" th:object="${user}">
<input type="hidden" th:field="*{id}">
<input type="hidden" th:field="*{pic}">
账号:<input type="text" th:field="*{username}">
<span th:errors="*{username}" th:if="${#fields.hasErrors('username')}"></span><br>
密码:<input type="text" th:field="*{password}">
<span th:errors="*{password}" th:if="${#fields.hasErrors('password')}"></span><br>
性别:<input type="radio" name="sex" value="0" th:field="*{sex}">男
<input type="radio" name="sex" value="1" th:field="*{sex}">女<br>
生日:<input type="text" name="birthday" th:field="*{birthday}"><font>yyyy-MM-dd</font><br>
头像:<img th:src="@{'/upload/'+*{pic}}" width="50px" height="50px">
<input type="file" name="photo" ><br>
<button class="btn btn-success">提交</button>
</form>
</div>
</body>
</html>
登录:login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<span th:include="~{include::myjs}"></span>
</head>
<body>
<div class="container">
<span th:utext="${mess}"></span>
<form method="post" th:object="${user}">
账号:<input type="text" name="username">
<span th:errors="*{username}" th:if="${#fields.hasErrors('username')}"></span><br>
密码:<input type="text" name="password">
<span th:errors="*{password}" th:if="${#fields.hasErrors('password')}"></span><br>
<button class="btn btn-success">登录</button>
</form>
</div>
</body>
</html>