【Java】springBoot初识(Web和数据库交互)
文章目录
!可以先跳过前序直接看项目示例
1.前序
1.1.sping
1.1.1.依赖注入(DI)
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void saveUser(User user) {
userRepository.save(user);
}
}
-
字段注入:测试类
-
构造器注入:常用
-
why:
服务层中使用构造器注入的好处
- 不可变性:构造器注入确保了依赖项在对象创建时就已经确定并且不可更改,这有助于保证对象的状态一致性。
- 明确性:通过构造器显式地列出所有依赖项,可以清晰地展示哪些依赖项是必需的,这有助于提高代码的可读性和可维护性。
- 易于测试:构造器注入使得对象更容易被测试,因为依赖项可以通过构造器传递给待测试的类。这使得我们可以很容易地为测试提供模拟对象。
- 强制依赖:构造器注入有助于防止
NullPointerException
,因为在构造器中必须提供所有必需的依赖项。 - 易于调试:由于构造器注入确保了所有依赖项在对象创建时就已经存在,因此更容易追踪和调试潜在的问题。
测试类中使用字段注入的好处
- 简化测试代码:字段注入可以减少测试代码的复杂性,特别是在需要注入多个依赖项的情况下。这使得测试类更加简洁明了。
- 快速启动:字段注入可以更快地启动测试环境,因为它不需要复杂的构造器和初始化逻辑。
- 易于理解和编写:字段注入使得依赖关系的注入变得非常直观,开发者可以直接看到哪些依赖项被注入到了类中。
1.1.2.面向切面(AOP)
// 日志切面
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.SomeService.doSomething(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before " + joinPoint.getSignature().getName());
}
@After("execution(* com.example.service.SomeService.doSomething(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After " + joinPoint.getSignature().getName());
}
}
// 服务类
@Service
public class SomeService {
public void doSomething() {
// 业务逻辑
}
}
1.1.3.好处
依赖注入(DI)的好处
- 降低耦合度:DI通过将对象的创建和依赖管理交给外部容器(如Spring容器),减少了对象之间的直接依赖,提高了代码的可维护性和灵活性。
- 易于测试:DI使得对象更容易被测试,因为依赖项可以通过构造器或其他方式传递给待测试的类。这使得我们可以很容易地为测试提供模拟对象。
- 代码重用:通过将依赖项注入到多个类中,可以减少代码重复,提高代码复用性。
- 更好的模块化:DI有助于将系统分解为更小、更独立的模块,这些模块之间通过接口进行通信,而不是直接调用实现。
- 减少样板代码:DI框架(如Spring)可以自动处理依赖项的创建和销毁,减少了需要手动编写的样板代码量。
面向切面编程(AOP)的好处
- 分离关注点:AOP允许将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,使得业务逻辑更加清晰,同时也更容易维护这些横切关注点。
- 代码重用:AOP通过定义切面来封装横切关注点的行为,使得这些行为可以在多个不同的地方重用,减少了代码重复。
- 易于扩展:新的横切关注点可以通过定义新的切面来轻松添加,而无需修改现有的业务逻辑代码。
- 模块化:AOP使得横切关注点成为独立的模块,这些模块可以独立于核心业务逻辑进行开发和维护。
- 透明性:AOP可以使得某些横切关注点对业务逻辑来说几乎是透明的,即业务逻辑不需要知道这些关注点是如何被处理的。
1.2.spingboot的作用
- 简化配置:Spring Boot 内置了许多默认配置,这意味着开发者不需要编写大量的 XML 或 properties 文件来配置应用程序。Spring Boot 会自动配置许多常见的功能,如嵌入式服务器、安全、数据访问、日志记录等。
- 自动配置:Spring Boot 提供了自动配置机制,它可以根据类路径中存在的 jar 包来自动配置 Spring Bean 和组件。这大大减轻了开发者手动配置的负担。
- 依赖管理:Spring Boot 提供了一套默认的依赖管理策略,包括版本管理和依赖排除,使得开发者不必担心版本冲突问题。
- 开箱即用的特性:Spring Boot 提供了许多开箱即用的功能,如嵌入式的 Tomcat、Jetty 或 Undertow 服务器,使得开发者可以快速启动 Web 应用程序,而无需额外配置服务器。
- 生产准备特性:Spring Boot 提供了一些生产准备特性,如健康检查、监控指标、审计和外部配置管理等,这些特性使得应用程序更容易部署和管理。
- 简化开发流程:Spring Boot 支持使用命令行界面(CLI)进行快速原型开发,并且提供了许多启动器(starter)项目,这些项目包含了一组预定义的依赖项,使得开发者可以快速搭建起基本的应用程序结构。
- 易于创建独立的、生产级别的基于 Spring 的应用程序:Spring Boot 应用程序可以被打包成独立的 JAR 或 WAR 文件,这意味着应用程序可以作为一个单一的可执行文件运行,无需外部部署。
2.项目示例
2.1利用IDEA创建SpringBoot项目
点击next,进入依赖的选择
先选择这些依赖后点击create,之后刷新maven下载这些依赖
2.2依赖的解释
<dependencies>
<!-- 1 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
</dependency>
<!-- 2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 3 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 4 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 5 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 6 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
1.spring-boot-starter-parent
- 统一依赖版本管理:
spring-boot-starter-parent
定义了一系列Spring Boot依赖的版本号。当你在项目中添加Spring Boot相关的依赖时,不需要指定版本号,因为spring-boot-starter-parent
已经为你指定了这些依赖的版本。 - 提供默认配置:
spring-boot-starter-parent
包含了Spring Boot的一些默认配置,比如自动配置和启动器(starters)。这意味着你可以使用Spring Boot提供的自动配置功能,而不需要手动配置大量的XML或properties文件。 - 简化项目结构:通过继承
spring-boot-starter-parent
,你可以在项目中使用Spring Boot的启动器(starters),这些启动器是预先配置好的依赖集合,可以帮助你快速搭建项目的基础结构。 - 提供构建插件:
spring-boot-starter-parent
还提供了一些构建插件,如spring-boot-maven-plugin
,这个插件可以用来打包Spring Boot应用程序,使其成为一个可执行的JAR文件。
2.spring-boot-starter-test
- 简化测试依赖管理:
spring-boot-starter-test
包含了编写和运行Spring Boot应用程序测试所需的各种库。这包括JUnit、Mockito、Spring Test等,它们都是编写高质量测试的重要工具。 - 自动配置:
spring-boot-starter-test
提供了一些自动配置,使得开发者可以轻松地使用Spring Boot的测试支持特性,如自动配置测试环境、MockMVC等。 - 简化测试代码:通过使用
spring-boot-starter-test
,开发者可以更容易地编写简洁的测试代码。例如,可以使用Spring Test的@RunWith(SpringRunner.class)
和@SpringBootTest
注解来配置测试上下文。
3.spring-boot-starter-web
- 简化依赖管理:
spring-boot-starter-web
包含了创建Web应用程序所需的各种依赖,如Spring Web MVC、Spring WebFlux、Jackson JSON处理器等。使用这个启动器可以避免手动添加和管理这些依赖。 - 自动配置:
spring-boot-starter-web
提供了一系列自动配置,使得开发者不需要编写大量的配置代码就可以启动一个Web应用。例如,它会自动配置嵌入式的Servlet容器(如Tomcat、Jetty或Undertow),以及Spring MVC相关的配置。 - 简化开发过程:使用
spring-boot-starter-web
可以极大地简化Web应用的开发过程,使得开发者可以专注于业务逻辑的实现,而不是配置。
4.spring-boot-starter-thymeleaf
- 简化依赖管理:
spring-boot-starter-thymeleaf
包含了Thymeleaf的核心库以及其他相关依赖,如Thymeleaf Spring Integration等。使用这个启动器可以避免手动添加和管理这些依赖。 - 自动配置:
spring-boot-starter-thymeleaf
提供了一系列自动配置,使得开发者不需要编写大量的配置代码就可以使用Thymeleaf模板。例如,它会自动配置Thymeleaf的模板解析器和视图解析器。 - 简化开发过程:使用
spring-boot-starter-thymeleaf
可以极大地简化Web应用的开发过程,使得开发者可以专注于业务逻辑的实现,而不是配置。
5.spring-boot-starter-data-jpa
- 简化依赖管理:
spring-boot-starter-data-jpa
包含了 JPA 实现(如 Hibernate)、JDBC 驱动、Spring Data JPA 等相关依赖,无需手动添加这些依赖。 - 自动配置:Spring Boot 会自动配置 JPA 和相关的数据源(DataSource),开发者不需要手动配置大量的 XML 文件或 Java 配置类。
- 简化开发过程:使用
spring-boot-starter-data-jpa
可以极大地简化数据访问层的开发过程,使得开发者可以专注于业务逻辑的实现。
6.lombok
@Getter
和@Setter
:- 自动生成所有字段的 getter 和 setter 方法。
- 可以指定
private
、protected
、public
等访问级别。
@Data
:- 结合了
@Getter
、@Setter
、@ToString
、@EqualsAndHashCode
等注解的功能,适用于简单的 POJO 类。
- 结合了
2.3.spring-boot-starter-web与spring-boot-starter-thymeleaf的使用
源码在最后
我们单独测试这两项,所以将jpa依赖注释掉并刷新maven
<!-- 注释这个 -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!-- </dependency>-->
创建cotroller包,在里面创建HelloWord类,写下如下代码
打开resources里面的templates,在里面创建helloWorld.html模板,写上如下代码
之后启动springBoot程序,并在浏览器访问http://127.0.0.1:8080/ (端口默认为8080) 则会看到hello,world字样
2.4 连接mySQL数据库
首先取消对jpa依赖的注释,并刷新maven
由于是连接mySQL数据库,所以我们还需要添加一个mySQL JDBC驱动的依赖:
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
配置application.properties文件,填写连接mySQL的信息
first是我的一个数据库的名称
为first数据库中的表创建模型:
这是我的first数据库中的名为second的表
对应其表头创建模型
创建mySQL仓,里面有mySQL数据库增删改查的很多方法
利用findAll()方法找到second表中的所有数据并将电影名打印出来
写好测试类并运行,观看效果
2.5 将数据库中的表格在前端显示出来
写一个显示数据库数据的路由,读取数据库中的数据并将其添加到model中方便html模板调用
写html模板,将表second中的数据在前端呈现出来
运行springBoot程序,访问http://127.0.0.1:8080/mysqlData 可以看到以下的显示效果
3.源码
1.pom.xml
<!-- 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 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>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.exam</groupId>
<artifactId>projectOf002</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>projectOf002</name>
<description>projectOf002</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</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>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>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.HelloWorld.java
// HelloWorld.java
package com.exam.projectof002.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HelloWorld {
@GetMapping("/")
public String helloWorld() {
return "helloWorld";
}
}
3.helloWorld.html
<!-- helloWorld.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>hello,world!</h1>
</body>
</html>
4.application.properties
# application.properties
spring.application.name=projectOf002
spring.datasource.url=jdbc:mysql://localhost:3306/first
spring.datasource.username=root
spring.datasource.password=yourPassword
5.MovieModel.java
// MovieModel.java
package com.exam.projectof002.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
@Entity
@Data
@Table(name="second")
public class MovieModel {
@Id
@GeneratedValue
private Long id;
private String title;
private int year;
private String subject;
private String duration;
private String intro;
}
6.MysqlRepository.java
// MysqlRepository.java
package com.exam.projectof002.dao;
import com.exam.projectof002.model.MovieModel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface MysqlRepository extends JpaRepository<MovieModel,Long> {
}
7.MysqlCrudService.java
// MysqlCrudService.java
package com.exam.projectof002.service;
import com.exam.projectof002.dao.MysqlRepository;
import com.exam.projectof002.model.MovieModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MysqlCrudService {
private final MysqlRepository mysqlRepository;
@Autowired
public MysqlCrudService(MysqlRepository mysqlRepository) {
this.mysqlRepository = mysqlRepository;
}
public List<MovieModel> getAllMovies() {
return mysqlRepository.findAll();
}
}
8.MysqlFindDataTest.java
// MysqlFindDataTest.java
package com.exam.projectof002;
import com.exam.projectof002.model.MovieModel;
import com.exam.projectof002.service.MysqlCrudService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class MysqlFindDataTest {
@Autowired
MysqlCrudService mysqlCrudService;
@Test
public void test() {
List<MovieModel> movieModelList=mysqlCrudService.getAllMovies();
for(MovieModel movieModel:movieModelList){
System.out.println(movieModel.getTitle());
}
}
}
9.ShowMysqlData.java
// ShowMysqlData.java
package com.exam.projectof002.controller;
import com.exam.projectof002.dao.MysqlRepository;
import com.exam.projectof002.model.MovieModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.ui.Model;
import java.util.List;
@Controller
public class ShowMysqlData {
MysqlRepository mysqlRepository;
@Autowired
public ShowMysqlData(MysqlRepository mysqlRepository) {
this.mysqlRepository = mysqlRepository;
}
@GetMapping("/mysqlData")
public String showMysqlData(Model model) {
List<MovieModel> movieModelList = mysqlRepository.findAll();
model.addAttribute("movieModelList", movieModelList);
return "mysqlData";
}
}
10.mysqlData.html
<!-- mysqlData.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MysqlData</title>
<style>
table,th,td{
border: 1px solid black;
border-collapse: collapse;
padding: 8px;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>序号</th>
<th>电影名</th>
<th>出版年份</th>
<th>标语</th>
<th>片长</th>
<th>简介</th>
</tr>
</thead>
<tbody>
<tr th:each="movie : ${movieModelList}">
<td th:text="${movie.id}"></td>
<td th:text="${movie.title}"></td>
<td th:text="${movie.year}"></td>
<td th:text="${movie.subject}"></td>
<td th:text="${movie.duration}"></td>
<td th:text="${movie.intro}"></td>
</tr>
</tbody>
</table>
</body>
</html>
4.结语
本人资历尚浅,发博客主要是记录与学习,欢迎大佬们批评指教!大家也可以在评论区多多交流,相互学习,共同成长。