五.spring boot
通过springboot可以快速的搭建一个基于ssm框架的Java application,简单配置,自动装配。
JavaConfiguration用java类来替代xml
Spring boot对常用的第三方的类库提供了方案,可以很好的和spring进行整合,一键搭建功能完备的java企业级的应用
开箱即用是Springboot的特点
优势:
不需要任何的xml配置文件
内嵌了Tomcat,看可以直接的部署
默认转换json数据,不需要转换
支持RESTful
配置文件简单、支持YAM格式
Spring boot是一种只需要极少配置的,就可以快速搭建spring应用,并且集成了常用的第三方的类库,让开发者可以快速的进行企业级的应用开发
Spring Boot2.x要求碧血基于Spring5.x,spring5.x要求java版本必须是8以上
开发
1.创建handller
package com.southwind.springboot.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class HelloHandler {
@GetMapping("/index")
public String index(){
return "hello spring boot";
}
}
2.创建启动类
package com.southwind.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
启动类必须覆盖所有与业务相关的类:启动类所在的包必须是业务类所在的包或者父包,如果没有覆盖业务类就不会自动装配到ioc容器里
springboot的配置文件
1.改端口:
server.port=8181
2.自定义banner.txt
hello spring boot
#设置端口
server.port=8181
#项目访问路径
server.servlet.context-path=/springboot
#cookie失效时间
server.servlet.session.cookie.max-age=100
#session的失效时间
server.servlet.session.timeout=100
#编码格式
server.tomcat.uri-encoding=UTF-8
YAML:
YAML是不同与Properties的另一种形式,他同样可以用来写配置文件,springboot默认支持YAML格式。
优点:
编写简单,结构清晰,利用缩进的形式来表现层级关系
相比Properties更加简单编写,更加方便。
使用YAML格式:
server:
port: 8181
servlet:
context-path: /springboot
session:
cookie:
max-age: 100
timeout: 100
tomcat:
uri-encoding: utf-8
YAML格式的书写规范非常严格,属性名和属性之间必须要有一个空格
如果properties和YAML的优先级谁会更高呢?
properties会更高
配置文件除了可以放在resources路径之外还可以有三个位置
工程根路径
resource下
resource下的包
项目的src同级下的包内
优先级
1.项目的src同级下的包内
2.工程根路径
3.resource下的包
4.resource下
可以直接在Handller中读取YAML中的数据,比如我们在业务方法中向客户端返回当前服务的端口的信息
package com.southwind.springboot.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class HelloHandler {
@Value("${server.port}")
private String port;
@GetMapping("/index")
public String index(){
return "当前服务的端口是"+this.port;
}
}
@Value注解同样适用于properties文件
Springboot整合JSP
spring boot与视图层次的整合:
JSP 效率低
Thymeleaf
java Server page 是Java提供的一种动态的网页技术,低层是Servlet,可以直接在HTML中插入Java代码
JSP的底层的原理:
JSP是一种中间层的组件,开发者可以在这个组件中将java代码,与html代码进行整合,有jsp的引擎组件转为Servlet,再把开发者定义在组件的混合代码翻译成Servlet的相应语句,输出给客户端。
1.创建工程:基于maven的项目
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!-- Spring boot父依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>
<dependencies>
<!-- Spring boot-->
<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>
<version>9.0.26</version>
</dependency>
</dependencies>
2.创建Handler
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/hello")
public class HelloHandler {
@GetMapping("/index")
public ModelAndView index(){
ModelAndView modelAndView =new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("mess","hello spring boot");
return modelAndView;
}
}
3.JSP
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-10
Time: 13:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>index</h1>
${mess}
</body>
</html>
4.application.yml
server:
port: 8181
spring:
mvc:
view:
prefix: /
suffix: .jsp
实际应用时
<!-- JSTL-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
lombok简化实体类代码的编写工作
常用的方法:getter、setter、toString自动生成lombox的使用要安装插件
实现增删改查(JSP)
1.实体类:User
package com.southwind.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
private Integer id;
private String name;
}
2.控制器:UserHandler
package com.southwind.controller;
import com.southwind.Service.UserService;
import com.southwind.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
@Controller
@RequestMapping("/user")
public class UserMapper {
@Autowired
private UserService userService;
@GetMapping("/findall")
public ModelAndView findall(){
ModelAndView modelAndView= new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("list",userService.finAll());
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("/delete/{id}")
public String deleteById(@PathVariable("id") Integer id){
userService.delete(id);
return "redirect:/findall";
}
@GetMapping("/update")
public String update( User user){
userService.uodate(user);
return "redirect:/user/findall";
}
}
3.业务Service
接口:
package com.southwind.Service;
import com.southwind.entity.User;
import java.util.Collection;
public interface UserService {
public Collection<User> finAll();
public User findById(Integer id);
public void save(User user);
public void delete(Integer id);
public void uodate(User user);
}
实现类:
package com.southwind.Service.impl;
import com.southwind.Reposity.UserReposity;
import com.southwind.Service.UserService;
import com.southwind.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collection;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserReposity userReposity;
@Override
public Collection<User> finAll() {
return userReposity.finAll();
}
@Override
public User findById(Integer id) {
return userReposity.findById(id);
}
@Override
public void save(User user) {
userReposity.save(user);
}
@Override
public void delete(Integer id) {
userReposity.delete(id);
}
@Override
public void uodate(User user) {
userReposity.uodate(user);
}
}
4.业务:Repositort
接口;
package com.southwind.Reposity;
import com.southwind.entity.User;
import java.util.Collection;
public interface UserReposity {
public Collection<User> finAll();
public User findById(Integer id);
public void save(User user);
public void delete(Integer id);
public void uodate(User user);
}
实现类:
package com.southwind.Reposity.impl;
import com.southwind.Reposity.UserReposity;
import com.southwind.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Repository
public class UserReposityImpl implements UserReposity {
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> finAll() {
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 delete(Integer id) {
map.remove(id);
}
@Override
public void uodate(User user) {
map.put(user.getId(),user);
}
}
5.视图层JSP
index.jsp
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-10
Time: 13:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>index</h1>
${mess}
<table>
<tr>
<th>编号</th>
<th>姓名</th>
<th>操作</th>
</tr>
<c:forEach items="${list}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>
<a href="/user/delete/${user.id}">删除</a>
<a href="/user/findbyid/${user.id}">修改</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
save.jsp:
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-10
Time: 18:24
To change this template use File | Settings | File Templates.
--%>
<%@ 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" value="提交">
</form>
</body>
</html>
update.jsp
<%--
Created by IntelliJ IDEA.
User: 郝泾钊
Date: 2022-04-10
Time: 18:27
To change this template use File | Settings | File Templates.
--%>
<%@ 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}"/><br>
<input type="text" name="name" value="${user.name}"/><br>
<input type="submit" value="提交">
</form>
</body>
</html>
springboot 整合Thymeleaf
Thymeleaf是目前流行的视图层的技术,Spring boot 官方推荐的使用Thymeleaf
什么是Thymeleaf?
Thymeleaf是一个支持原生的THML文件的java末班,可以实现前后端的分离的交互方式,即视图与业务的数据分开响应,他可以直接返回服务端返回的数据生成HTML文件,同时也可以处理XML、javascript、css等格式。
Thymeleaf的最大特点是即可以直接在浏览器打开(静态方式),也可以结合服务器将业务数据填充到HTML之后启动动态的页面(动态方式),Springboot支持Thymeleaf,使用起来非常方便。
1.创建maven工程
<parent>
<artifactId>spring-boot-dependencies</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.2.4.RELEASE</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>
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
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/hello")
public class HellloHandler {
@GetMapping("/index")
public ModelAndView index(){
ModelAndView modelAndView =new ModelAndView();
modelAndView.setViewName("index");
modelAndView.addObject("mess","张三");
return modelAndView;
}
}
4.启动类
package com.southwind;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
5.视图:
HTML
<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymaleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>index</h1>
<p th:text="${mess}">hello word</p>
</body>
</html>
需要引入标签
<html xmlns:th="http://www.thymaleaf.org">
<p th:text="${mess}">hello word</p>
Thymeleaf是直接嵌入到模版标签的内部的,不同于JSTL模版
Thymeleaf常用标签
th:text
th:text用于文本的显示,将业务的值显示到HTML的页面中
th:if
th:if用于条件判断,对业务数据的判断,如果条件成立,则显示内容,否则不显示,具体的使用:
@GetMapping("/if") public ModelAndView ifTest(){ ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("score",90); return modelAndView; }
test.html
<!DOCTYPE html> <html lang="en"> <html xmlns:th="http://www.thymaleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p th:if=" 不能识别此Latex公式: {score>=90}">优秀</p> <p th:if=" {score<90}">良好</p> </body> </html> 不能识别此Latex公式: {score>=90}">优秀</p> <p th:if="
th:unless
th:unless也用作条件判断,逻辑于if恰好相反,如果条件成立不显示,条件不成立显示
@GetMapping("/unless") public ModelAndView unlessTest(){ ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("score",90); return modelAndView; }
html</p></li> </ul> ¨K76K
¨K129K
- th:switch th:case
th:switch th:case两结合起来使用,用于多条件的等值判断,逻辑于java的switch case一致,当switch中的业务数据等于摸个case时,就显示该case对应的内容。
@GetMapping("/switch") public ModelAndView switchTest(){ ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("mess",1); return modelAndView; }
<!--switch--> <div th:switch="${mess}"> <p th:case="1">优秀</p> <p th:case="2">良好</p> </div>
-
th:action
用来指定请求的URL,相当于form表单的action属性
1.写死
html</p></li> </ul> ¨K75K
2.后端传过来
<form th:action="${url}" method="get"> <input type="submit" value="提交"> </form>
@GetMapping("/redirect/{url}") public String redirect(@PathVariable("url") String url, Model model){ model.addAttribute("url" ,"/hello/action"); return url; }
@GetMapping("/action") @ResponseBody public String actionTest(){ return "action"; }
-
th;each
用来遍历集合
1.实体类
package com.southwind.entity; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class User { private String name; private Integer id; }
2.Handler
@GetMapping("/each") public ModelAndView each(){ List<User> users = Arrays.asList(new User("张三",1),new User("李四",2),new User("王五",3)); ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("list",users); return modelAndView; }
3.视图
html</p></li> </ul> ¨K77K
¨K130K
-
th:value
用来给标签赋值
@GetMapping("/value") public ModelAndView value(){ ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("list","sprngboot"); return modelAndView; }
html</p></li> </ul> ¨K78K
¨K131K
th:src
用来引入静态资源相当于HTML的原生的img。scrip的src标签
图片、css、js都必须放在resource下的static中
@GetMapping("/src") public ModelAndView src(){ ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("src","/1.jpg"); return modelAndView; }
<!--value--> <input type="text" th:value="${list}">
-
th:href
用来设置超链接的href
@GetMapping("/href") public ModelAndView href(){ ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("src","https://www.baidu.com"); return modelAndView; }
html</p></li> </ul> ¨K79K
¨K132K
th:selected标签
给html设置选中的元素,条件成立选中,条件不成立不选中
@GetMapping("/selected") public ModelAndView selected(){ List<User> users = Arrays.asList(new User("张三",1),new User("李四",2),new User("王五",3)); ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("list",users); modelAndView.addObject("name","李四"); return modelAndView; }
<!--selected--> <select> <option th:each="user:${list}" th:value="${user.id}" th:text="${user.name}" th:selected="${user.name==name}" ></option> </select>
结合th:each来使用,首次遍历list的集合来动态的创建元素,更具每次遍历出的user、name于业务数据中的name是否相等来决定是否要选择。
-
th:attr
给HTML的任意标签来赋值
@GetMapping("/attr") public ModelAndView attr(){ ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("attr","spring boot"); return modelAndView; }
html</p></li> </ul> ¨K80K
¨K133K
Thymeleaf的对象
Thymeleaf是直接支持访问Servlet web的原生资源,HttpServletRequest HttpServletResponse HttpSession ServletContext.
#request:获取HttpServletRequest对象 #response:获取HttpServletResponse 对象 #session:获取HttpSession 对象 #servletContext:获取ServletContext对象
1.Handler
@GetMapping("/servlet") public String servlet(HttpServletRequest request){ request.setAttribute("valye","request"); request.getSession().setAttribute("valye","request"); request.getServletContext().setAttribute("valye","request"); return "test"; }
<!--request--> <p th:text="${#request.getAttribute('value')}"></p> <p th:text="${#session.getAttribute('value')}"></p> <p th:text="${#servletContext.getAttribute('value')}"></p> <p th:text="${#reponse}"></p>
Thymeleaf支持直接访问session,相对于
${#servletContext.getAttribute('value')}也可以简化为${value}
Thymeleaf的内置对象
- dates;日期格式化
- calendars:日期操作
- numbers:数字格式化
- Strings:字符格式化
- bools:boolean
- arrays:数组内置对象
- lists:list集合内置对象
- sets:set集合内置对象
- maps;map集合内置对象
@GetMapping("/uniltity") public ModelAndView uniltity(){ ModelAndView modelAndView =new ModelAndView(); modelAndView.setViewName("test"); modelAndView.addObject("date",new Date()); Calendar calendar =Calendar.getInstance(); calendar.set(2020,1,1); modelAndView.addObject("calendar",calendar); modelAndView.addObject("number",0.06); modelAndView.addObject("string","Springboot"); modelAndView.addObject("boolean",true); modelAndView.addObject("array",Arrays.asList("张三","李四","王五")); List<User> users = Arrays.asList(new User("张三",1),new User("李四",2),new User("王五",3)); modelAndView.addObject("list",users); Set<User> set =new HashSet<>(); set.add(new User("张三",1)); set.add(new User("李四",2)); 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; }
date:格式化<span th:text="${#dates.format(date,'yyy-mm-dd')}"></span><br> 当前时间:<span th:text="${#dates.cteateToday()}"></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.isTmpty(string)}"></span><br> name的长度:<span th:text="${#strings.length(string)}"></span><br> name的拼接:<span th:text="${#strings.concat('Good',string)}"></span><br> boolen是否为true:<span th:text="${#bools.isTrue(boolean)}"></span><br> arrys的长度:<span th:text="${#arrays.length(array)}"></span><br> array是否包含张三:<span th:text="${#arrays.contains(array,'张三')}"></span><br> list是否为空:<span th:text="${#list.isEmpty(list)}"></span><br> list的长度:<span th:text="${#list.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>
Spring boot 整合JDBC Template
JDBC Template是spring自带的一个JDBC的模版组件,底层实现了对JDBC的封装,用法和Mybatis类似,需要开发者定义SQL语句,JDBC Template帮助我们完成数据库的连接,SQL的执行,结果集的封装
不足之处灵活性不如Mybatis,因为Mybatis是直接卸载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>soringbootdo</artifactId> <version>1.0-SNAPSHOT</version> <parent> <artifactId>spring-boot-starter-web</artifactId> <groupId>org.springframework.boot</groupId> <version>2.2.4.RELEASE</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-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
2.实体类:
package com.southwind.entity; import lombok.Data; @Data public class User { private Integer id; private String name; private Integer money; }
3.Repository
接口:
package com.southwind.Repository; import com.southwind.entity.User; import java.util.List; public interface UserRepository { public List<User> findAll(); public User finById(Integer id); public int save (User user); public int update(User user); public int delete(Integer id); }
package com.southwind.Repository.impl; import com.southwind.Repository.UserRepository; import com.southwind.entity.User; 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; public List<User> findAll() { return jdbcTemplate.query( "select * from people", new BeanPropertyRowMapper<>(User.class) ); } public User finById(Integer id) { return jdbcTemplate.queryForObject( "select * from people where id=?", new Object[]{id}, new BeanPropertyRowMapper<>(User.class) ); } public int save(User user) { return jdbcTemplate.update( "insert into people(id,name,money) values (?,?,?)", user.getId(), user.getName(), user.getMoney() ); } public int update(User user) { return jdbcTemplate.update( "update people set name=?,money=? where id=?", user.getName(), user.getMoney(), user.getId() ); } public int delete(Integer id) { return jdbcTemplate.update( "delete from people where id=?", id ); } }
4.Handeler
package com.southwind.Controller; import com.southwind.Repository.UserRepository; import com.southwind.Repository.impl.UserRepositoryImpl; import com.southwind.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.util.List; @Controller @RequestMapping("/user") public class UserHandler { @Autowired private UserRepositoryImpl userRepository; @GetMapping("/findall") @ResponseBody public List<User> findall(){ return userRepository.findAll(); } @GetMapping("/findbyid/{id}") @ResponseBody public User findbyid(@PathVariable("id")Integer id) { return userRepository.finById(id); } @PostMapping("/save") @ResponseBody public int save(@RequestBody User user){ return userRepository.save(user); } @PutMapping("/update") @ResponseBody public int update(@RequestBody User user){ return userRepository.update(user); } @DeleteMapping("/delete/{id}") @ResponseBody public int delete(@PathVariable Integer id){ return userRepository.delete(id); } }
方法
query:
public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException { return (List)result(this.query((String)sql, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper)))); }
RowMapper是一个接口,作用是分析结果集,将JDBC查询的ResultSet对象转化成对应的POJO
queryForObjiect(String sql,Object[] args, RowMapper
rowMapper) 该方法查询一条数据,并将结果封装成一个POJO
update
public int update(String sql, @Nullable Object... args) throws DataAccessException { return this.update(sql, this.newArgPreparedStatementSetter(args)); }
增加、修改、删除都可以用这个方法
Springboot Mybatis
<?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>soringbootdo</artifactId> <version>1.0-SNAPSHOT</version> <parent> <artifactId>spring-boot-starter-web</artifactId> <groupId>org.springframework.boot</groupId> <version>2.2.4.RELEASE</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-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- Mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> </dependencies> </project>
2.实体类
package com.southwind.entity; import lombok.Data; @Data public class User { private Integer id; private String name; private Integer money; }
3.创建Repository
package com.southwind.mybatis.Repository; import com.southwind.entity.User; import java.util.List; public interface UserRepository { public List<User> findAll(); public User finById(Integer id); public int save (User user); public int update(User user); public int delete(Integer id); }
<?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.southwind.mybatis.Repository.UserRepository"> <select id="findAll" resultType="User"> select * from people </select> <select id="finById" parameterType="java.lang.Integer" resultType="User"> select * from people where id=#{id} </select> <insert id="save" parameterType="User"> insert into people(id,name,money) values(#{id},#{name},#{money}) </insert> <update id="update" parameterType="User"> update people set name=#{name},money=#{name} where id=#{id} </update> <delete id="delete" parameterType="java.lang.Integer"> delete from people where id=#{id} </delete> </mapper>
4.Hnadelri
package com.southwind.Controller; import com.southwind.entity.User; import com.southwind.mybatis.Repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.util.List; @Controller @RequestMapping("mbuser") public class MuserHandler { @Autowired private UserRepository userRepository; @GetMapping("/findall") @ResponseBody public List<User> findall(){ return userRepository.findAll(); } @GetMapping("/findbyid/{id}") @ResponseBody public User findbyid(@PathVariable("id")Integer id) { return userRepository.finById(id); } @PostMapping("/save") @ResponseBody public int save(@RequestBody User user){ return userRepository.save(user); } @PutMapping("/update") @ResponseBody public int update(@RequestBody User user){ return userRepository.update(user); } @DeleteMapping("/delete/{id}") @ResponseBody public int delete(@PathVariable Integer id){ return userRepository.delete(id); } }
5.配置文件:
spring: datasource: url: jdbc:mysql://localhost:3306/text?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 mybatis: mapper-locations: classpath:/mapping/*.xml type-aliases-package: com.southwind.entity
6.启动类
package com.southwind; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.southwind.mybatis.Repository") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
Springboot 整合 Spring Data JPA
Spring Data JPA是Spring Data大家族的一员
JPA和Spring Data JPA的关系
JPA(Java Persistence API)java持久层的约束,定义了一系列的ORM接口,他本身不能直接使用,接口的必须实现才能使用,Hibernate框架实现了JPA规范的框架
Spring Data JPA是Spring框架提供的对JPA规范的抽象,通过约定的命名规范完成持久层接口的编写,在不需要实现接口的情况下,就可以完成对数据库的操作。
简单理解,通过Spring Data JPA只需要定义接口而不需要实现,就能完成CRUD操作
Spring Data JPA本身并不是一个具体的实现,他只是一个抽象层,底层还是需要Hibernate这样的JPA来提供支持。
Spring Data JPA和Spring JDBC Template的关系
JDBC Template是spring自带的一个JDBC的模版组件,底层实现了对JDBC的封装,用法和Mybatis类似,需要开发者定义SQL语句,JDBC Template帮助我们完成数据库的连接,SQL的执行,结果集的封装
Spring Data JPA是JPA的抽象
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>soringbootdo</artifactId> <version>1.0-SNAPSHOT</version> <parent> <artifactId>spring-boot-starter-web</artifactId> <groupId>org.springframework.boot</groupId> <version>2.2.4.RELEASE</version> </parent> <dependencies> <!-- --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springboot 集成jdbcTenplate--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- springboot 集成Mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <!-- springboot 集成JPA--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> </dependencies> </project>
2.实体类:完成实体类于表的映射
package com.southwind.entity; import lombok.Data; import javax.persistence.*; @Data @Entity(name = "people") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column private String name; @Column private Integer money; }
- @Entity将实体类与数据表进行映射
- @Id将实体类中的成员变量于数据表的主键进行映射,一般是id
- @GeneratedValue(strategy = GenerationType.IDENTITY)自动生成主键,strategy为主键选择的生成策略
- @Column将实体类中的成员变量与数据表的普通字段进行映射
3.创建Repository
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.data.jpa.repository; import java.util.List; import org.springframework.data.domain.Example; import org.springframework.data.domain.Sort; import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.QueryByExampleExecutor; @NoRepositoryBean public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { List<T> findAll(); List<T> findAll(Sort var1); List<T> findAllById(Iterable<ID> var1); <S extends T> List<S> saveAll(Iterable<S> var1); void flush(); <S extends T> S saveAndFlush(S var1); void deleteInBatch(Iterable<T> var1); void deleteAllInBatch(); T getOne(ID var1); <S extends T> List<S> findAll(Example<S> var1); <S extends T> List<S> findAll(Example<S> var1, Sort var2); }
package com.southwind.mybatis.Repository; import com.southwind.entity.User; import org.springframework.data.jpa.repository.JpaRepository; public interface JpaUserRepository extends JpaRepository<User,Integer> { }
4.创建Handler
package com.southwind.Controller; import com.southwind.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController("/jpaHandler") @RequestMapping("/JpaUser") public class JpaUserHandler { @Autowired private JpaRepository jpaRepository; @GetMapping("/findall") public List<User> findall(){ return jpaRepository.findAll(); } @GetMapping("/findbyid/{id}") @ResponseBody public User findbyid(@PathVariable("id")Integer id) { return (User) jpaRepository.findById(id).get(); } @PostMapping("/save") @ResponseBody public void save(@RequestBody User user){ jpaRepository.save(user); } @PutMapping("/update") @ResponseBody public Object update(@RequestBody User user){ return jpaRepository.save(user); } @DeleteMapping("/delete/{id}") @ResponseBody public void delete(@PathVariable("id") Integer id){ jpaRepository.deleteById(id); } }
5.配置application.yml
spring: datasource: url: jdbc:mysql://localhost:3306/text?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 jpa: show-sql: true properties: hibernate: format_sql: true mybatis: mapper-locations: classpath:/mapping/*.xml type-aliases-package: com.southwind.entity
6.在继承员原来的基础上增加新的方法
package com.southwind.jpa.Repository; import com.southwind.entity.User; import org.springframework.data.jpa.repository.JpaRepository; public interface JpaUserRepository extends JpaRepository<User,Integer> { public User findByName(String name); }
Spring Boot 整合Spring Seccurity
1.创建maven工程
<?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>springsecurity</artifactId> <version>1.0-SNAPSHOT</version> <parent> <artifactId>spring-boot-starter-web</artifactId> <groupId>org.springframework.boot</groupId> <version>2.2.4.RELEASE</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
package com.southwind.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class SecurtyHandler { @GetMapping("/index") public String index(){ return "index"; } }
3.HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p>idnex</p> <form method="post" action="/login"> <input type="submit" value="退出"> </form> </body> </html>
4.配置文件
spring: thymeleaf: suffix: .html prefix: classpath:/templates/
5.启动类
package com; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
用户名默认user
密码:默认随机
自定义:
spring: thymeleaf: suffix: .html prefix: classpath:/templates/ security: user: name: admin password: 123456
权限管理
定义两个资源:
index.html
package com.southwind.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.WebSecurityConfigurerAdapter; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { /** * 角色和资源 * @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() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll() .and() .csrf() .disable(); } /** * 用户和角色 * @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"); } }
admin.html
定义两个角色:
- ADMIN访问index.html
- USER访问index.html
1.创建SecurityConfig
2.自定义MypasswordEncoder类
package com.southwind.Config; import org.springframework.security.crypto.password.PasswordEncoder; public class MypasswordEncoder implements PasswordEncoder { @Override public String encode(CharSequence charSequence) { return charSequence.toString(); } @Override public boolean matches(CharSequence charSequence, String s) { return s.equals((charSequence.toString())); } }
3.
package com.southwind.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.WebSecurityConfigurerAdapter; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { /** * 角色和资源 * @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() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll() .and() .csrf() .disable(); } /** * 用户和角色 * @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"); } }
4.Handler
package com.southwind.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class SecurtyHandler { @GetMapping("/index") public String index(){ return "index"; } @GetMapping("/admin") public String admin(){ return "adimin"; } @GetMapping("/login") public String login(){ return "login"; } }
5.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>
<!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>
<!DOCTYPE html> <html lang="en"> <html xmlns:th="http://www.thymeleaf.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>
-
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律