继上一篇《从零开始学SpringBoot-增删改查需求》的 需求功能描述,这篇文章主要是讲解实现思路和对应的实现代码,如大家发现实现过程中有疑问或者是有其他的实现注意点,可以留言,便于学习和交流。
本篇文章对增删改查需求的实现,主要是结合了SpringBoot+MyBastis+MySQL,其中SpringBoot的代码结构直接从官网上下载demo,在pom.xml中集成JSP、MyBatis和MySQL的数据源,实现的代码的目录结构如图:
分解功能,描述+代码形式来讲解实现功能:
1.基本配置
1.1.pom.xml配置,使用到的依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>priveded</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>priveded</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.2.application.properties文件配置
#页面默认前缀目录和后缀
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
#关闭默认模板引擎
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=false
#数据库信息
spring.datasource.url=jdbc:mysql://localhost:3306/mytest?useSSL=false
spring.datasource.username=root
spring.datasource.password=mysql2017
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
2.有了上述的配置后,现在开始考虑实现
本篇文章主要以webapp中的jsp界面调用controller,通过controller调用service,在通过service调用Mapper,Mapper操作实体Bean映射,与数据库进行数据的操作。其中有些部分省略,例如service定义接口,在写入实现,由于考虑到对SpringBoot集成MyBatis对数据库进行操作,所以就不会细化太多层次。
2.1.实体类(User.java),与数据库中的字段对应
package com.example.demo.bean;
public class User {
private int id;
private String name;
private String password;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2.2.编写UserMapper.java映射器类
针对此类,一般有两种实现方式来操作数据库
1)注解:@Insert、@Select、@Update、@Delete
2)xml文件配置
本篇文章中使用第一种:注解的方式来实现,大家有兴趣可以使用xml文件配置
package com.example.demo.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.example.demo.bean.User;
@Mapper
public interface UserMapper {
/**
* 全部用户查询
* @return
*/
@Select("SELECT ID,NAME,PASSWORD,AGE FROM USER")
List<User> findAll();
/**
* 新增用户
*/
@Insert("INSERT INTO USER(NAME,PASSWORD,AGE)VALUES(#{name}, #{password}, #{age})")
void addUser(User user);
/**
* 修改用户
*/
@Update("UPDATE USER SET NAME=#{name}, PASSWORD=#{password}, AGE=#{age} WHERE ID=#{id}")
void updateUser(User user);
/**
* 删除用户
*/
@Delete("DELETE FROM USER WHERE ID=#{id}")
void deleteUser(int id);
@Select("SELECT ID,NAME,PASSWORD,AGE FROM USER WHERE ID=#{id}")
User findById(@Param("id")int id);
}
注意:在类的方法上,本篇文章使用了@Mapper的注解来当前UserMapper注入到bean容器中,原因是因为此篇文章中只是用了一个Mapper的类,如果存在很多的话,建议大家在SpringBoot的启动类上添加@MapperScan("com.example.demo.mapper.*")来扫描Mapper类注入。
2.3.编写service和controller类
UserService.java代码:
package com.example.demo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.bean.User;
import com.example.demo.mapper.UserMapper;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
/**
* 获取全部的用户
* @return
*/
public List<User> findAll() {
return userMapper.findAll();
}
/**
* 添加用户
* @param user
*/
@Transactional
public void addUser(User user) {
userMapper.addUser(user);
}
/**
* 修改用户
* @param user
*/
@Transactional
public void updateUser(User user) {
userMapper.updateUser(user);
}
/**
* 删除用户
* @param id
*/
@Transactional
public void deleteUser(int id) {
userMapper.deleteUser(id);
}
/**
* 查询指定用户
* @param id
* @return
*/
public User findById(int id) {
return userMapper.findById(id);
}
}
UserController.java代码
package com.example.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.demo.bean.User;
import com.example.demo.service.UserService;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/listUser")
public String listUser(Model model) {
List<User> users = userService.findAll();
model.addAttribute("users", users);
return "listUser";
}
@RequestMapping("/toAdd")
public String toAdd() {
return "/addUser";
}
@RequestMapping("/add")
public String addUser(User user) {
userService.addUser(user);
return "redirect:/listUser";
}
@RequestMapping("/toUpdate")
public String toUpdate(Model model, int id) {
User user = userService.findById(id);
model.addAttribute("user", user);
return "/updateUser";
}
@RequestMapping("/update")
public String updateUser(User user) {
userService.updateUser(user);
return "redirect:/listUser";
}
@RequestMapping("/delete")
public String deleteUser(int id) {
userService.deleteUser(id);
return "redirect:/listUser";
}
}
3.写完了服务端代码,现在考虑前端的实现
3.1.先将前端的目录结构展示下:
3.2.将效果图和对应的代码进行粘贴
- listUser.jsp 数据展示界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<h2>用户列表</h2>
<a href="${pageContext.request.contextPath}/toAdd">添加</a>
<table border="1">
<tr>
<td>id</td>
<td>name</td>
<td>password</td>
<td>age</td>
<td>operate</td>
</tr>
<c:forEach items="${users}" var="s" varStatus="st">
<tr>
<td>${s.id}</td>
<td>${s.name}</td>
<td>${s.password}</td>
<td>${s.age}</td>
<td>
<a href="${pageContext.request.contextPath}/delete?id=${s.id}">删除</a>
<a href="${pageContext.request.contextPath}/toUpdate?id=${s.id}">修改</a>
</td>
</tr>
</c:forEach>
</table>
其中
1)<a href="${pageContext.request.contextPath}/toAdd">添加</a>,会调用controller层的@RequestMapping("/toAdd")注解下的方法,通过跳转到addUser.jsp界面。
2)<a href="${pageContext.request.contextPath}/delete?id=${s.id}">删除</a>,会调用controller层的@RequestMapping("/delete")注解下的方法,删除后直接指向listUser.jsp界面。
3)<a href="${pageContext.request.contextPath}/toUpdate?id=${s.id}">修改</a>,会调用controller层的@RequestMapping("/toUpdate")注解下的方法,通过跳转到updateUser.jsp界面。- addUser.jsp用户添加界面
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="/add" method="post">
name:<input type="text" name="name" />
age:<input type="text" name="age" />
password:<input type="text" name="password" />
<input type="submit" value="submit" />
</form>
</body>
</html>
在完成数据的录入后,当进行提交的时候,使用form的action="/add",调用controller层的@RequestMapping("/add")注解下的方法,实现数据的新增,然后直接指向listUser.jsp界面。
- updateUser.jsp用户修改界面
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action="/update" method="post">
id:<input type="text" name="id" value="${user.id}" readonly />
name:<input type="text" name="name" value="${user.name}" />
password:<input type="text" name="password" value="${user.password}" />
age:<input type="text" name="age" value="${user.age}" />
<input type="submit" value="submit" />
</form>
</body>
</html>
在完成数据的录入后,当进行提交的时候,使用form的action="/update",调用controller层的@RequestMapping("/update")注解下的方法,实现数据的修改,然后直接指向listUser.jsp界面。
根据上面的代码,大家可以直接来验证功能,通过查询MySQL数据库来看数据的变化情况,涉及到的表结构和数据。

扫描关注:全栈工程师成长记