Spring Boot @Repository
最后修改于 2023 年 8 月 2 日
Spring Boot @Repository 教程展示了如何在 Spring 应用程序中使用 @Repository 注解。
Spring 是一个流行的 Java 应用程序框架,而 Spring Boot 是 Spring 的一个演进,它有助于轻松创建独立的、生产级的基于 Spring 的应用程序。
@Repository
@Repository 是一个 Spring 注解,用于指示被修饰的类是一个存储库。存储库是一种封装存储、检索和搜索行为的机制,它模拟了一个对象集合。它是 @Component 注解的特化,允许通过类路径扫描自动检测实现类。
@ComponentScan 确保使用 @Component 及其衍生类(包括 @Repository)修饰的类被找到并注册为 Spring Bean。@ComponentScan 自动包含在 @SpringBootApplication 中。
Spring Boot @Repository 示例
以下应用程序演示了 @Repository 的用法。它向用户显示一个 HTML 表格中的国家/地区列表。
build.gradle
...
src
├── main
│ ├── java
│ │ └── com
│ │ └── zetcode
│ │ ├── Application.java
│ │ ├── controller
│ │ │ └── MyController.java
│ │ ├── model
│ │ │ └── Country.java
│ │ ├── repository
│ │ │ └── CountryRepository.java
│ │ └── service
│ │ ├── CountryService.java
│ │ └── ICountryService.java
│ └── resources
│ ├── application.yml
│ ├── import.sql
│ ├── static
│ │ └── index.html
│ └── templates
│ └── showCountries.ftlh
└── test
├── java
└── resources
这是项目结构。
plugins {
id 'org.springframework.boot' version '3.1.1'
id 'io.spring.dependency-management' version '1.1.0'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-freemarker'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
}
这是 Gradle 构建文件。 h2 依赖项包括 H2 数据库驱动程序。
Spring Boot starters 是一组方便的依赖项描述符,它们大大简化了配置。spring-boot-starter-web 启用 Web 应用程序,包括经典应用程序和 RESTFul 应用程序。 spring-boot-starter-web-freemarker 是一个用于使用 Freemarker 模板引擎构建 Web 应用程序的 starter。它使用 Tomcat 作为默认的嵌入式容器。spring-boot-starter-data-jpa 是一个用于将 Spring Data JPA 与 Hibernate 一起使用的 starter。
server:
port: 8086
servlet:
context-path: /SpringBootRepository
spring:
main:
banner-mode: "off"
jpa:
database: h2
hibernate:
dialect: org.hibernate.dialect.H2Dialect
ddl-auto: create-drop
在 application.yml 文件中,我们编写了 Spring Boot 应用程序的各种配置设置。port 设置服务器端口,context-path 设置上下文路径(应用程序名称)。在这些设置之后,我们通过 localhost:8086/SpringBootRepository/ 访问应用程序。使用 banner-mode 属性,我们关闭 Spring banner。
JPA 的 database 值指定要操作的目标数据库。我们指定了 Hibernate 方言,在本例中为 org.hibernate.dialect.H2Dialect。ddl-auto 是数据定义语言模式;create-drop 选项自动创建和删除数据库模式。H2 数据库在内存中运行。
INSERT INTO countries(name, population) VALUES('China', 1382050000);
INSERT INTO countries(name, population) VALUES('India', 1313210000);
INSERT INTO countries(name, population) VALUES('USA', 324666000);
INSERT INTO countries(name, population) VALUES('Indonesia', 260581000);
INSERT INTO countries(name, population) VALUES('Brazil', 207221000);
INSERT INTO countries(name, population) VALUES('Pakistan', 196626000);
INSERT INTO countries(name, population) VALUES('Nigeria', 186988000);
INSERT INTO countries(name, population) VALUES('Bangladesh', 162099000);
INSERT INTO countries(name, population) VALUES('Nigeria', 186988000);
INSERT INTO countries(name, population) VALUES('Russia', 146838000);
INSERT INTO countries(name, population) VALUES('Japan', 126830000);
INSERT INTO countries(name, population) VALUES('Mexico', 122273000);
INSERT INTO countries(name, population) VALUES('Philippines', 103738000);
INSERT INTO countries(name, population) VALUES('Ethiopia', 101853000);
INSERT INTO countries(name, population) VALUES('Vietnam', 92700000);
INSERT INTO countries(name, population) VALUES('Egypt', 92641000);
INSERT INTO countries(name, population) VALUES('Germany', 82800000);
INSERT INTO countries(name, population) VALUES('the Congo', 82243000);
INSERT INTO countries(name, population) VALUES('Iran', 82800000);
INSERT INTO countries(name, population) VALUES('Turkey', 79814000);
INSERT INTO countries(name, population) VALUES('Thailand', 68147000);
INSERT INTO countries(name, population) VALUES('France', 66984000);
INSERT INTO countries(name, population) VALUES('United Kingdom', 60589000);
INSERT INTO countries(name, population) VALUES('South Africa', 55908000);
INSERT INTO countries(name, population) VALUES('Myanmar', 51446000);
INSERT INTO countries(name, population) VALUES('South Korea', 68147000);
INSERT INTO countries(name, population) VALUES('Colombia', 49129000);
INSERT INTO countries(name, population) VALUES('Kenya', 47251000);
INSERT INTO countries(name, population) VALUES('Spain', 46812000);
INSERT INTO countries(name, population) VALUES('Argentina', 43850000);
INSERT INTO countries(name, population) VALUES('Ukraine', 42603000);
INSERT INTO countries(name, population) VALUES('Sudan', 41176000);
INSERT INTO countries(name, population) VALUES('Algeria', 40400000);
INSERT INTO countries(name, population) VALUES('Poland', 38439000);
模式由 Hibernate 自动创建;之后,执行 import.sql 文件以填充表数据。
package com.zetcode.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.Objects;
@Entity
@Table(name = "countries")
public class Country {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int population;
public Country() {
}
public Country(Long id, String name, int population) {
this.id = id;
this.name = name;
this.population = population;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Country country = (Country) o;
return population == country.population &&
Objects.equals(id, country.id) &&
Objects.equals(name, country.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name, population);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Country{");
sb.append("id=").append(id);
sb.append(", name='").append(name).append('\'');
sb.append(", population=").append(population);
sb.append('}');
return sb.toString();
}
}
这是 Country 实体。每个实体都必须定义至少两个注解:@Entity 和 @Id。之前,我们将 ddl-auto 选项设置为 create-drop,这意味着 Hibernate 将从此实体创建表模式。
@Entity
@Table(name = "countries")
public class Country {
@Entity 注解指定该类是一个实体,并映射到一个数据库表。@Table 注解指定用于映射的数据库表的名称。
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
@Id 注解指定实体的主键,@GeneratedValue 为主键值提供生成策略。
package com.zetcode.repository;
import com.zetcode.model.Country;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CountryRepository extends CrudRepository<Country, Long> {
}
CountryRepository 使用 @Repository 注解进行修饰。
通过继承 Spring CrudRepository,我们为我们的数据存储库实现了一些方法,包括 findAll。这节省了一些样板代码。
package com.zetcode.service;
import com.zetcode.model.Country;
import java.util.List;
public interface ICountryService {
List<Country> findAll();
}
ICountryService 包含 findAll 契约方法。
package com.zetcode.service;
import com.zetcode.model.Country;
import com.zetcode.repository.CountryRepository;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CountryService implements ICountryService {
private final CountryRepository repository;
public CountryService(CountryRepository repository) {
this.repository = repository;
}
@Override
public List<Country> findAll() {
return (List<Country>) repository.findAll();
}
}
CountryService 包含 findAll 方法的实现。
private final CountryRepository repository;
public CountryService(CountryRepository repository) {
this.repository = repository;
}
CountryRepository 被注入。
@Override
public List<Country> findAll() {
return (List<Country>) repository.findAll();
}
findAll 方法返回数据库中所有国家/地区的列表。
package com.zetcode.controller;
import com.zetcode.model.Country;
import com.zetcode.service.ICountryService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.List;
@Controller
public class MyController {
private final ICountryService countryService;
public MyController(ICountryService countryService) {
this.countryService = countryService;
}
@GetMapping("/countries")
public ModelAndView getCountries() {
var countries = (List<Country>) countryService.findAll();
var params = new HashMap<String, Object>();
params.put("countries", countries);
return new ModelAndView("showCountries", params);
}
}
MyController 处理来自客户端的请求。
@Controller
public class MyController {
控制器使用 @Controller 注解进行注解。
private final ICountryService countryService;
public MyController(ICountryService countryService) {
this.countryService = countryService;
}
ICountryService 被注入到 countryService 属性中。
var countries = (List<Country>) countryService.findAll();
从服务对象中,我们使用 findAll 方法检索所有国家/地区。
var params = new HashMap<String, Object>();
params.put("countries", countries);
return new ModelAndView("showCountries", params);
处理被发送到 showCountries.ftlh 模板文件,以及国家/地区列表。
<!DOCTYPE html>
<html>
<head>
<title>Home page</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<p>
<a href="countries">Show countries</a>
</p>
</body>
</html>
这是主页。它包含一个获取所有国家/地区的链接。
<!DOCTYPE html>
<html>
<head>
<title>Show countries</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>List of countries</h2>
<table>
<tr>
<th>Id</th>
<th>Name</th>
<th>Population</th>
</tr>
<#list countries as country>
<tr>
<td>${country.id}</td>
<td>${country.name}</td>
<td>${country.population}</td>
</tr>
</#list>
</table>
</body>
</html>
这是 showCountries.ftlh 模板文件。使用 #list 指令,我们显示列表中的所有项目。
package com.zetcode;
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);
}
}
Application 是设置 Spring Boot 应用程序的入口点。@SpringBootApplication 注解启用自动配置和组件扫描。它是 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 注解的便捷注解。
$ ./gradlew bootRun
我们运行应用程序并导航到 localhost:8086/SpringBootRepository/。
在本文中,我们展示了如何在 Spring 应用程序中使用 @Repository 注解。