【Spring】Spring的模块架构与生态圈—数据访问与集成(JDBC、ORM、Transactions)

server/2024/12/22 9:14:11/

在企业级应用中,数据的存储和访问是核心功能之一。Java开发语言通过Spring框架提供了多种方式来实现数据访问和集成,包括JDBC(Java Database Connectivity)、ORM(对象关系映射)以及事务管理。这些技术的有效结合使得开发者能够更高效地与数据库进行交互,处理复杂的数据操作。

为什么需要数据访问与集成?

在实际开发中,数据访问是几乎所有应用程序的基础。例如,一个电商平台需要管理用户信息、商品信息、订单等数据。在这些场景中,开发者需要高效、可靠地与数据库进行交互。Spring提供的模块化解决方案使得数据访问更加简单和灵活,减少了繁琐的样板代码,提高了开发效率。

Spring数据访问的基本概念

  1. JDBC:Java Database Connectivity是Java用于连接和操作数据库的标准API。它提供了基本的数据库操作功能,如连接、查询和更新数据。

  2. ORM:对象关系映射是一种将对象模型与数据库表结构进行映射的技术。Spring支持多种ORM框架,如Hibernate、JPA(Java Persistence API)等。

  3. 事务管理:事务是一组操作的集合,要么全部成功,要么全部失败。Spring提供了声明式事务管理,简化了事务的处理。

Spring JDBC的使用

Spring JDBC提供了简化的JDBC操作接口,减少了样板代码。下面我们通过一个简单的示例来演示如何使用Spring JDBC进行数据访问。

1. 添加依赖

首先,在pom.xml中添加Spring JDBC的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope>
</dependency>

这里我们使用H2数据库作为内存数据库进行测试。

2. 配置数据源

application.properties中配置数据源:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
3. 创建数据模型

我们创建一个简单的用户模型User

public class User {private Long id;private String name;// Getters and Setterspublic Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
4. 创建DAO类

接下来,我们创建一个UserDao类,用于访问用户数据。

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
public class UserDao {private final JdbcTemplate jdbcTemplate;public UserDao(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}// 添加用户public void addUser(User user) {String sql = "INSERT INTO users (name) VALUES (?)";jdbcTemplate.update(sql, user.getName());}// 查询所有用户public List<User> getAllUsers() {String sql = "SELECT * FROM users";return jdbcTemplate.query(sql, (rs, rowNum) -> {User user = new User();user.setId(rs.getLong("id"));user.setName(rs.getString("name"));return user;});}
}

代码解释

  • @Repository注解表示该类是一个持久层组件。

  • JdbcTemplate是Spring提供的用于简化JDBC操作的类。

  • addUser方法使用jdbcTemplate.update执行插入操作。

  • getAllUsers方法使用jdbcTemplate.query查询所有用户,并将结果映射为User对象列表。

5. 创建数据库表

在应用启动时,我们需要创建数据库表。可以在@PostConstruct注解的方法中执行SQL语句。

import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;@Component
public class DatabaseInitializer {private final JdbcTemplate jdbcTemplate;public DatabaseInitializer(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@PostConstructpublic void init() {jdbcTemplate.execute("CREATE TABLE users (id BIGINT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255))");}
}
6. 测试DAO

我们创建一个测试类来验证我们的DAO是否正常工作。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class AppRunner implements CommandLineRunner {@Autowiredprivate UserDao userDao;@Overridepublic void run(String... args) throws Exception {User user = new User();user.setName("John Doe");userDao.addUser(user);System.out.println("All users:");userDao.getAllUsers().forEach(u -> System.out.println(u.getName()));}
}
7. 运行应用

运行Spring Boot应用后,控制台将输出:

All users:
John Doe

Spring ORM的使用

Spring还支持多种ORM框架,其中Hibernate是最常用的ORM框架之一。使用Hibernate可以更方便地处理对象与数据库之间的映射。

1. 添加依赖

pom.xml中添加Hibernate和JPA的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope>
</dependency>
2. 创建实体类

我们将User类修改为JPA实体类:

import javax.persistence.*;@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "name")private String name;// Getters and Setters// ...
}

代码解释

  • @Entity注解表示该类是一个JPA实体。

  • @Table注解指定数据库表名。

  • @Id@GeneratedValue注解用于定义主键和自增策略。

3. 创建Repository接口

创建一个UserRepository接口,继承JpaRepository

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
4. 使用Repository

我们在AppRunner中使用UserRepository来操作数据:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class AppRunner implements CommandLineRunner {@Autowiredprivate UserRepository userRepository;@Overridepublic void run(String... args) throws Exception {User user = new User();user.setName("Jane Doe");userRepository.save(user);System.out.println("All users:");userRepository.findAll().forEach(u -> System.out.println(u.getName()));}
}
5. 运行应用

运行Spring Boot应用后,控制台将输出:

All users:
Jane Doe

Spring事务管理

在数据访问中,事务管理是非常重要的,尤其是在涉及多个数据库操作时。Spring提供了声明式事务管理,简化了事务的处理。

1. 启用事务管理

在主应用类上添加@EnableTransactionManagement注解:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;@SpringBootApplication
@EnableTransactionManagement
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
2. 使用事务

我们可以在服务层的方法上使用@Transactional注解来声明事务:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Transactionalpublic void addUserWithTransaction(User user) {userRepository.save(user);// 其他操作,如果出现异常,事务会回滚}
}

总结

通过以上示例,我们了解了Spring在数据访问与集成方面的强大能力。Spring JDBC和ORM的结合使得数据操作变得简单和高效,而声明式事务管理则确保了数据的一致性和完整性。在实际开发中,合理地使用这些技术可以大大提高开发效率和代码质量。


http://www.ppmy.cn/server/152192.html

相关文章

WatchAlert - 开源多数据源告警引擎

概述 在现代 IT 环境中&#xff0c;监控和告警是确保系统稳定性和可靠性的关键环节。然而&#xff0c;随着业务规模的扩大和数据源的多样化&#xff0c;传统的单一数据源告警系统已经无法满足复杂的需求。为了解决这一问题&#xff0c;我开发了一个开源的多数据源告警引擎——…

Halcon单相机+机器人=眼在手上#标定心得

首先&#xff0c;这个标定板肯定是放在我们要作业的工作台上的 目的 **1&#xff0c;得到标定物&#xff08;工作台&#xff09;与机器人底座之间的pose转换关系。2&#xff0c;得到相机与机器人末端tool的的转换关系。 两个不确定的定量 1&#xff0c;标定板与机器人底座b…

Leetcode 三角形最小路径和

算法思想与代码详解 这段代码采用的是**动态规划&#xff08;Dynamic Programming&#xff09;**的思想&#xff0c;用来解决“120. 三角形最小路径和”问题。动态规划通过将问题分解成更小的子问题&#xff0c;并通过保存子问题的解来避免重复计算&#xff0c;从而提高效率。…

shiny数字输入框

在 Shiny 应用中&#xff0c;可以使用 numericInput 函数来创建一个数字输入框。numericInput 函数允许用户输入一个数值&#xff0c;并提供了多种选项来定制输入框的外观和行为。 在 Shiny 应用中使用 numericInput&#xff1f; 创建一个新的 Shiny 应用文件夹&#xff0c;并…

网络视频监控平台/安防监控/视频综合管理Liveweb视频汇聚平台解决方案

一、当前现状分析 当前视频资源面临以下问题&#xff1a; 1&#xff09;不同单位在视频平台建设中以所属领域为单位&#xff0c;设备品牌众多&#xff0c;存在的标准不一&#xff0c;各系统之间也没有统一标准&#xff1b; 2&#xff09;各单位视频平台建设分散、统筹性差&am…

Vue+element 回车查询页面刷新

问题描述&#xff1a; form 表单出查询条件需要实现 input 输入完成后键盘回车查询&#xff1a;keyup.enter“handleQuery”&#xff0c;如果 form 里只有一个input&#xff0c;回车没有触发事件&#xff0c;而是刷新页面&#xff0c;放两个input就没问题 问题原因&#xff1…

HarmonyOS(72)事件拦截处理详解

事件拦截 1、参考资料2、HitTestMode3、onTouchIntercept、onTouch、onClick事件执行顺序3.1、系统默认事件传递顺序3.2、子组件拦截事件1、参考资料 HarmonyOS(71) 自定义事件分发之TouchTestStrategy使用说明HarmonyOS(70) ArkUI 事件分发拦截,事件冲突解决方案HitTestModea…

【C++】sophus : sim3.hpp 描述了在 3D 空间中的缩放、旋转和平移 (十九)

sim3.hpp 文件定义了与 Sim(3) 群相关的类和操作。Sim(3) 群描述了在 3D 空间中的缩放、旋转和平移。以下是对该文件主要内容的总结&#xff1a; 主要类和命名空间 命名空间 Sophus Sophus 命名空间包含了与 Sim(3) 群相关的所有类和函数定义。 类模板 Sim3Base Sim3Base 是一个…