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
注解。