首页 > 编程语言 >使用 Spring 框架构建 MVC 应用程序:初学者教程

使用 Spring 框架构建 MVC 应用程序:初学者教程

时间:2024-10-16 15:11:01浏览次数:1  
标签:String Spring id MVC 初学者 new Skill public Developer

Spring Framework 是一个功能强大、功能丰富且设计精良的 Java 平台框架。它提供了一系列编程和配置模型,旨在简化和精简 Java 中健壮且可测试的应用程序的开发过程。

人们常说 Java 太复杂了,构建简单的应用程序需要很长时间。尽管如此,Java 提供了一个稳定的平台,周围有一个非常成熟的生态系统,这使其成为开发强大软件的绝佳选择。

Spring FrameworkJava 生态系统中众多强大的框架之一,它附带了一系列编程和配置模型,旨在简化 Java 中高性能和可测试应用程序的开发。

![image-20241015212521538](/Users/gongweiming/Library/Application Support/typora-user-images/image-20241015212521538.png)

在本教程中,我们将接受构建一个简单的应用程序的挑战,该应用程序将SpringMVC充分使用起来。

Spring Framework 教程入门

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

  • Maven 相关
  • Gradle 相关

在 Spring Tool Suite 中,我们通过从“File > New”菜单下选择“Spring Starter Project”来创建一个新项目。

![image-20241015212714756](/Users/gongweiming/Library/Application Support/typora-user-images/image-20241015212714756.png)

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

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</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-data-jpa</artifactId>
</dependency>
<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-commons</artifactId>
</dependency>

这些列出的依赖项将加载 Spring Boot WebThymeleafJPA H2(将用作我们的内存数据库)。所有必要的库都将自动拉取。

实体类

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

这两个类都被定义为带有一些注解的普通 Java 类。通过在类之前添加@Entity,我们可以将它们的实例提供给 JPA。这将使在需要时从持久性数据存储中存储和检索实例变得更加容易。此外,@Id@GeneratedValue注释允许我们指示实体的唯一 ID 字段,并在存储在数据库中时自动生成其值。

由于开发人员可以拥有许多技能,因此我们可以使用 “@ManyToMany” 注解定义一个简单的多对多关系。

Developer 开发 人员

@Entity
public class Developer {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private long id;
	private String firstName;
	private String lastName;
	private String email;
	@ManyToMany
	private List<Skill> skills;

	public Developer() {
		super();
	}

	public Developer(String firstName, String lastName, String email,
			List<Skill> 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<Skill> getSkills() {
		return skills;
	}

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

	public boolean hasSkill(Skill skill) {
		for (Skill containedSkill: getSkills()) {
			if (containedSkill.getId() == skill.getId()) {
				return true;
			}
		}
		return false;
	}

}

Skill 技能

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

    public Skill() {
		super();
    }

    public Skill(String label, String description) {
		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(String description) {
		this.description = description;
	}
    
}

Repositories 存储库

用 JPA,我们可以定义一个非常有用的 Developer Repository 接口和 SkillRepository 接口,它们允许简单的 CRUD 操作。这些接口将允许我们通过简单的方法调用访问存储的开发人员和技能,例如:

  • respository.findAll():返回所有开发人员
  • repository.findOne(id):返回具有给定 ID 的开发人员

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

Developer Repository 开发人员存储库

public interface DeveloperRepository extends CrudRepository<Developer, Long> {

}

Skill Repository 技能仓库

public interface SkillRepository extends CrudRepository<Skill, Long> {
	public List<Skill> 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("skills", skillRepository.findAll());
		return "developer";
	}

	@RequestMapping(value="/developers",method=RequestMethod.GET)
	public String developersList(Model model) {
		model.addAttribute("developers", repository.findAll());
		return "developers";
	}

	@RequestMapping(value="/developers",method=RequestMethod.POST)
	public String developersAdd(@RequestParam String email, 
						@RequestParam String firstName, @RequestParam String lastName, Model model) {
		Developer newDeveloper = new Developer();
		newDeveloper.setEmail(email);
		newDeveloper.setFirstName(firstName);
		newDeveloper.setLastName(lastName);
		repository.save(newDeveloper);

		model.addAttribute("developer", newDeveloper);
		model.addAttribute("skills", skillRepository.findAll());
		return "redirect:/developer/" + newDeveloper.getId();
	}

	@RequestMapping(value="/developer/{id}/skills", method=RequestMethod.POST)
	public String developersAddSkill(@PathVariable Long id, @RequestParam Long skillId, Model model) {
		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("skills", skillRepository.findAll());
			return "redirect:/developer/" + developer.getId();
		}

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

}

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

这些方法的 model 参数允许将数据传递到视图。从本质上讲,这些是键到值的简单映射。

每个控制器方法要么返回要用作视图的 Thymeleaf 模板的名称,要么返回要重定向到的特定模式(redirect:)的 URL。例如,方法 developer_developersList_ 返回模板的名称,而 developersAdddevelopersAddSkill 返回要重定向到的 URL。

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

Views 视图

最后,我们需要为要生成的视图定义一些模板。为此,我们使用了 Thymeleaf,一个简单的模板引擎。我们在控制器方法中使用的模型可以直接在模板中使用,即当我们在模型的 contract” 键中输入合约时,我们将能够从模板中以 “contract.name” 的形式访问 name 字段。

Thymeleaf 包含一些控制 HTML 生成的特殊元素和属性。他们非常直观和直接。例如,要使用技能名称填充 span 元素的内容,您只需定义以下属性(假设在模型中定义了键“skill”):

<span th:text="${skill.label}"></span>

与设置锚点元素的 href 属性类似,可以使用特殊属性 *th:href

在我们的应用程序中,我们需要两个简单的模板。为清楚起见,我们将在嵌入式模板代码中跳过所有 style 和 class 属性(即 Bootstrap 属性)。

Developer List 开发者名单

![image-20241015213159202](/Users/gongweiming/Library/Application Support/typora-user-images/image-20241015213159202.png)

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head> 
	<title>Developers database</title> 
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Developers</h1>
	<table>
		<tr>
			<th>Name</th>
			<th>Skills</th>
			<th></th>
		</tr>
		<tr th:each="developer : ${developers}">
			<td th:text="${developer.firstName + ' ' + developer.lastName}"></td>
			<td>
				<span th:each="skill,iterStat : ${developer.skills}">
					<span th:text="${skill.label}"/><th:block th:if="${!iterStat.last}">,</th:block>
				</span>
			</td>
			<td>
				<a th:href="@{/developer/{id}(id=${developer.id})}">view</a>
			</td>
		</tr>
	</table>
	<hr/>
	<form th:action="@{/developers}" method="post" enctype="multipart/form-data">
		<div>
			First name: <input name="firstName" />
		</div>
		<div>
			Last name: <input name="lastName" />
		</div>
		<div>
			Email: <input name="email" />
		</div>
		<div>
			<input type="submit" value="Create developer" name="button"/>
		</div>
	</form>
</body>
</html>

Developer Details 开发者详情

![image-20241015213228888](/Users/gongweiming/Library/Application Support/typora-user-images/image-20241015213228888.png)

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<title>Developer</title>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
	<h1>Developer</h1>
	Name: <b th:text="${developer.firstName}" /> <b th:text="${developer.lastName}" /><br/>
	Email: <span th:text="${developer.email}" /><br/>
	Skills:
		<span th:each="skill : ${developer.skills}">
			<br/>&nbsp;&nbsp;<span th:text="${skill.label}" /> - <span th:text="${skill.description}" />
		</span>
	<form th:action="@{/developer/{id}/skills(id=${developer.id})}" method="post" enctype="multipart/form-data" >
		<select name="skillId">
			<option th:each="skill : ${skills}" 
				th:value="${skill.id}" 
				th:text="${skill.description}">Skill</option>
		</select>
		<input type="submit" value="Add skill"/>
	</form>
</body>
</html>

启动服务器

Spring 包含一个 boot 模块。这允许我们轻松地从命令行作为命令行 Java 应用程序启动服务器:

@SpringBootApplication
public class Application implements 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 {
	Skill javascript = new Skill("javascript", "Javascript language skill");
	Skill ruby = new Skill("ruby", "Ruby language skill");
	Skill emberjs = new Skill("emberjs", "Emberjs framework");
	Skill angularjs = new Skill("angularjs", "Angularjs framework");

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

	List<Developer> developers = new LinkedList<Developer>();
	developers.add(new Developer("John", "Smith", "[email protected]", 
			Arrays.asList(new Skill[] { javascript, ruby })));
	developers.add(new Developer("Mark", "Johnson", "[email protected]", 
			Arrays.asList(new Skill[] { emberjs, ruby })));
	developers.add(new Developer("Michael", "Williams", "[email protected]", 
			Arrays.asList(new Skill[] { angularjs, ruby })));
	developers.add(new Developer("Fred", "Miller", "[email protected]", 
			Arrays.asList(new Skill[] { emberjs, angularjs, javascript })));
	developers.add(new Developer("Bob", "Brown", "[email protected]", 
			Arrays.asList(new Skill[] { emberjs })));
	developerRepository.save(developers);
}

总结

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

GitHub 该篇文章中使用到Demo源码整个项目的源代码。

标签:String,Spring,id,MVC,初学者,new,Skill,public,Developer
From: https://www.cnblogs.com/gongwm/p/18469974

相关文章

  • SpringBoot+mail 轻松实现各类邮件自动推送
    在实际的项目开发过程中,经常需要用到邮件通知功能。例如,通过邮箱注册,邮箱找回密码,邮箱推送报表等等,实际的应用场景非常的多。早期的时候,为了能实现邮件的自动发送功能,通常会使用JavaMail相关的api来完成。后来Spring推出的JavaMailSender工具,进一步简化了邮件的自动发送......
  • 基于SpringBoot+Vue的校园周边美食探索及分享平台的设计与实现(带文档)
    基于SpringBoot+Vue的校园周边美食探索及分享平台的设计与实现(带文档)开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue等工具:IDEA/Ecilpse、Navicat、Maven源码校园周边美食探索及分享平台是一个旨在为校园用户提供便捷的美食发现和分享服务的系统。该平台通过现......
  • 支付宝沙箱版(什么是支付宝沙箱、配置支付宝沙箱、配置内网穿透、在SpringBoot项目中对
    文章目录0.前言1.什么是支付宝沙箱2.配置支付宝沙箱2.1沙箱应用的应用信息(获取app-id和gateway-url)2.2沙箱账号的商家信息和买家信息2.3下载秘钥工具2.4生成秘钥(获取private-key)2.5配置秘钥(获取alipay-public-key)3.配置内网穿透3.1使用cpolar实现内网穿透3.2......
  • java毕业设计-基于Springboot的社区医疗服务可视化系统【d代码+论文+PPT】
    全文内容包括:1、采用技术;2、系统功能;3、系统截图;4、部分代码;5、配套内容。索取方式见文末微信号,欢迎关注收藏!一、采用技术语言:Java1.8框架:Springboot数据库:MySQL5.7、8.0开发工具:IntelliJIDEA旗舰版其他:Maven3.8以上二、系统功能管理员管理:负责系统后台维护,确保运行......
  • Spring Boot框架的大创项目进度跟踪系统
    5系统详细实现5.1管理员模块的实现5.1.1项目中检管理大创管理系统的系统管理员可以管理项目中检,可以对项目中检信息添加修改删除以及查询操作。具体界面的展示如图5.1所示。图5.1项目中检信息管理界面5.1.2专家评审管理系统管理员可以查看对专家评审信息进行添加......
  • spring上 -基于注解配置bean,动态代理,AOP笔记
     用的是jdk8,spring框架里jar包的下载可以自己搜到注解用到的jar包。  60,注解配置Bean快速入门 基本介绍 代码结构: UserDao.javapackagecom.hspedu.spring.component;importorg.springframework.stereotype.Repository;/**使用@Repository标识该......
  • springboot超市商品管理系统-计算机毕业设计源码55289
    摘 要随着信息技术的快速发展和普及,传统的超市管理模式已经无法满足现代商业的需求。为了提高超市的管理效率,优化商品销售流程,本文提出了一种基于SpringBoot框架的超市商品管理系统。该系统结合了现代软件开发技术,包括MySQL数据库、Java语言等,实现了对超市商品的全面管理。......
  • springboot社区团购系统-计算机毕业设计源码50782
    摘要随着互联网技术的不断发展和普及,社区团购作为一种新型的互联网零售模式,已经成为了人们越来越喜欢的购物方式之一。社区团购系统是支撑社区团购业务的重要基础设施,其功能和性能的好坏直接影响到社区团购业务的发展和用户体验。本论文研究了社区团购系统的需求分析、系统实......
  • springboot校园运动会管理系统-计算机毕业设计源码94492
    摘要校园运动会作为学校重要的体育活动之一,对于促进学生身心健康、增强团队合作意识具有重要意义。为了更好地组织和管理校园运动会,开发了基于SpringBoot的校园运动会管理系统。该系统旨在整合现代信息技术,提高运动会的组织效率和参与体验。通过该系统,学校可以方便地进行运......
  • 体检预约毕业设计社区体检管理网站预约排号基于SpringBootSSM框架
    目录1、项目概述‌1.1开发背景‌2、技术选择2.1IDEA开发工具2.2SpringBoot框架‌3需求分析3.1功能模块设计‌3.2非功能需求‌‌4、数据库设计‌‌5、界面设计‌‌6、安全性设计‌1、项目概述‌随着社区居民健康意识的不断提升,体检服务的需求也日益增长。然......