1.Jdbc 템플릿
SpringData 소개
Spring Framework의 데이터베이스 작업은 Jdbc에 깊이 캡슐화되어 있으며 종속성 주입 기능을 통해 DataSource를 JdbcTemplate에 등록할 수 있으므로 개체 관계 매핑을 쉽게 완료하고 일반적인 오류를 방지할 수 있습니다. SpringBoot에서 쉽게 사용할 수 있습니다.
특징:
- 속도가 빠르다 다른 ORM 프레임워크에 비해 JDBC 방식이 가장 빠르다.
- Spring 자체적으로 생성되는 간단한 구성, 추가 구성이 거의 없음
- 낮은 학습 비용, 모든 JDBC가 가장 기본적인 지식이므로 JdbcTemplate은 DBUtils와 비슷합니다.
JdbcTemplate 통합
pom.xml에서 JdbcTemplate에 대한 종속성 추가
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</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-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
application.properties에 다음 구성을 추가합니다. 기본적으로 SpringBoot가 자동으로 DataSource를 구성한다는 점은 주목할 가치가 있습니다
.HikariCP 연결 풀에 우선 순위를 부여합니다.그러한 종속성이 없으면 tomcat-jdbc를 선택하고, 앞의 두 가지를 사용할 수 없으면 마지막으로
Commons DBCP2를 선택하십시오. 다른 유형의 연결 풀은 spring.datasource.type 속성을 통해 지정할 수 있습니다.
# 数据源
spring:
datasource:
url: jdbc:mysql:///boot?useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password:
프로젝트를 시작하고 로그를 통해 기본적으로 HikariDataSource가 주입된 것을 확인할 수 있습니다.
2022-11-16 09:14:46.329 INFO 16472 --- [ main]
com.xja.Day03Application : Starting Day03Application using Java
1.8.0_201 on DESKTOP-TTS40QH with PID 16472 (E:\课程记录\T6\03-SpringBoot整合
\day03\target\classes started by lenovo in E:\课程记录\T6\03-SpringBoot整合\day03)
2022-11-16 09:14:46.336 INFO 16472 --- [ main]
com.xja.Day03Application : No active profile set, falling back
to 1 default profile: "default"
2022-11-16 09:14:47.614 INFO 16472 --- [ main]
.s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC
repositories in DEFAULT mode.
2022-11-16 09:14:47.624 INFO 16472 --- [ main]
.s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository
scanning in 5 ms. Found 0 JDBC repository interfaces.
2022-11-16 09:14:48.329 INFO 16472 --- [ main]
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080
(http)
2022-11-16 09:14:48.342 INFO 16472 --- [ main]
o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-11-16 09:14:48.342 INFO 16472 --- [ main]
org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache
Tomcat/9.0.68]
2022-11-16 09:14:48.559 INFO 16472 --- [ main] o.a.c.c.C.[Tomcat].
[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-11-16 09:14:48.560 INFO 16472 --- [ main]
w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext:
initialization completed in 2156 ms
2022-11-16 09:14:48.977 WARN 16472 --- [ main]
ion$DefaultTemplateResolverConfiguration : Cannot find template location:
classpath:/templates/ (please add some templates, check your Thymeleaf
configuration, or set spring.thymeleaf.check-template-location=false)
2022-11-16 09:14:49.090 INFO 16472 --- [ main]
com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-11-16 09:14:49.283 INFO 16472 --- [ main]
com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-11-16 09:14:49.586 INFO 16472 --- [ main]
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080
(http) with context path ''
2022-11-16 09:14:49.596 INFO 16472 --- [ main]
com.xja.Day03Application : Started Day03Application in 4.047
seconds (JVM running for 7.288)
케이스 테스트
t_user 테이블 생성
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(1) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
엔티티 클래스
package com.xja.entity;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
private int age;
private String description;
}
컨트롤 레이어
package com.xja.controller;
import java.util.List;
@Controller
@RequestMapping("/student")
public class StudentController {
@Autowired
private StudentService studentService;
/**
* 查询
*/
@RequestMapping("queryStudentList")
public String queryStudentList(Model model){
List<Student> list = studentService.queryStudentList();
model.addAttribute("list",list);
return "student_list";
}
/**
* 增加跳转
*/
@RequestMapping("/toAdd")
public String toAdd(){
return "student_add";
}
/**
* 增加
*/
@RequestMapping("/saveStudent")
public String saveStudent(Student student){
studentService.saveStudent(student);
return "redirect:/student/queryStudentList";
}
@RequestMapping("/deleteStudent")
public String deleteStudent(Integer id){
studentService.deleteStudent(id);
return "redirect:/student/queryStudentList";
}
}
비즈니스 레이어 생략 -> 지속 레이어
package com.xja.dao;
import java.util.List;
@Repository //老实持久层的标记 同 @Controller @Service 一起的
public class StudentDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<Student> queryStudentList() {
String sql = "select * from student";
List<Student> list = jdbcTemplate.query(sql, new
BeanPropertyRowMapper<>(Student.class));
return list;
}
//单个对象 queryForObject
public void saveStudent(Student student) {
String sql = "insert into student (name,age,description) value
(?,?,?)";
jdbcTemplate.update(sql,student.getName(),student.getAge(),student.getDescript
ion());
}
public void deleteStudent(Integer id) {
String sql = "delete from student where id = ?";
jdbcTemplate.update(sql,id);
}
}
쿼리 페이지
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<script type="text/javascript" th:src="@{/js/jquery-3.6.0.js}"></script>
<script type="text/javascript" th:src="@{/js/bootstrap.min.js}"></script>
<script>
$(function () {
$("#save").click(function () {
window.location = "toAdd";
})
})
function deletes(id){
alert(id);
}
</script>
</head>
<body>
<button class="btn btn-success" id="save">增加</button>
<table class="table table-bordered" style="width: 800px">
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>描述</th>
<th>操作</th>
</tr>
<tr th:each="stu,i:${list}">
<td th:text="${i.count}"></td>
<td th:text="${stu.name}"></td>
<td th:text="${stu.age}"></td>
<td th:text="${stu.description}"></td>
<td>
<button class="btn btn-sm btn-danger"
th:onclick="|deletes(${stu.id})|">删除</button>
<a th:href="|deleteStudent?id=${stu.id}|">删除</a>
</td>
</tr>
</table>
</body>
</html>
결과: 약간
2. 타임리프 템플릿
소개:
Thymeleaf는 웹 및 독립 실행형 환경 프로젝트를 개발하기 위한 최신 서버 측 Java 템플릿 엔진입니다.
Thymeleaf의 주요 목표는 HTML의 우아함을 개발 워크플로에 가져오는 것입니다. 다이렉트 브라우저에 올바르게 표시할 수
있고 정적 프로토타입으로 사용할 수 있으므로 개발 팀 간의 협업이 강화됩니다.
원하는 대로 자유롭게 선택할 수 있는 Spring Framework의 모듈과 플러그형 기능 구성 요소를 갖춘 Thymeleaf는 훨씬
더 많은 작업을 수행할 수 있지만 최신 HTML5 JVM 웹 개발에 이상적입니다.
Spring에서 공식적으로 지원하는 서비스의 렌더링 템플릿에는 jsp가 포함되어 있지 않습니다. Thymeleaf 및 Freemarker 등이며
Thymeleaf와 SpringMVC의 뷰 기술 및 SpringBoot의 자동 구성의 통합이 완벽하고 비용이 거의 들지 않으며 Thymeleaf의 구문에만주의하면됩니다
.
특징:
동적 및 정적 조합: Thymeleaf는 네트워크 환경과 비네트워크 환경 모두에서 실행할 수 있습니다. 즉, 아티스트가 브라우저에서 페이지의 정적 효과를 볼 수 있고 프로그래머가 서버의 데이터로 동적 페이지 효과를 볼 수 있습니다. . 이는 html 프로토타입을 지원한 다음
html 태그에 속성을 추가하여 템플릿 + 데이터 표시를 달성하기 때문입니다. 브라우저가 html을 해석할 때 정의되지 않은 태그 속성을 무시하므로
thymeleaf 템플릿이 정적으로 실행될 수 있습니다. 일부 데이터가 페이지로 반환되면 Thymeleaf 태그가 정적
콘텐츠를 동적으로 대체하여 페이지가 동적으로 표시될 수 있습니다.
2. 기본 제공: 표준 및 스프링 표준 방언을 제공하고 템플릿을 직접 적용하여 JSTL 및 OGNL 표현 효과를 얻을 수 있으므로
매일 템플릿, jstl 및 레이블 변경 문제를 피할 수 있습니다. 동시에 개발자는 사용자 지정 방언을 확장하고 만들 수도 있습니다.
3. Multi-dialect 지원: Thymeleaf는 스프링 표준 방언과 SpringMVC와 완벽하게 통합된 선택적 모듈을 제공하여
폼 바인딩, 속성 편집기 및 국제화와 같은 기능을 빠르게 실현할 수 있습니다.
4. SpringBoot와의 완벽한 통합, SpringBoot는 Thymeleaf의 기본 구성을 제공하고 Thymeleaf에 대한 뷰 파서를 설정하면
jsp를 작동했던 것처럼 Thymeleaf를 작동할 수 있습니다. 템플릿 구문을 제외하고 코드에는 거의 차이가 없습니다
.
기본 설정
환경 생성
웹 및 Thymeleaf
의 기본 구성 확인
어떠한 구성도 할 필요 없이 런처는 Thymeleaf의 뷰 파서를 구성하는 데 도움이 됩니다.
또한 jsp + 뷰 이름과 유사한 접두사인 템플릿 파일(HTML)의 위치도 구성합니다. +접미사 스타일
기본 접두사: classpath:/templates/
기본 접미사: .html
따라서 사용자 보기로 돌아가면 classpath:/templates/users.html을 가리킬 것입니다.
Thymeleaf는 기본적으로 페이지 캐싱을 활성화하여 페이지 동시성을 향상시킵니다. 그러나 수정된 페이지가 즉시 표시되지 않으므로
캐시를 닫습니다.
#关闭Thymeleaf的缓存
spring.thymeleaf.cache=false
또한 페이지를 수정한 후 바로 가기 키(Ctrl + Shift + F9)를 사용하여 프로젝트를 새로 고쳐야 합니다.
빠른 시작
보기 점프를 제어할 컨트롤러를 준비하자
@Controller
public class HelloController {
@GetMapping("show1")
public String show1(Model model){
model.addAttribute("msg", "Hello, Thymeleaf!");
return "hello";
}
}
새 HTML 템플릿 만들기
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<h1 th:text="${msg}">大家好</h1>
</body>
</html>
html의 네임스페이스를 다음으로 변경하십시오. xmlns:th="http://www.thymeleaf.org" 구문 프롬프트가 나타납니다.
프로젝트를 시작하고 페이지를 방문하십시오.
문법
Thymeleaf의 주요 기능은 모델의 데이터를 HTML로 렌더링하는 것이므로 구문은 주로 모델의 데이터를 구문 분석하는 방법입니다. 다음 측면에서 배우십시오.
-
변하기 쉬운
-
방법
-
조건부 판단
-
주기
-
작업
逻辑预算 布尔运算 比较运算 条件运算
-
다른
변하기 쉬운
먼저 새 엔터티 클래스를 생성해 보겠습니다. 사용자
public class User {
String name;
int age;
User friend;// 对象类型属性
}
그런 다음 모델에 데이터를 추가합니다.
@GetMapping("show2")
public String show2(Model model){
User user = new User();
user.setAge(21);
user.setName("Jack Chen");
user.setFriend(new User("李小龙", 30));
model.addAttribute("user", user);
return "show2";
}
문법 설명:
Thymeleaf는 모델에서 변수를 얻기 위해 ${}를 사용합니다. 이것은 el 표현식이 아니라 ognl 표현식이지만 구문은 매우 유사합니다.
예:
페이지에서 사용자 데이터를 얻습니다.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>用户页面</title>
</head>
<body>
<div th:text="${user.name}"></div>
</body>
</html>
결과:
el 표현과 거의 같은 느낌입니다. 그러나 차이점은 표현식이 지시어라고 하는 th:text라는 태그 속성에 작성된다는 것입니다
.
동적 및 정적
지침의 조합:
Thymeleaf는 자연 템플릿을 지지합니다. 즉, 템플릿은 템플릿 엔진과 분리된 순수한 html 코드이며 순수한 정적 환경에서 직접 실행할 수 있습니다
. 이제 ${}와 같은 표현식을 html에 직접 작성하면 정적 환경에서 분명히 잘못될 것이며 이는 Thymeleaf의 철학과 일치하지 않습니다
.
Thymeleaf의 모든 표현식은 HTML5의 사용자 정의 속성인 디렉티브로 작성해야 하며 Thymeleaf의 모든 디렉티브는
th:로 시작합니다. ${user.name} 표현식은 사용자 정의 속성으로 작성되기 때문에 정적 환경에서 표현식의 내용은 일반 문자열로
처리 브라우저는 이러한 지침을 자동으로 무시하므로 오류가 보고되지 않습니다. !
이제 SpringMVC를 거치지 않고 브라우저에서 직접 페이지를 열어 다음을 확인합니다.
- 정적 페이지에서는 th 명령이 인식되지 않지만 브라우저는 오류를 보고하지 않고 일반 속성으로 처리합니다. 이렇게 하면 스팬의 기본값인 로그인하십시오. 페이지에 표시됩니다.
- Thymeleaf 환경이면 th 명령을 인식하고 파싱하며 th:text 의 의미는 레이블의 텍스트 내용을 대체하는 것이므로 user.name 의 값이 기본값을 대체합니다. 스팬에서 로그인하십시오.
명령의 디자인은 정확히 Thymeleaf의 탁월함이며 다른 템플릿 엔진보다 우수한 이유이기도 합니다.
정적 및 동적 디자인의 조합은 프론트엔드 개발자와 백엔드 개발자 모두에게 완벽하게 맞습니다 .
하위 호환성
하지만 브라우저가 Html5를 지원하지 않는다면 어떻게 될까요?
이 th: 네임스페이스를 지원하지 않는 경우 th:text를 data-th-text로 대체할 수 있으며 Thymeleaf도 호환됩니다.
또한 보안 상의
이유로 th:text 명령은 HTML 주입을 방지하기 위해 표현식에서 읽은 값을 처리합니다.
예를 들어,
안녕하세요
형식은 lt ; p lt;pLT ;p gt;hello lt;/p lt;/pLT ;/ plt ; . 형식화된 출력 대신 원래 내용을 출력하려면 대신 th:utext를 사용하십시오 . 그러나 경우에 따라 속성 이름 자체가 변수일 수 있습니다. 어떻게 해야 합니까? ognl은 js와 유사한 구문을 제공합니다.
例如: ${
user.name} 可以写作${
user['name']}
사용자 정의 변수
시나리오
다음 사례를 참조하십시오.
<h2>
<p>Name: <span th:text="${user.name}">Jack</span>.</p>
<p>Age: <span th:text="${user.age}">21</span>.</p>
<p>friend: <span th:text="${user.friend.name}">Rose</span>.</p>
</h2>
사용자의 모든 정보를 가져와 별도로 표시합니다.
데이터 양이 상대적으로 많으면 사용자를 자주 쓰는 것이 매우 번거로울 것입니다.
따라서 Thymeleaf는 해결하기 위한 사용자 지정 변수를 제공합니다.
예:
<h2 th:object="${user}">
<p>Name: <span th:text="*{name}">Jack</span>.</p>
<p>Age: <span th:text="*{age}">21</span>.</p>
<p>friend: <span th:text="*{friend.name}">Rose</span>.</p>
</h2>
먼저 h2에서 th:object="${user}"를 사용하여 user의 값을 가져오고 저장한 다음 h2 내부의 모든 요소에서 *{attribute name}으로 user의 속성을 가져올 수 있습니다. 많은 사용자를 절약
합니다 .
<h2 th:object="${user}">
<p>FirstName: <span th:text="*{name.split(' ')[0]}">Jack</span>.</p>
<p>LastName: <span th:text="*{name.split(' ')[1]}">Li</span>.</p>
</h2>
Thymeleaf에서 제공하는 전역 객체:
예를 들어
날짜 유형 개체를 환경 변수에 추가합니다.
@GetMapping("show3")
public String show3(Model model){
model.addAttribute("today", new Date());
return "show3";
}
페이지 처리
<p>
今天是: <span th:text="${#dates.format(today,'yyyy-MM-dd')}">2018-04-25</span>
</p>
리터럴 값
때로는 명령에서 문자열, 값, 부울 등과 같은 기본 유형을 채워야 하며 Thymeleaf가 이를 현재 리터럴 값이라고 하는 변수로 구문 분석하는 것을 원하지 않습니다 .
문자열 리터럴
' 쌍을 사용하여 문자열 리터럴인 내용을 인용합니다.
<p>
你正在观看 <span th:text="'thymeleaf'">template</span> 的字符串常量值.
</p>
th:text의 Thymeleaf는 변수로 간주되지 않지만 문자열입니다. 숫자
리터럴 값
숫자는 특별한 구문이 필요하지 않으며 쓰여진 내용 그대로이며 산술 연산을 직접 수행할 수 있습니다.
<p>今年是 <span th:text="2018">1900</span>.</p>
<p>两年后将会是 <span th:text="2018 + 2">1902</span>.</p>
부울 리터럴
부울 리터럴은 참 또는 거짓입니다.
<div th:if="true">
你填的是true
</div>
vue의 v-if와 유사한 th:if 명령이 여기에 인용됩니다
산술
연산
지원되는 산술 연산자: + - * / %
<span th:text="${user.age}"></span>
<span th:text="${user.age}%2 == 0"></span>
- 비교 작업
지원되는 비교 작업: > , < , >= 및 <= 하지만 > , < 는 xml이 태그로 구문 분석되고 별칭을 사용해야 하므로 직접 사용할 수 없습니다.
== 및 !=는 equals의 기능과 유사하게 값을 비교할 수만 있는 것은 아닙니다.
사용할 수 있는 별칭: gt(>), lt(<), ge(>=), le(<=), not(!) eq(==), neq/ne(!=). - 조건부 연산
1. 삼항 연산
<span th:text="${user.sex} ? '男':'女'"></span>
삼항 연산자의 세 부분: conditon ? then : else
condition: condition
then: 조건이 참인 결과
else: 참이 아닌 결과 이
각 부분은 Thymeleaf의 모든 표현식이 될 수 있습니다.
2. 기본값
가끔 비어있을 수 있는 값을 취하는데 이때 비어 있지 않은지 판단해야 하는데 ?: 기본값의 약어
:
<span th:text="${user.name} ?: '二狗'"></span>
이전 표현식 값이 null이면 후자의 기본값이 사용됩니다.
참고: ?: 사이에는 공백이 없습니다.
주기
루프는 또한 매우 자주 사용되는 요구 사항입니다. 우리는 완료하기 위해 th:each 명령을 사용합니다.
사용자 컬렉션이 있는 경우: 사용자는 컨텍스트에 있습니다.
<tr th:each="user : ${users}">
<td th:text="${user.name}">Onions</td>
<td th:text="${user.age}">2.41</td>
</tr>
${users}는 순회할 컬렉션이며 다음 유형일 수 있습니다.
1.Iterable, Iterable 인터페이스를 구현하는 클래스
2.Enumeration, 열거형
3.Interator, 반복자
4.Map, 순회되는 것은 Map.Entry임
5.Array, 결과를 준수하는 배열 및 기타 모든 개체 배열이
동시에 반복되므로 반복된 상태 객체를 얻을 수도 있습니다.
<tr th:each="user,stat : ${users}">
<td th:text="${user.name}">Onions</td>
<td th:text="${user.age}">2.41</td>
</tr>
stat 개체에는 다음 속성이 포함되어 있습니다.
- 인덱스, 0부터 시작하는 인덱스
- count, 요소 수, 1부터 시작
- 크기, 총 요소 수
- current, 현재 통과한 요소
- 짝수/홀수, 홀수인지 짝수인지 반환, 부울 값
- 첫 번째/목록, 반환 값이 첫 번째인지 마지막인지, Boolean 값
논리 판단
if와 else를 사용하면 모든 기능을 수행할 수 있습니다 _ .
Thymeleaf에서 th:if 또는 th:unless를 사용하십시오. 둘의 의미는 정반대입니다.
<span th:if="${user.age} < 24">小鲜肉</span>
표현식이 true로 평가되면 레이블이 페이지에 렌더링되고 그렇지 않으면 렌더링되지 않습니다.
다음 조건이 참으로 간주됩니다.
표현식 값이 참,
표현식 값이 0이 아닌 값,
표현식 값이 0이 아닌 문자
, 표현식 값이 문자열이지만 "거짓", "아니오"가 아님, "off"
표현식이 부울이 아닙니다. , 문자열, 숫자, 문자,
null을 포함한 기타 조건 중 하나는 거짓으로 간주됩니다.