Spring Boot 整合持久层技术
1 整合 JDBC
1.1搭建项目环境
1.1.1创建表
1.1.1.1 建表语句
CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`usersex` varchar(10) DEFAULT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1.1.2创建项目
1.1.3修改 POM 文件,添加相关依赖
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>springbootjdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootjdbc</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Thymeleaf启动器坐标-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--JDBC启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--数据库驱动坐标-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
添加MySQL坐标(选择对应的版本):https://mvnrepository.com/search?q=MySQL
1.2配置数据源
1.2.1通过自定义配置文件方式配置数据源信息
1.2.1.1 通过@PropertySource 注解读取配置文件
1.2.1.1.1添加 Druid 数据源依赖
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>springbootjdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootjdbc</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Thymeleaf启动器坐标-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--JDBC启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--数据库驱动坐标-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!--Druid数据源坐标-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1.2.1.1.2创建 Properties 文件
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&serverTimezone=UTC
jdbc.username=root
jdbc.password=root
1.2.1.1.3创建配置类
/**
* 数据源JDBC配置类
*/
@Configuration
@PropertySource("classpath:/jdbc.properties") //加载指定的proper配置文件
public class JDBCConfiguration {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
* 实例化Druid
*/
@Bean
public DataSource getDataSource(){
DruidDataSource source = new DruidDataSource();
source.setPassword(this.password);
source.setUsername(this.username);
source.setUrl(this.url);
source.setDriverClassName(this.driverClassName);
return source;
}
}
添加controller
@Controller
public class UsersController {
@Autowired
private DataSource dataSource;
@GetMapping("/showInfo")
public String showInfo(){
return "ok";
}
}
debug断点测试一下,发现已注入成功
1.2.1.2 通过@ConfigurationProperties 注解读取配置信息
1.2.1.2.1创建配置信息实体类
/**
* JDBC配置信息属性类
*/
@ConfigurationProperties(prefix = "jdbc")//是SpringBoot的注解不能读取其他配置文件,只能读取SpringBoot的application配置文件
public class jdbcProperties {
private String driverClassName;
private String url;
private String username;
private String password;
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
1.2.1.2.2修改配置类
/**
* 数据源JDBC配置类
*/
@Configuration
//@PropertySource("classpath:/jdbc.properties") //加载指定的proper配置文件
@EnableConfigurationProperties(JdbcProperties.class)//指定加载哪一个配置信息属性类
public class JdbcConfiguration {
// @Autowired 方法1
// private JdbcProperties jdbcProperties;
/*public JdbcConfiguration(JdbcProperties jdbcProperties){
this.jdbcProperties = jdbcProperties;
} 方法2*/
/**
* 实例化Druid
*/
@Bean
public DataSource getDataSource(JdbcProperties jdbcProperties){
DruidDataSource source = new DruidDataSource();
source.setPassword(jdbcProperties.getPassword());
source.setUsername(jdbcProperties.getUsername());
source.setUrl(jdbcProperties.getUrl());
source.setDriverClassName(jdbcProperties.getDriverClassName());
return source;
}
}
1.2.1.2.3@ConfigurationProperties 注解的优雅使用方式
/**
* 数据源JDBC配置类
*/
@Configuration
//@PropertySource("classpath:/jdbc.properties") //加载指定的proper配置文件
//@EnableConfigurationProperties(JdbcProperties.class)//指定加载哪一个配置信息属性类
public class JdbcConfiguration {
//@Autowired
//private JdbcProperties jdbcProperties;
/*public JdbcConfiguration(JdbcProperties jdbcProperties){
this.jdbcProperties = jdbcProperties;
}*/
/**
* 实例化Druid
*/
@Bean
@ConfigurationProperties(prefix = "jdbc")//是SpringBoot的注解不能读取其他配置文件,只能读取SpringBoot的application配置文件
public DataSource getDataSource(){
DruidDataSource source = new DruidDataSource();
return source;
}
}
1.2.2通过 Spring Boot 配置文件配置数据源
在Spring Boot1.x版本中的spring-boot-starter-jdbc 启 动 器 中 默 认 使 用 的 是org.apache.tomcat.jdbc.pool.DataSource
作为数据源
在 Spring Boot2.x 版 本 中 的 spring-boot-starter-jdbc 启 动 器 中 默 认 使 用 的 是com.zaxxer.hikariDataSource
作为数据源
1.2.2.1 使用 Spring Boot 默认的 HikariDataSource 数据源
配置信息
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
将Configuration注释掉
测试一下
1.2.2.2 使用第三方的 Druid 数据源
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
1.3添加用户
1.3.1创建 POJO
package com.bjsxt.springbootjdbc.pojo;
public class Users {
private Integer usersid;
private String username;
private String usersex;
public Integer getUsersid() {
return usersid;
}
public void setUsersid(Integer usersid) {
this.usersid = usersid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsersex() {
return usersex;
}
public void setUsersex(String usersex) {
this.usersex = usersex;
}
}
1.3.2创建页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<from th:action="@{/user/addUser}" method="post">
<input type="text" name="username"><br/>
<input type="text" name="usersex"><br/>
<input type="submit" value="OK">
</from>
</body>
</html>
1.3.3创建 Controller
1.3.3.1 PageController
/**
* 页面跳转Controller
*/
@Controller
public class PageController {
/**
* 页面跳转方法
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
1.3.3.2 UsersController
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
/**
*添加用户
* @return
*/
@PostMapping("/addUser")
public String showInfo(Users users){
System.out.println("hhgh");
try {
this.usersService.addUser(users);
}catch (Exception e){
e.printStackTrace();
return "error";
}
return "redirect:/ok";
}
}
1.3.4创建 Service
/**
* 用户管理业务层
*/
@Service
public class UsersServiceImpl implements UsersService {
@Autowired
private UsersDao usersDao;
/**
* 添加用户
* @param users
*/
@Override
@Transactional
public void addUser(Users users) {
this.usersDao.insertUsers(users);
}
}
1.3.5创建 Dao
/**
* 用户管理持久层
*/
@Repository
public class UsersDaoImpl implements UsersDao {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 添加用户
* @param users
*/
@Override
public void insertUsers(Users users) {
String sql = "insert into users(username,usersex) values(?,?)";
this.jdbcTemplate.update(sql,users.getUsername(),users.getUsersex());
}
}
1.3.6解决 favicon.ico 解析问题
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
1.4查询用户
1.4.1修改 Controller
/**
* 查询全部用户
*/
@GetMapping("/findUserAll")
public String findUserAll(Model model){
List<Users> list = null;
try{
list = this.usersService.findUsersAll();
model.addAttribute("list",list);
}catch(Exception e){
e.printStackTrace();
return "error";
}
return "showUsers";
}
1.4.2修改业务层
/**
* 查询全部用户
* @return
*/
@Override
public List<Users> findUsersAll() {
return this.usersDao.selectUsersAll();
}
1.4.3修改持久层
/**
* 查询全部用户
* @return
*/
@Override
public List<Users> selectUsersAll() {
String sql = "select * from users";
return this.jdbcTemplate.query(sql, new RowMapper<Users>() {
/**
* 结果集的映射
* @param resultSet
* @param i
* @return
* @throws SQLException
*/
@Override
public Users mapRow(ResultSet resultSet, int i) throws SQLException {
Users users = new Users();
users.setUserid(resultSet.getInt("userid"));
users.setUsername(resultSet.getString("username"));
users.setUsersex(resultSet.getString("usersex"));
return users;
}
});
}
1.4.4创建页面显示查询结果
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<title>北京尚学堂首页</title>
</head>
<body>
<table border="1" align="center">
<tr>
<th>用户ID</th>
<th>用户姓名</th>
<th>用户性别</th>
<th>操作</th>
</tr>
<tr th:each="u : ${list}">
<td th:text="${u.userid}"></td>
<td th:text="${u.username}"></td>
<td th:text="${u.usersex}"></td>
<td>
<a th:href="@{/user/preUpdateUser(id=${u.userid})}">修改</a>
<a th:href="@{/user/deleteUser(id=${u.userid})}">删除</a>
</td>
</tr>
</table>
</body>
</html>
1.5更新用户
1.5.1预更新查询
1.5.1.1 修改 Controller
/**
* 预更新用户的查询
*/
@GetMapping("/preUpdateUser")
public String preUpdateUser(Integer id,Model model){
try{
Users user = this.usersService.findUserById(id);
model.addAttribute("user",user);
}catch(Exception e){
e.printStackTrace();
return "error";
}
return "updateUser";
}
1.5.1.2 修改业务层
/**
* 预更新查询
* @param id
* @return
*/
@Override
public Users findUserById(Integer id) {
return this.usersDao.selectUserById(id);
}
1.5.1.3 修改持久层
/**
* 预更新用户查询
* @param id
* @return
*/
@Override
public Users selectUserById(Integer id) {
Users user = new Users();
String sql = "select * from users where userid = ?";
//参数绑定
Object[] arr = new Object[]{id};
this.jdbcTemplate.query(sql,arr, new RowCallbackHandler() {
@Override
public void processRow(ResultSet resultSet) throws SQLException {
user.setUsername(resultSet.getString("username"));
user.setUsersex(resultSet.getString("usersex"));
user.setUserid(resultSet.getInt("userid"));
}
});
return user;
}
1.5.1.4 创建用户更新页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<title>北京尚学堂首页</title>
</head>
<body>
<form th:action="@{/user/updateUser}" method="post">
<input type="hidden" name="userid" th:value="${user.userid}"/>
<input type="text" name="username" th:value="${user.username}"><br/>
<input type="text" name="usersex" th:value="${user.usersex}"><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
1.5.2更新用户操作
1.5.2.1 修改 Controller
/**
* 更新用户
*/
@PostMapping("/updateUser")
public String updateUser(Users users){
try{
this.usersService.modifyUser(users);
}catch(Exception e){
e.printStackTrace();
return "error";
}
return "redirect:/ok";
}
1.5.2.2 修改业务层
/**
* 更新用户
* @param users
*/
@Override
@Transactional
public void modifyUser(Users users) {
this.usersDao.updateUsers(users);
}
1.5.2.3 修改持久层
/**
* 更新用户
* @param users
*/
@Override
public void updateUsers(Users users) {
String sql = "update users set username = ?,usersex=? where userid = ?";
this.jdbcTemplate.update(sql,users.getUsername(),users.getUsersex(),users.getUserid());
}
1.6删除用户
1.6.1修改 Controller
/**
* 删除用户
*/
@GetMapping("/deleteUser")
public String deleteUser(Integer id){
try{
this.usersService.dropUser(id);
}catch(Exception e){
e.printStackTrace();
return "error";
}
return "redirect:/ok";
}
1.6.2修改业务层
/**
* 删除用户
* @param id
*/
@Override
@Transactional
public void dropUser(Integer id) {
this.usersDao.deleteUserById(id);
}
1.6.3修改持久层
/**
* 删除用户
* @param id
*/
@Override
public void deleteUserById(Integer id) {
String sql = "delete from users where userid= ?";
this.jdbcTemplate.update(sql,id);
}
2 整合 MyBatis
2.1搭建项目环境
2.1.1创建项目
2.1.2修改POM文件,添加相关依赖
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>springbootmybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootmybatis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Mybatis启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--数据库驱动坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!--Druid数据源依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.1.3配置数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&serverTimezone=UTC
username: root
password: user
type: com.alibaba.druid.pool.DruidDataSource
2.2配置 Maven 的 generator 插件
2.2.1添加 generator 插件坐标
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>springbootmybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootmybatis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Mybatis启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--数据库驱动坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!--Druid数据源依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--配置Generator插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
</dependencies>
<!--指定配置文件的路径-->
<configuration>
<configurationFile>
${project.basedir}/src/main/resources/generatorConfig.xml
</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.2.2添加 generator 配置文件
直接引入generatorConfig.xml文件,但是这里会报错,这是因为第一次引入IDEA无法找到这个文件,我们手动添加一下就可以了。
先复制报错的URL
2.2.3添加 generator 配置文件的 DTD 文件
2.2.4运行 generator 插件生成代码
修改配置信息
2.3配置资源拷贝插件
2.3.1添加资源拷贝插件坐标
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>springbootmybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootmybatis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Mybatis启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--数据库驱动坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!--Druid数据源依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--配置Generator插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
</dependencies>
<!--指定配置文件的路径-->
<configuration>
<configurationFile>
${project.basedir}/src/main/resources/generatorConfig.xml
</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
<!--配置资源拷贝插件-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
</project>
2.3.2修改启动类添加@MapperScan 注解
@SpringBootApplication
@MapperScan("com.bjsxt.springbootmybatis.mapper")//指定扫描接口与映射配置文件的包名
public class SpringbootmybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootmybatisApplication.class, args);
}
}
2.4 MyBatis 的其他配置项
mybatis:
#扫描 classpath 中 mapper 目录下的映射配置文件,针对于映射配置文件放 到了 resources 目录下
mapper-locations: classpath:/mapper/*.xml
#定义包别名,使用 pojo 时可以直接使用 pojo 的类型名称不用加包名
type-aliases-package: com.bjsxt.springbootmybatis.pojo
2.5添加用户功能
2.5.1创建页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<title>北京尚学堂首页</title>
</head>
<body>
<form th:action="@{/user/addUser}" method="post">
<input type="text" name="username"><br/>
<input type="text" name="usersex"><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
2.5.2创建 Controller
2.5.2.1 PageController
/**
* 页面跳转Controller
*/
@Controller
public class PageController {
/**
* 页面跳转方法
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
2.5.2.2 UsersController
/**
* 用户管理Controller
*/
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
/**
* 添加用户
*/
@PostMapping("/addUser")
public String addUser(Users users){
try {
this.usersService.addUsers(users);
}catch (Exception e){
e.printStackTrace();
return "error";
}
return "redirect:/ok";
}
}
2.5.3创建 Service
/**
* 用户管理业务层
*/
@Service
public class UsersServiceImpl implements UsersService {
@Autowired
private UsersMapper usersMapper;
@Override
@Transactional
public void addUsers(Users users) {
this.usersMapper.insert(users);
}
}
2.6查询用户功能
2.6.1修改 UsersController
/**
* 查询全部用户
*/
@GetMapping("/findUserAll")
public String findUserAll(Model model){
try{
List<Users> list = this.usersService.findUserAll();
model.addAttribute("list",list);
}catch(Exception e){
e.printStackTrace();
return "error";
}
return "showUsers";
}
2.6.2修改业务层
/**
* 查询全部用户
*/
@Override
public List<Users> findUserAll(){
UsersExample example = new UsersExample();
return this.usersMapper.selectByExample(example);
}
2.6.3创建页面显示查询结果
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<title>北京尚学堂首页</title>
</head>
<body>
<table border="1" align="center">
<tr>
<th>用户ID</th>
<th>用户姓名</th>
<th>用户性别</th>
<th>操作</th>
</tr>
<tr th:each="u : ${list}">
<td th:text="${u.userid}"></td>
<td th:text="${u.username}"></td>
<td th:text="${u.usersex}"></td>
<td>
<a th:href="@{/user/preUpdateUser(id=${u.userid})}">修改</a>
<a th:href="@{/user/deleteUser(id=${u.userid})}">删除</a>
</td>
</tr>
</table>
</body>
</html>
2.7更新用户功能
2.7.1预更新用户查询
2.7.1.1 修改 UsersController
/**
* 预更新用户查询
*/
@GetMapping("/preUpdateUser")
public String preUpdateUser(Integer id,Model model){
try{
Users user = this.usersService.preUpdateUsers(id);
model.addAttribute("user",user);
}catch(Exception e){
e.printStackTrace();
return "error";
}
return "updateUser";
}
2.7.1.2 修改业务层
/**
* 预更新查询
* @param id
* @return
*/
@Override
public Users preUpdateUsers(Integer id) {
return this.usersMapper.selectByPrimaryKey(id);
}
2.7.1.3 创建更新用户页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<title>北京尚学堂首页</title>
</head>
<body>
<form th:action="@{/user/updateUser}" method="post">
<input type="hidden" name="userid" th:value="${user.userid}"/>
<input type="text" name="username" th:value="${user.username}"><br/>
<input type="text" name="usersex" th:value="${user.usersex}"><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
2.7.2更新用户操作
2.7.2.1 修改 UsersController
/**
* 更新用户
*/
@PostMapping("/updateUser")
public String updateUser(Users users){
try{
this.usersService.modifyUsers(users);
}catch(Exception e){
e.printStackTrace();
return "error";
}
return "redirect:/ok";
}
2.7.2.2 修改业务层
/**
* 更新用户
* @param users
*/
@Override
@Transactional
public void modifyUsers(Users users) {
this.usersMapper.updateByPrimaryKey(users);
}
2.8删除用户功能
2.8.1修改 UsersController
/**
* 删除用户
*/
@GetMapping("/deleteUser")
public String deleteUser(Integer id){
try{
this.usersService.dropUsersById(id);
}catch(Exception e){
e.printStackTrace();
return "error";
}
return "redirect:/ok";
}
2.8.2修改业务层
/**
* 删除用户
* @param id
*/
@Override
@Transactional
public void dropUsersById(Integer id) {
this.usersMapper.deleteByPrimaryKey(id);
}
十、 SpringBoot 中异常处理与单元测试
1 异常处理 SpringBoot 中对于异常处理提供了五种处理方式
1.1自定义错误页面
SpringBoot 默认的处理异常的机制:SpringBoot默认的已经提供了一套处理异常的机制。 一旦程序中出现了异常 SpringBoot 会向/error 的 url 发送请求。在 SpringBoot 中提供了一个 名为 BasicErrorController 来处理/error 请求,然后跳转到默认显示异常的页面来展示异常信 息。
如 果 我 们 需 要 将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面 , 需 要 再 src/main/resources/templates 目录下创建 error.html 页面。注意:页面名称必须叫 error
尝试在Controller中编写一个空指针异常,以下程序肯定会报错。
@Controller
public class UsersController {
@RequestMapping("showInfo")
public String showInfo(){
String str = null;
str.length();
return "ok";
}
}
运行项目,如果没有error,,会出现这样的页面,用户看不懂这样的提示,所以对用户的体验感是不好的。
SpringBoot 默认的处理异常的机制,要 将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面 , 需 要 再 src/main/resources/templates 目录下创建 error.html 页面。注意:页面名称必须叫 error
1.2通过@ExceptionHandler 注解处理异常
1.2.1修改 Controller
@Controller
public class UsersController {
@RequestMapping("showInfo")
public String showInfo(){
String str = null;
str.length();
return "ok";
}
@ExceptionHandler(value = {java.lang.NullPointerException.class})
public ModelAndView nullpointExcepitonHandler(ExceptionHandler e){
ModelAndView mv = new ModelAndView();
mv.addObject("err", e.toString());
mv.setViewName("error1");
return mv;
}
}
1.2.2创建页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>北京尚学堂首页</title>
</head>
<body>
出错啦。。。
<span th:text="${err}"></span>
</body>
</html>
1.3通过@ControllerAdvice 与@ExceptionHandler 注解处理异 常
1.3.1创建全局异常处理类
@Controller
public class UsersController {
@RequestMapping("/showInfo")
public String showInfo(){
String str = null;
str.length();
return "ok";
}
@RequestMapping("/showInfo2")
public String showInfo2(){
int a =10/0;
return "ok";
}
}
**
* 全局异常处理类
*/
@ControllerAdvice
public class GlobalException {
@ExceptionHandler(value = {java.lang.NullPointerException.class} )
public ModelAndView nullpointExcepitonHandler(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("err",e.toString());
mv.setViewName("error1");
return mv;
}
@ExceptionHandler(value = {java.lang.ArithmeticException.class} )
public ModelAndView arithmeticExceptionHandler(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("err",e.toString());
mv.setViewName("error2");
return mv;
}
}
1.4通过 SimpleMappingExceptionResolver 对象处理异常
1.4.1创建全局异常处理类
/**
* 全局异常
* SimpleMappingExceptionResolver
*/
@Configuration
public class GlobalException2 {
/**
* 此方法返回值必须是SimpleMappingExceptionResolver 对象
* @return
*/
@Bean
public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
/**
* 参数一:异常类型,并且是全名
* 参数二:视图名称
*/
properties.put("java.lang.NullPointerException", "error3");
properties.put("java.lang.ArithmeticException", "error4");
resolver.setExceptionMappings(properties);
return resolver;
}
}
1.5通过自定义 HandlerExceptionResolver 对象处理异常
1.5.1创建全局异常处理类
/**
* 自定义HandlerExceptionResolver对象处理异常
* 必须要实现HandlerExceptionResolver
*/
@Configuration
public class GlobalException3 implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
ModelAndView mv = new ModelAndView();
//判断不同异常类型,做不同视图的跳转
if(e instanceof NullPointerException){
mv.setViewName("error5");
}
if(e instanceof ArithmeticException){
mv.setViewName("error6");
}
mv.addObject("error",e.toString());
return mv;
}
}
2 Spring Boot 整合 Junit 单元测试
SpringBoot2.x 使用 Junit5 作为测试平台
2.1修改 POM 文件添加 Test 启动器
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>springbootexcepionandjunit</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootexcepionandjunit</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!--junit-vintage-engine 提供了Junit3与Junit4的运行平台-->
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2编写测试代码
@Repository
public class UsersDaoImpl {
public void insert(){
System.out.println("insert into values .....");
}
}
@Service
public class UsersServiceImpl {
@Autowired
private UsersDaoImpl usersDao;
public void addUser(){
this.usersDao.insert();
}
}
测试
//但项目中含有多个启动器,可以通过classes来指定
//@SpringBootTest(classes = SpringbootexcepionandjunitApplication.classs )
@SpringBootTest
class SpringbootexcepionandjunitApplicationTests {
@Autowired
private UsersServiceImpl usersService;
@Test
void contextLoads() {
this.usersService.addUser();
}
}
十一、 Spring Boot 服务端数据校验
1 Spring Boot 对实体对象的校验
1.1搭建项目环境
1.1.1创建项目
1.1.2创建实体
public class Users {
private Integer userid;
private String username;
private String usersex;
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsersex() {
return usersex;
}
public void setUsersex(String usersex) {
this.usersex = usersex;
}
@Override
public String toString() {
return "Users{" +
"userid=" + userid +
", username='" + username + '\'' +
", usersex='" + usersex + '\'' +
'}';
}
}
1.1.3创建 Controller
@Controller
@RequestMapping("/user")
public class UsersController {
/**
* 添加用户
*/
@RequestMapping("/addUser")
public String addUser(Users users){
System.out.println(users);
return "ok";
}
}
1.1.4创建页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<title>北京尚学堂首页</title>
</head>
<body>
<form th:action="@{/user/addUser}" method="post">
<input type="text" name="username"><br/>
<input type="text" name="usersex"><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
1.2对实体对象做数据校验
1.2.1Spring Boot 数据校验的技术特点
Spring Boot 中使用了 Hibernate-validator 校验框架。
1.2.2对实体对象数据校验步骤
1.2.2.1 修改实体类添加校验规则
/**
* @NotNull: 对基本数据类型的对象类型做非空校验
* @NotBlank: 对字符串类型做非空校验
* @NotEmpty: 对集合类型做非空校验
*/
public class Users {
@NotNull
private Integer userid;
@NotBlank
private String username;
@NotBlank
private String usersex;
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsersex() {
return usersex;
}
public void setUsersex(String usersex) {
this.usersex = usersex;
}
@Override
public String toString() {
return "Users{" +
"userid=" + userid +
", username='" + username + '\'' +
", usersex='" + usersex + '\'' +
'}';
}
}
1.2.2.2 在 Controller 中开启校验
@Controller
@RequestMapping("/user")
public class UsersController {
/**
* 添加用户
*/
@RequestMapping("/addUser")
public String addUser(@Validated Users users, BindingResult result) {
if (result.hasErrors()) {
List<ObjectError> list = result.getAllErrors();
for (ObjectError err : list) {
FieldError fieldError = (FieldError) err;
String fieldName = fieldError.getField();
String msg = fieldError.getDefaultMessage();
System.out.println(fieldName + "\t" + msg);
}
return "addUser";
}
System.out.println(users);
return "ok";
}
}
1.2.2.3 在页面中获取提示信息
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<title>北京尚学堂首页</title>
</head>
<body>
<form th:action="@{/user/addUser}" method="post">
<input type="text" name="username"><font color="red"><span th:errors="${users.username}"/></font><br/>
<input type="text" name="usersex"><font color="red"><span th:errors="${users.usersex}"/></font><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
1.2.3自定义错误提示信息
1.2.3.1 在注解中定义提示信息
/**
* @NotNull: 对基本数据类型的对象类型做非空校验
* @NotBlank: 对字符串类型做非空校验
* @NotEmpty: 对集合类型做非空校验
*/
public class Users {
@NotNull(message = "用户ID不能为空")
private Integer userid;
@NotBlank(message = "用户姓名不能为空")
private String username;
@NotBlank(message = "用户性别不能为空")
private String usersex;
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsersex() {
return usersex;
}
public void setUsersex(String usersex) {
this.usersex = usersex;
}
@Override
public String toString() {
return "Users{" +
"userid=" + userid +
", username='" + username + '\'' +
", usersex='" + usersex + '\'' +
'}';
}
}
1.2.3.2 在配置文件中定义提示信息
配置文件名必须是 ValidationMessages.properties
userid.notnull=用户ID不能为空-pro
username.notnull=用户姓名不能为空-pro
usersex.notnull=用户性别不能为空-pro
修改实体类
@NotNull(message = "{userid.notnull}")
private Integer userid;
@NotBlank(message = "{username.notnull}")
private String username;
@NotBlank(message = "{usersex.notnull")
这里会出现乱码,这里转一下码就可以了
打开JDK
修改ValidationMessages.properties
userid.notnull=\u7528\u6237ID\u4e0d\u80fd\u4e3a\u7a7a-pro
username.notnull=\u7528\u6237\u59d3\u540d\u4e0d\u80fd\u4e3a\u7a7a-pro
usersex.notnull=\u7528\u6237\u6027\u522b\u4e0d\u80fd\u4e3a\u7a7a-pro
1.2.4解决页面跳转异常
在跳转页面的方法中注入一个对象,要求参数对象的变量名必须是对象类型名称首字母 小写格式。
@Controller
public class PageController {
/**
* 跳转页面方法
* 解决异常的方式:可以在跳转页面的方法中注入一个Users对象
* 由于SpringMVC会将该对象放到Model中传递,key的名称会使用该对象的
* 驼峰命名规则来作为key
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page, Users users){
return page;
}
}
1.2.5 修改参数key的名称
@Controller
public class PageController {
/**
* 跳转页面方法
* 解决异常的方式:可以在跳转页面的方法中注入一个Users对象
* 由于SpringMVC会将该对象放到Model中传递,key的名称会使用该对象的
* 驼峰命名规则来作为key
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page, @ModelAttribute("aa") Users suibian){
return page;
}
}
@Controller
@RequestMapping("/user")
public class UsersController {
/**
* 添加用户
*/
@RequestMapping("/addUser")
public String addUser(@ModelAttribute("aa") @Validated Users users, BindingResult result) {
if (result.hasErrors()) {
List<ObjectError> list = result.getAllErrors();
for (ObjectError err : list) {
FieldError fieldError = (FieldError) err;
String fieldName = fieldError.getField();
String msg = fieldError.getDefaultMessage();
System.out.println(fieldName + "\t" + msg);
}
return "addUser";
}
System.out.println(users);
return "ok";
}
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}"/>
<head>
<title>北京尚学堂首页</title>
</head>
<body>
<form th:action="@{/user/addUser}" method="post">
<input type="text" name="username"><font color="red"><span th:errors="${aa.username}"/></font><br/>
<input type="text" name="usersex"><font color="red"><span th:errors="${aa.usersex}"/></font><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
1.2.6其他校验规则
- @NotNull: 判断基本数据类型的对象类型是否为 null
- @NotBlank: 判断字符串是否为 null 或者是空串(去掉首尾空格)。
- @NotEmpty: 判断集合是否为空。
- @Length: 判断字符的长度(最大或者最小)
- @Min: 判断数值最小值
- @Max: 判断数值最大值
- @Email: 判断邮箱是否合法
@NotNull(message = "{userid.notnull}")
private Integer userid;
@NotBlank(message = "{username.notnull}")
@Length(min = 3,max = 8,message = "最小3,最大8")
private String username;
@NotBlank(message = "{usersex.notnull")
2 Spring Boot 对 Controller 中其他参数的校验
2.1编写页面
2.2对参数指定校验规则
@PostMapping("/findUser")
public String findUser(@NotBlank(message = "用户名不能为空") String username){
System.out.println(username);
return "ok";
}
2.3在 Controller 中开启校验
@Controller
@RequestMapping("/user")
@Validated
public class UsersController {
2.4通过全局异常处理来跳转页面
@Configuration
public class GlobalException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
ModelAndView mv = new ModelAndView();
//判断不同异常类型,做不同视图的跳转
if(e instanceof NullPointerException){
mv.setViewName("error5");
}
if(e instanceof ArithmeticException){
mv.setViewName("error6");
}
if(e instanceof ConstraintViolationException){
mv.setViewName("findUser");
}
mv.addObject("error",e.getMessage().split(":")[1]);
return mv;
}
}
十二、 Spring Boot 热部署
1 通过 DevTools 工具实现热部署
1.1修改 POM 文件,添加 DevTools 依赖
<!--添加 DevTools 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
1.2配置 Idea
1.2.1设置自动编译
1.2.2设置 Idea 的 Registry
通过快捷键打开该设置项:Ctrl+Shift+Alt+/
勾选 complier.automake.allow.when.app.running
十三、 Spring Boot 度量指标监控与健康检查
1 使用 Actuator 检查与监控
1.1创建项目
1.2需改 POM 文件,添加依赖
<!--Actuator 坐标依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
启动项目
1.3修改配置文件
#配置访问端点的根路径
management.endpoints.web.base-path=/actuator
#配置开启其他端点的 URI
#开启所有的端点访问:*
#指定开启端点访问:如:beans,env
management.endpoints.web.exposure.include=*
#排除指定端点
#management.endpoints.web.exposure.exclude=env,beans
1.4各项监控指标接口 URL 介绍
2 使用可视化监控应用 Spring Boot Admin
2.1使用步骤
Spring Boot Admin 的使用是需要建立服务端与客户端。
服务端:独立的项目,会将搜集到的数据在自己的图形界面中展示。
客户端:需要监控的项目。
对应关系:一个服务端可以监控多个客户端。
2.1.1搭建服务端
2.1.1.1 创建项目![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6c5e21b76e9719dc2c402135ed479a90.png)
2.1.1.2 修改 POM 文件
注意:目前在 Spring Boot Admin Starter Server2.1.6 版本中不支持 Spring Boot2.2.x 版本, 只支持到 2.1.X
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.bjsxt</groupId>
<artifactId>springbootactuatorserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springbootactuatorserver</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-server -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.1.6</version>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.1.1.3 修改配置文件
server.port=9090
2.1.1.4 修改启动类
@SpringBootApplication
@EnableAdminServer//开启Spring Boot Admin服务端
public class SpringbootactuaorserverApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootactuaorserverApplication.class, args);
}
}
2.2搭建客户端
2.2.1修改 POM 文件
<!-- https://mvnrepository.com/artifact/de.codecentric/spring-boot-admin-starter-client -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.1.6</version>
</dependency>
2.2.2修改配置文件
#配置访问端点的跟路径
management.endpoints.web.base-path=/actuator
#配置开启其他端点的 URI
#开启所有的端点访问:*
#指定开启端点访问:如:beans,env
management.endpoints.web.exposure.include=*
#指定服务端的访问地址
spring.boot.admin.client.url=http://localhost:9090
2.2.3效果图
十四、 Spring Boot 的日志管理
Spring Boot 默认使用 Logback 组件作为日志管理。Logback 是由 log4j 创始人设计的一 个开源日志组件。
在 Spring Boot 项目中我们不需要额外的添加 Logback 的依赖,因为在 spring-boot-starter 或者 spring-boot-starter-web 中已经包含了 Logback 的依赖。
1 Logback 读取配置文件的步骤
(1)在 classpath 下查找文件 logback-test.xml
(2)如果文件不存在,则查找 logback.xml
(3)如果两个文件都不存在,LogBack 用 BasicConfiguration 自动对自己进行最小化配 置,这样既实现了上面我们不需要添加任何配置就可以输出到控制台日志信息。
2 添加 Logback 配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="${catalina.base}/logs/" />
<!-- 控制台输出 -->
<appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="info">
<appender-ref ref="Stdout" />
<appender-ref ref="RollingFile" />
</root>
<!--日志异步到数据库 -->
<!-- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
日志异步到数据库
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
连接池
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
<user>root</user>
<password>root</password>
</dataSource>
</connectionSource>
</appender> -->
</configuration>
3 配置 Logback
4 在代码中使用 Logback
@RestController
@RequestMapping("/logback")
public class HelloController {
private final static Logger logger = LoggerFactory.getLogger(HelloController.class);
@RequestMapping("/showInfo")
public String showInfo(){
logger.info("记录日志");
return "Hello LogBack";
}
}
5 在配置文件中屏蔽指定包的日志记录
#屏蔽指定包中的日志输出
logging.level.org=off
十五、 Spring Boot 项目打包与多环境配置
1 Spring Boot 项目打包
1.1Spring Boot 的打包插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
1.2项目打包方式
1.3运行命令
注意:需要正确的配置环境变量。
运行命令:java -jar 项目的名称
2 Spring Boot 的多环境配置
语法结构:application-{profile}.properties/yml
profile
:代表某个配置环境的标识
示例:
application-dev.properties/yml
开发环境
application-test.properties/yml
测试环境
application-prod.properties/yml
生产环境
2.1Windows 环境下启动方式
java -jar xxx.jar --spring.profiles.active={profile}
2.2在 Linux 环境下启动方式
2.2.1安装上传下载工具
安装命令:yum install lrzsz -y
上传命令:rz
下载命令:sz 下载文件名
2.2.2启动脚本的使用
修改脚本文件中的参数值
将启动脚本文件上传到 Linux 中
分配执行权限:chmod 777
通过脚本启动命令:server.sh start
通过脚本关闭命令:server.sh stop
智能家居