系列文章目录
Spring学习笔记 之 Spring
https://blog.youkuaiyun.com/weixin_43985478/article/details/124411746?spm=1001.2014.3001.5501Spring学习笔记 之 Spring-MVC
https://blog.youkuaiyun.com/weixin_43985478/article/details/124923196?spm=1001.2014.3001.5501Spring学习笔记之MyBatis
https://blog.youkuaiyun.com/weixin_43985478/article/details/125328919?spm=1001.2014.3001.5501
Spring学习笔记之SSM整合https://blog.youkuaiyun.com/weixin_43985478/article/details/125467462
文章目录
目录
- 一、Spring Boot
- 二、Spring Boot 的优势
- 三、Spring Boot 的基本使⽤
- 四、Spring Boot 配置⽂件
- Properties 格式
- YAML/YML格式
- 五、Spring Boot 整合 JSP
- 实际应用
- 六、Spring Boot 整合Thymeleaf
- 什么是Thymeleaf
- 七、Thymeleaf常用标签
- 八、Thymeleaf 对象
- 九、Thymeleaf 内置对象
- 十、Spring Boot 整合持久层
- Spring Boot 整合JDBC Template
- Spring Boot整合MyBatis
- 十一、Spring Boot 整合 Spring Data JPA
- Spring Data JPA和SpringJdbcTemplate的关系
- 十二、Spring Boot 整合 Spring Security
- 权限管理
一、Spring Boot
- 通过 Spring Boot 可以快速构建⼀个基于 Spring 框架的 Java Application,简化配置,⾃动装配
- JavaConfifiguration ⽤ Java 类替代 XML 的配置⽅式
- Spring Boot 对常⽤的第三⽅库提供了配置⽅案,可以很好地和 Spring 进⾏整合,⼀键式搭建功能完备的 Java 企业级应⽤
二、Spring Boot 的优势
- 不需要任何 XML 配置⽂件
- 内嵌 Tomcat,可以直接部署
- 默认⽀持 JSON 数据,不需要进⾏转换
- ⽀持 RESTful
- 配置⽂件⾮常简单,⽀持 YAML 格式
Spring Boot 是⼀种只需要极少配置就可以快速搭建 Spring 应⽤,并且集成了常⽤的第三⽅类库,让开发者可以快速进⾏企业级应⽤开发
Spring Boot 2.x 要求必须基于 Spring 5.x,Spring 5.x 要求 Java 版本必须是 8 以上
三、Spring Boot 的基本使⽤
1、新建project,选择SpringInitializr,再选择以下基本依赖
2、在SpringbootApplication的同级文件夹下创建controller包,并新建Handler
- 启动类SpringbootApplication必须覆盖所有与业务相关的类
- 启动类所在的包必须是业务类所在包的同包或者⽗包,如果没有覆盖,业务类就不会⾃动装配到 IoC 容器中
- 使用@ComponentScan注解可以指定扫描的Controller包
- 默认是扫启动类所在的包下的全部
@RestController //@Controller + @Responsebody
@RequestMapping("/hello")
public class HelloHandler {
@GetMapping("/index")
public String index(){
return "Hello Spring Boot";
}
}
3、直接运行SpringbootApplication
四、Spring Boot 配置⽂件
进入spring-boot-starter-parent.pom种可以看到:默认读取的配置文件有几种 yml/ yaml/ properties
其中系统自动创建的是application.properties
Properties 格式
key - value形式
#端⼝
server.port=8181
#项⽬访问路径
server.servlet.context-path=/
#cookie失效时间
server.servlet.session.cookie.max-age=100
#session失效时间
server.servlet.session.timeout=100
#编码格式
server.tomcat.uri-encoding=UTF-8
YAML/YML格式
- YAML 是不同于 Properties 的格式,同样可以⽤来写配置⽂件,Spring Boot 默认⽀持YAML 格式
- YAML 的优点在于编写简单,结构清晰,利⽤缩紧的形式来表示层级关系
application.yml
server:
port: 8181
servlet:
context-path: /
session:
cookie:
max-age: 100
timeout: 100
tomcat:
uri-encoding: UTF-8
需要注意的是 YAML 格式书写规范⾮常严格,属性名和属性值之间必须⾄少⼀个空格
优先级(由高到低):
- 根路径下的 config 中的配置⽂件
- 根路径下的配置⽂件
- resources 路径下的 config 中的配置⽂件
- resources 路径下的配置⽂件
可以在Handler中读取YAML文件中的数据,比如读取端口号
@RestController
@RequestMapping("/hello")
public class HelloHandler {
/**
* spEL:Spring Expression Language
* @return
* 读取配置文件的server.port数据赋值给port
*/
@Value("${server.port}")
private String port;
@GetMapping("/index")
public String index(){
return "Hello Spring Boot " + port;
}
}
五、Spring Boot 整合 JSP
Spring Boot 与视图层的整合
- JSP -Java Server Page 是Java提供的一种动态网页技术,底层是Serverlet.可以在HTML中插入Java代码
JSP底层原理:
JSP 是⼀种中间层组件,开发者可以在这个组件中将 Java 代码与 HTML 代码进⾏整合,由 JSP 引擎将组件转为 Servlet,再把开发者定义在组件中的混合代码翻译成 Servlet 的响应语句,输出给客户端
- Themeleaf
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.7.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
</dependencies>
2、创建 Handler
@Controller
@RequestMapping("/hello")
public class HelloHandler {
@GetMapping("/index")
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView();
//配置文件配置前后缀变成 /index.jsp
modelAndView.setViewName("index");
modelAndView.addObject("mess","Hello Spring Boot");
return modelAndView;
}
}
3.index.jsp
<%@ page isELIgnored="false" %>
<html>
<body>
<h2>Hello World!</h2>
${mess}
</body>
</html>
4.application.yml
server:
port: 8181
spring:
mvc:
view:
prefix: /
suffix: .jsp
5.Application.class
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
实际应用
JSTL 和 lombok 引入
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
创建实体类
@Data
@AllArgsConstructor
public class User {
private Integer id;
private String name;
}
Repository
public interface UserRepository {
public Collection<User> findAll();
public User findById(Integer id);
public void save(User user);
public void deleteById(Integer id);
public void update(User user);
}
//实现类上添加注解
@Repository
public class UserRepositoryImpl implements UserRepository {
private static Map<Integer,User> map;
static {
map = new HashMap<>();
map.put(1,new User(1,"张三"));
map.put(2,new User(2,"李四"));
map.put(3,new User(3,"王五"));
}
@Override
public Collection<User> findAll() {
return map.values();
}
@Override
public User findById(Integer id) {
return map.get(id);
}
@Override
public void save(User user) {
map.put(user.getId(),user);
}
@Override
public void deleteById(Integer id) {
map.remove(id);
}
@Override
public void update(User user) {
map.put(user.getId(),user);
}
}
Service
public interface UserService {
public Collection<User> findAll();
public User findById(Integer id);
public void save(User user);
public void deleteById(Integer id);
public void update(User user);
}
//实现类加上注解
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public Collection<User> findAll() {
return userRepository.findAll();
}
@Override
public User findById(Integer id) {
return userRepository.findById(id);
}
@Override
public void save(User user) {
userRepository.save(user);
}
@Override
public void deleteById(Integer id) {
userRepository.deleteById(id);
}
@Override
public void update(User user) {
userRepository.update(user);
}
}
Handler 中创建业务⽅法
@Controller
@RequestMapping("/user")
public class UserHandler {
@Autowired
private UserService userService;
@GetMapping("/findAll")
public ModelAndView find(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("users",userService.findAll());
return modelAndView;
}
@GetMapping("findById/{id}")
public ModelAndView findById(@PathVariable("id") Integer id){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("update");
modelAndView.addObject("user",userService.findById(id));
return modelAndView;
}
@PostMapping("/save")
public String save(User user){
userService.save(user);
return "redirect:/user/findAll";
}
@GetMapping("/deleteById/{id}")
public String deleteById(@PathVariable("id") Integer id){
userService.deleteById(id);
return "redirect:/user/findAll";
}
@PostMapping("/update")
public String update(User user){
userService.update(user);
return "redirect:/user/findAll";
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<table>
<tr>
<th>编号</th>
<th>姓名</th>
<th>操作</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>
<a href="/user/deleteById/${user.id}">删除</a>
<a href="/user/findById/${user.id}">修改</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
update.jsp
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/user/update" method="post">
<input type="text" name="id" value="${user.id}" readonly><br>
<input type="text" name="name" value="${user.name}"><br>
<input type="submit">
</form>
</body>
</html>
save.jsp
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/user/save" method="post">
<input type="text" name="id"><br>
<input type="text" name="name"><br>
<input type="submit">
</form>
</body>
</html>
六、Spring Boot 整合Thymeleaf
什么是Thymeleaf
- Thymeleaf是一个支持原生THML文件的java模板,可以实现前后端分离 即 视图与业务数据分离
- 可以直接将服务端返回的数据生成HTML文件,同时也可以处理XML,JS,CSS等格式
- Thymeleaf最大的特点是既可以在浏览器直接打开,也可以结合服务端将业务数据填充到HTML后动态生成页面,JSP只能做到动态访问,HTML动静态都可以
1、创建Maven工程,不需要web工程,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>org.example</groupId>
<artifactId>thymeleaf</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.7.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
</project>
2、application.yml
spring:
thymeleaf:
prefix: classpath:/templates/ #模板路径
suffix: .html #模板后缀
servlet:
content-type: text/html #设置 Content-type
encoding: UTF-8
mode: HTML5 #校验 H5 格式
cache: false #关闭缓存,开发过程中可以立即看到页面修改结果
3、创建Handler
@Controller
@RequestMapping("/hello")
public class HelloHandler {
@GetMapping("/index")
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("name","张三");
return modelAndView;
}
}
4、启动类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
//参数中的类跟启动类类名一致(本人犯了低级错误)
SpringApplication.run(Application.class,args);
}
}
5、index.html
<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Index</h1>
<!--嵌入便签内部,引入thymeleaf成功会有自动代码补充-->
<p th:text="${name}">Hello World</p> <!--成功的话,name把Hello World 覆盖>
</body>
</html>
七、Thymeleaf常用标签
- th:text:用于文本显示,将业务数据填充到HTML标签中
- th:if:⽤于条件判断,对业务数据的值进⾏判断,如果条件成⽴,则显示内容,否则不显示
- th:unless:也⽤作条件判断,逻辑与 th:if 恰好相反,如果条件不成⽴则显示,否则不显示
@GetMapping("/unless")
public ModelAndView unlessTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("test");
modelAndView.addObject("score",90);
return modelAndView;
}
<p th:unless="${score>=90}">优秀</p>
<!-- 这里不成立,显示良好-->
<p th:unless="${score<90}">良好</p>
- th:switch 和 th:case :用作多条件 等值判断
<div th:switch="${id}">
<p th:case="1">张三</p>
<p th:case="2">李四</p>
<p th:case="3">王五</p>
</div>
- th:action:⽤来指定请求的 URL,相当于 form 表单中的 action
从后端访问html资源的例子如下:
@GetMapping("redirect/{url}")
public String redirect(@PathVariable("url") String url,Model model){
model.addAttribute("url",url);
return url;
}
<form th:action="${url}" method="post">
<input type="submit"/>
</form>
- th:each :⽤来遍历集合
相当于JSP中的:<c:forEach items="${list}" var="user">
<table>
<tr>
<th>编号<th>
<th>姓名<th>
</tr>
<tr th:each="user:${list}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
</tr>
</table>
- th:value:给标签赋值
<input type="text" th:value="${value}"/>
- th:src :引入静态资源
⽤来引⼊静态资源,相当于 HTML 原⽣标签 img、script 的 src 属性。
@GetMapping("/src")
public ModelAndView src(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("test");
modelAndView.addObject("src","/1.png");
return modelAndView;
}
<img th:src="${src}"/>
- th:href:用作超链接
@GetMapping("/href")
public ModelAndView href(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("test");
modelAndView.addObject("href","https://www.baidu.com");
return modelAndView;
}
<a th:href="${href}">百度</a>
八、Thymeleaf 对象
Thymeleaf ⽀持直接访问 Servlet Web 原⽣资源
- HttpServletRequest
- HttpServletResponse
- HttpSession
- ServletContext
Controller
@GetMapping("/servlet")
public String servlet(HttpServletRequest request){
request.setAttribute("value","request");
request.getSession().setAttribute("value","session");
request.getServletContext().setAttribute("value","servletContext");
return "test";
}
HTML
<p th:text="${#request.getAttribute('value')}"></p>
<!--¥{#session.value}也可以-->
<p th:text="${#session.getAttribute('value')}"></p>
<p th:text="${#servletContext.getAttribute('value')}"></p>
<p th:text="${#response}"></p>
九、Thymeleaf 内置对象
- dates:⽇期格式化
- calendars:⽇期操作
- numbers:数字格式化
- strings:字符串格式化
- bools:boolean
- arrays:数组内置对象
- lists:List 集合内置对象
- sets:Set 集合内置对象
- maps:Map 集合内置对象
Controller
@GetMapping("/utility")
public ModelAndView utility(){
ModelAndView modelAndView =new ModelAndView();
modelAndView.setViewName("test");
modelAndView.addObject("data",new Date());
Calendar calendar = Calendar.getInstance();
calendar.set(2022,9,19);
modelAndView.addObject("calendar",calendar);
modelAndView.addObject("number",0.05);
modelAndView.addObject("string","张三");
modelAndView.addObject("boolean",true);
modelAndView.addObject("array", Arrays.asList(1,2,3));
List<User> list = new ArrayList<>();
list.add(new User(1,"张三"));
list.add(new User(2,"lisi"));
list.add(new User(3,"王五"));
modelAndView.addObject("list",list);
Set<User> set = new HashSet<>();
set.add(new User(1,"张三"));
set.add(new User(2,"李四"));
set.add(new User(3,"王五"));
modelAndView.addObject("set",set);
Map<Integer,User> map = new HashMap<>();
map.put(1,new User(1,"张三"));
map.put(2,new User(2,"李四"));
modelAndView.addObject("map",map);
return modelAndView;
}
test.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
date格式化:<sapn th:text ="${#dates.format(date,'yyyy-MM-dd')}"></sapn><br/>
当前日期:<span th:text="${#dates.createToday()}"></span><br/>
当前时间:<span th:text="${#dates.createNow()}"></span><br/>
Calendar格式化:<span th:text="${#calendars.format(calendar,'yyyy-MM-dd')}"></span><br/>
number百分比格式化:<span th:text="${#numbers.formatPercent(number,2,2)}"></span><br/>
name是否为空:<span th:text="${#strings.isEmpty(string)}"></span><br/>
name长度:<span th:text="${#strings.length(string)}"></span><br/>
name拼接:<span th:text="${#strings.concat('Good',string)}"></span><br/>
boolean是否为true:<span th:text="${#bools.isTrue(boolean)}"></span><br/>
arrays的长度:<span th:text="${#arrays.length(array)}"></span><br/>
arrays是否包含张三:<span th:text="${#arrays.contains(array,3)}"></span><br/>
List是否为空:<span th:text="${#lists.isEmpty(list)}"></span><br/>
List的长度:<span th:text="${#lists.size(list)}"></span><br/>
Set是否为空:<span th:text="${#sets.isEmpty(set)}"></span><br/>
Set的长度:<span th:text="${#sets.size(set)}"></span><br/>
Map是否为空:<span th:text="${#maps.isEmpty(map)}"></span><br/>
Map长度:<span th:text="${#maps.size(map)}"></span><br/>
</body>
</html>
十、Spring Boot 整合持久层
Spring Boot 整合JDBC Template
Jdbc Template 是Spring 自带的JDBC组件,底层实现了JDBC的封装,用法与MyBatis类似,需要开发者自定义SQL语句,JdbcTemplate帮助我们完成数据库的连接,SQL执行,结果集封装
不足之处是灵活性不如MyBatis,因为MyBatis的SQL语句定义在XML中,更利于维护和扩展,Jdbc Template以硬编码的方式将SQL直接卸载Java代码中,不利于扩建维护
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>org.example</groupId>
<artifactId>springjdbc</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.7.3</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
</project>
2.application.yml
#配置数据源
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
username: root
password: 12345678
driver-class-name: com.mysql.cj.jdbc.Driver
3.实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
}
4.UserRepository 和 UserRepositoryImpl
package com.hqq.repository;
import com.hqq.entity.User;
import org.springframework.stereotype.Repository;
import java.util.List;
public interface UserRepository {
public List<User> findAll();
public User findById(Integer id);
public int save(User user);
public int update(User user);
public int deleteById(Integer id);
}
-----------------------------------------------------------
package com.hqq.repository.impl;
import com.hqq.entity.User;
import com.hqq.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class UserRepositoryImpl implements UserRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
//保证实体类要有无参构造器
@Override
public List<User> findAll() {
return jdbcTemplate.query(
"select * from user",
new BeanPropertyRowMapper<>(User.class)
);
}
@Override
public User findById(Integer id) {
return jdbcTemplate.queryForObject(
"select * from user where id = ?",
new Object[]{id},
new BeanPropertyRowMapper<>(User.class)
);
}
@Override
public int save(User user) {
return jdbcTemplate.update(
"insert into user (name) value (?)",
user.getName()
);
}
@Override
public int update(User user) {
return jdbcTemplate.update(
"update user set name = ? where id =?",
user.getName(),
user.getId()
);
}
@Override
public int deleteById(Integer id) {
return jdbcTemplate.update(
"delete from user where id = ?",
id
);
}
}
5.Handler
@RestController
@RequestMapping("/hello")
public class HelloHandler {
@Autowired
private UserRepository userRepository;
@GetMapping("/findAll")
public List<User> findAll(){
return userRepository.findAll();
}
@GetMapping("/findById/{id}")
public User findById(@PathVariable("id") Integer id){
return userRepository.findById(id);
}
@PostMapping("/save")
public int save(@RequestBody User user){
return userRepository.save(user);
}
@PutMapping("/update")
public int update(@RequestBody User user){
return userRepository.update(user);
}
@GetMapping("/delete/{id}")
public int deleteById(@PathVariable("id") Integer id){
return userRepository.deleteById(id);
}
}
Spring Boot整合MyBatis
1.pom.xml(与上相比多了一个依赖)
<!--添加以下依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
2.实体类User(上面已有,省略)
3.UserRepository(不用实现类)
4.UserHandler(已有)
5.resources/mapping下创建UserRepository.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hqq.repository.UserRepository">
<select id="findAll" resultType="User">
select * from user
</select>
<select id="findById" parameterType="java.lang.Integer" resultType="User">
select * from user where id = #{id}
</select>
<insert id="save" parameterType="User">
insert into user (name) value (#{name})
</insert>
<update id="update" parameterType="User">
update user set name =#{name} where id = #{id}
</update>
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
</mapper>
6.application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 12345678
mybatis:
mapper-locations: classpath:/mapping/*.xml #找到map文件
type-aliases-package: com.hqq.entity
7.启动类(已有)
十一、Spring Boot 整合 Spring Data JPA
JPA(Java Persistence API)JAVA持久层规范,定义了一系列ORM接口,它本身是不能直接使用的,接口必须实现才能使用,Hibernate框架就是实现了JPA规范的范畴
Spring Data JPA 是Spring框架提供的对JPA规范的抽象,通过约定的命名规范完成持久层接口的编写,在不需要实现接口的情况下,就可以完成对数据库的操作
SpringDataJPA不是一个具体实现,是抽象层,底层还是Hibernate实现
Spring Data JPA和SpringJdbcTemplate的关系
1.pom.xml
<!-- Spring Boot集成 Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2.User类
@Data
@Entity(name="user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column
private String name;
}
- @Entity 将实体类与数据表进⾏映射
- @Id 将实体类中的成员变量与数据表的主键进⾏映射,⼀般都是 id
- @GeneratedValue 表示⾃动⽣成主键,strategy 为主键选择⽣成策略
- @Column 将实体类中的成员变量与数据表的普通字段进⾏映射
3.UserRepository
//第二个参数为主键类型,继承不需要实现
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {}
4.Handler
//指定bean id
@RestController(value = "/jpa")
@RequestMapping("/user")
public class UserHandler {
@Autowired
private UserRepository userRepository;
@GetMapping("/findAll")
public List<User> findAll(){
return userRepository.findAll();
}
@GetMapping("/findById/{id}")
public User findById(@PathVariable("id") Integer id){
return userRepository.findById(id).get();
}
@PostMapping("/save")
public void save(@RequestBody User user){
userRepository.save(user);
}
@PutMapping("/update")
public void update(@RequestBody User user){
userRepository.save(user);
}
@DeleteMapping("/delete/{id}")
public void deleteById(@PathVariable Integer id){
userRepository.deleteById(id);
}
}
5.application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 12345678
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
6.自定义功能
(1)在UserRepository新增想实现的方法,方法名为findBy + 字段名
//第二个参数为主键类型,继承不需要实现
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {
public User findByName(String name);
}
(2)在Handler上调用
@GetMapping("/findByName/{name}")
public User findByName(@PathVariable("name") String name){
return userRepository.findByName(name);
}
十二、Spring Boot 整合 Spring Security
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>org.example</groupId>
<artifactId>spring_security</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.7.3</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-security</artifactId>
</dependency>
</dependencies>
</project>
2.Handler
@Controller
public class SecurityHandler {
@GetMapping("/index")
public String index(){
return "index";
}
}
3.index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>index</p>
<form method="post" action="/logout">
<input type="submit" value="退出">
</form>
</body>
</html>
4、application.yml
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
security:
user:
name: admin
password: 123456 #设置初始密码
5、Application
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
权限管理
定义两个资源
- index.html
- admin.html
定义两个⻆⾊
- ADMIN 访问 index.html 和 admin.html
- USER 访问 index.html
普通用户只有USER角色,管理员有ADMIN和USER两个角色
1、创建 SecurityConfig 类
package com.hqq.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 设置用户和角色的关系 和 用户密码
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder())
.withUser("user").password(new MyPasswordEncoder().encode("000"))
.roles("USER").and()
.withUser("admin").password(new MyPasswordEncoder().encode("123"))
.roles("ADMIN","USER");
}
/**
* 设置角色和资源的关系
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/index").access("hasRole('ADMIN') or hasRole('USER')")
.anyRequest().authenticated() //所有请求都要验证 不能直接进入admin.html 或 index.html
.and()
.formLogin()
.loginPage("/login") //指定登陆页面
.permitAll()
.and()
.logout()
.permitAll()
.and()
.csrf().disable();
}
}
2.⾃定义 MyPassowrdEncoder
package com.hqq.config;
import org.springframework.security.crypto.password.PasswordEncoder;
public class MyPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
//第二参数表示自己输入的密码
@Override
public boolean matches(CharSequence rawPassword, String s) {
return s.equals(rawPassword);
}
}
3、Handler
@Controller
public class SecurityHandler {
@GetMapping("/index")
public String index(){
return "index";
}
@GetMapping("/admin")
public String admin(){
return "admin";
}
@GetMapping("/login")
public String login(){
return "login";
}
}
4、login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://wwwthymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p th:if ="${param.error}">
用户名或密码错误
</p>
<form th:action="@{/login}" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<input type="submit" value="登陆">
</form>
</body>
</html>
5、index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>欢迎回来</p>
<form method="post" action="/logout">
<input type="submit" value="退出">
</form>
</body>
</html>
6、admin.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>后台管理系统</p>
<form method="post" action="/logout">
<input type="submit" value="退出">
</form>
</body>
</html>