作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Stefan Varga
Verified Expert in Engineering
17 Years of Experience

Stefan是一名合格的软件开发人员,拥有计算机科学学位,在科技行业有近十年的经验.

Expertise

Share

人们常说Java太复杂,构建简单的应用程序需要花费太长时间. Nonetheless, Java提供了一个稳定的平台和一个非常成熟的生态系统, 这使得它成为开发健壮软件的绝佳选择.

Spring框架是众多强大的框架之一 Java ecosystem, 提供了一系列编程和配置模型,旨在简化Java中高性能和可测试应用程序的开发.

Spring Framework

In this tutorial, 我们将尝试构建一个简单的应用程序,作为数据库 software developers 使用Spring框架和Java持久化API (JPA).

应用程序遵循标准的MVC体系结构. 它将有一个控制器(ContractsController类), views (based on Thymeleaf templates), and a model (a Java map object). For the sake of simplicity, 在应用程序运行时,我们将使用JPA后面的内存数据库来持久化数据.

Spring框架入门教程

要构建一个基于Spring的应用程序,我们需要使用以下构建工具之一:

  • Maven
  • Gradle

In this tutorial, we will use Maven. 如果您对这两个工具中的任何一个都不熟悉,一个简单的入门方法是下载 Spring Tool Suite. 该套件专门用于Spring框架,并附带了自己的套件 Eclipse based IDE.

In Spring Tool Suite, we create a new project by selecting “Spring Starter Project” from under the “File > New” menu.

Spring Framework Tutorial

一旦创建了新项目,我们将需要编辑Maven配置文件。”pom.xml,并添加以下依赖项:


	org.springframework.boot
	spring-boot-starter-web


	org.springframework.boot
	spring-boot-starter-thymeleaf


	org.springframework.boot
	spring-boot-starter-data-jpa


	com.h2database
	h2


	org.springframework.data
	spring-data-commons

列出的这些依赖项将加载Spring Boot Web, Thymeleaf, JPA, 和H2(将作为我们的内存数据库). 所有必要的库将被自动拉出.

Entity Classes

能够存储有关开发人员及其技能的信息, 我们需要定义两个实体类:Developer” and “Skill”.

它们都被定义为带有一些注释的普通Java类. 通过在类之前添加“@Entity”,我们使它们的实例对JPA可用. 这将使在需要时更容易从持久数据存储中存储和检索实例. Additionally, “@Id”和“@GeneratedValue”注释允许我们为实体指定唯一的ID字段,并在存储在数据库中时自动生成其值.

As a developer can have many skills, 我们可以使用“@ manymany”注释定义一个简单的多对多关系.

Developer

@Entity
public class Developer {

	@Id
	= GenerationType @GeneratedValue(策略.AUTO)
	private long id;
	private String firstName;
	private String lastName;
	private String email;
	@ManyToMany
	private List skills;

	public Developer() {
		super();
	}

	public Developer(字符串firstName,字符串lastName,字符串email)
			List skills) {
		super();
		this.firstName = firstName;
		this.lastName = lastName;
		this.email = email;
		this.skills = skills;
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public List getSkills() {
		return skills;
	}

	public void setSkills(List skills) {
		this.skills = skills;
	}

	hashkill(技能技能){
		for (Skill containedSkill: getSkills()) {
			if (containedSkill.getId() == skill.getId()) {
				return true;
			}
		}
		return false;
	}

}

Skill

@Entity
public class Skill {
    @Id
    = GenerationType @GeneratedValue(策略.AUTO)
    private long id;
    private String label;
    private String description;

    public Skill() {
		super();
    }

    公共技能(字符串标签,字符串描述){
		super();
		this.label = label;
		this.description = description;
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		this.label = label;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(字符串描述){
		this.description = description;
	}
    
}

Repositories

使用JPA,我们可以定义一个非常有用的DeveloperRepository接口和SkillRepository接口, which allow for easy CRUD operations. 这些接口将允许我们通过简单的方法调用访问存储的开发人员和技能, such as:

  • “respository.findAll()”: returns all developers
  • “repository.findOne(id) ":返回具有给定id的开发人员

要创建这些接口,我们所需要做的就是扩展CrudRepository接口.

Developer Repository

public interface DeveloperRepository extends CrudRepository {

}

Skill Repository

public interface SkillRepository extends CrudRepository {
	public List findByLabel(String label);
}

附加方法的功能findByLabel ,将由JPA自动提供.

Controller

接下来,我们可以处理这个应用程序的控制器. 控制器将映射请求uri以查看模板,并在两者之间执行所有必要的处理.

@Controller
public class DevelopersController {

	@Autowired
	DeveloperRepository repository;

	@Autowired
	SkillRepository skillRepository;

	@RequestMapping("/developer/{id}")
	public String developer(@PathVariable Long id, Model Model) {
		model.addAttribute("developer", repository.findOne(id));
		model.addAttribute (skillRepository“技能”.findAll());
		return "developer";
	}

	@RequestMapping (value = " /开发人员”,方法= RequestMethod.GET)
	公共字符串developersList(模型模型){
		model.addAttribute("developers", repository.findAll());
		return "developers";
	}

	@RequestMapping (value = " /开发人员”,方法= RequestMethod.POST)
	public String developersAdd(@RequestParam String email) 
						@RequestParam String firstName, @RequestParam String lastName,模型模型){
		开发者newDeveloper =新开发者();
		newDeveloper.setEmail(email);
		newDeveloper.setFirstName(firstName);
		newDeveloper.setLastName(lastName);
		repository.save(newDeveloper);

		model.addAttribute(“开发人员”,newDeveloper);
		model.addAttribute (skillRepository“技能”.findAll());
		返回"redirect:/developer/" + newDeveloper.getId();
	}

	@RequestMapping (value = " /开发/ {id} /技能”,= RequestMethod方法.POST)
	公共字符串developersAddSkill(@PathVariable长id, @RequestParam长skilid,模型模型){
		Skill skill = skillRepository.findOne(skillId);
		Developer developer = repository.findOne(id);

		if (developer != null) {
			if (!developer.hasSkill(skill)) {
				developer.getSkills().add(skill);
			}
			repository.save(developer);
			model.addAttribute("developer", repository.findOne(id));
			model.addAttribute (skillRepository“技能”.findAll());
			返回"redirect:/developer/" + developer.getId();
		}

		model.addAttribute("developers", repository.findAll());
		return "redirect:/developers";
	}

}

uri到方法的映射是通过简单的“@RequestMapping”注释完成的. 在这种情况下,控制器的每个方法都映射到一个URI.

这些方法的模型参数允许将数据传递给视图. 本质上,这些是键到值的简单映射.

每个控制器方法返回要用作视图的thymleaf模板的名称, 或特定模式的URL (" redirect:”) to redirect to. For example, 方法" developer "和" _developersList_ "返回模板的名称, 而“developersAdd”和“developersAddSkill”返回要重定向到的url.

Within the controller, “@Autowired”注释会在相应的字段中自动分配我们定义的存储库的有效实例. 这允许从控制器内部访问相关数据,而无需处理大量样板代码.

Views

最后,我们需要为要生成的视图定义一些模板. 为此,我们使用Thymeleaf,一个简单的模板引擎. 我们在控制器方法中使用的模型可以直接在模板中使用.e. when we enter a contract into “contract的关键字,我们将能够访问名称字段为“合同.name” from within the template.

Thymeleaf包含一些控制HTML生成的特殊元素和属性. 它们非常直观和直接. For example, 用技能的名称填充span元素的内容, 您所需要做的就是定义以下属性(假设键“skill” is defined in the model):


Similarly to set the “href"锚元素的属性,特殊属性"th:href” can be used.

在我们的应用程序中,我们需要两个简单的模板. For clarity, 我们将跳过嵌入模板代码中的所有样式和类属性(即Bootstrap属性).

Developer List



 
	Developers database 
	


	

Developers

Name Skills
, view

First name:
Last name:
Email:

Developer Details




	Developer
	


	

Developer

Name:
Email:
Skills:
   -

Running the Server

Spring contains a boot module. 这使得我们可以很容易地从命令行启动服务器 a command line Java application:

@SpringBootApplication
应用程序实现CommandLineRunner {

    @Autowired
    DeveloperRepository DeveloperRepository;

    @Autowired
    SkillRepository skillRepository;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

因为我们使用的是内存数据库, 在启动时用一些预定义的数据引导数据库是有意义的. 这样,当服务器启动并运行时,数据库中至少会有一些数据.

@Override
public void run(String... args) throws Exception {
	技能javascript =新技能(“javascript”,“javascript语言技能”);
	技能ruby =新技能(“ruby”,“ruby语言技能”);
	技能emberjs =新技能(“emberjs”,“emberjs框架”);
	技能angularjs =新技能("angularjs", "angularjs框架");

	skillRepository.save(javascript);
	skillRepository.save(ruby);
	skillRepository.save(emberjs);
	skillRepository.save(angularjs);

	List developers = new LinkedList();
	developers.add(new Developer)(“John”,“Smith”,“John”).smith@example.com", 
			Arrays.asList(新技能[]{javascript, ruby}));
	developers.添加新的开发人员(“Mark”,“Johnson”,“mjohnson@example”).com", 
			Arrays.asList(new Skill[] {emberjs, ruby}));
	developers.add(new Developer)(“Michael”,“Williams”,“Michael .”).williams@example.com", 
			Arrays.asList(new Skill[] {angularjs, ruby}));
	developers.添加新的开发人员(“Fred”,“Miller”,“f”).miller@example.com", 
			Arrays.asList(new Skill[] {emberjs, angularjs, javascript}));
	developers.add(new Developer)(“Bob”,“Brown”,“brown@example .”).com", 
			Arrays.asList(new Skill[] { emberjs })));
	developerRepository.save(developers);
}

Conclusion

Spring是一个允许构建MVC应用程序的通用框架. 用Spring构建一个简单的应用程序既快速又透明. 应用程序还可以使用JPA轻松地与数据库集成.

整个项目的源代码是 available on GitHub.

Hire a Toptal expert on this topic.
Hire Now
Stefan Varga

Stefan Varga

Verified Expert in Engineering
17 Years of Experience

布拉迪斯拉发,布拉迪斯拉发地区,斯洛伐克

Member since March 5, 2015

About the author

Stefan是一名合格的软件开发人员,拥有计算机科学学位,在科技行业有近十年的经验.

作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Expertise

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 privacy policy.

世界级的文章,每周发一次.

输入您的电子邮件,即表示您同意我们的 privacy policy.

Toptal Developers

Join the Toptal® community.