## 6. 数据库访问 参考[jdbc(ppt)](./resources/JDBC.pptx) ### 6.1 JDBC(掌握) #### 6.1.1 什么是JDBC? - **定义**: JDBC (Java Database Connectivity) 是Java中用于连接和操作关系型数据库的标准API。 - **用途**: JDBC允许Java应用程序与各种关系型数据库进行交互,包括执行SQL语句、处理查询结果等。 - **优势**: 提供了一个统一的接口,使得开发者可以使用相同的API来操作不同的数据库。 #### 6.1.2 JDBC常用API - **Driver接口**: 定义了数据库驱动必须实现的方法。 - **DriverManager类**: 提供了加载驱动、获取数据库连接等静态方法。 - **Connection接口**: 代表与数据库的连接,用于创建Statement对象。 - **Statement接口**: 用于发送SQL语句到数据库。 - **PreparedStatement接口**: 继承自Statement,用于预编译SQL语句并设置参数。 - **ResultSet接口**: 用于处理查询结果。 - **SQLException类**: JDBC中所有异常的基类,用于表示数据库访问过程中出现的问题。 #### 6.1.3 实现第一个JDBC程序 下面是一个使用JDBC API操作数据库的例子: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class JdbcCrudExample { private static final String DB_URL = "jdbc:mysql://localhost:3306/mydatabase"; private static final String USER = "root"; private static final String PASS = "password"; public static void main(String[] args) { Connection conn = null; try { // 加载MySQL驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 获取数据库连接 conn = DriverManager.getConnection(DB_URL, USER, PASS); // 创建表 createTable(conn); // 插入记录 insertUser(conn, "Alice", 28); insertUser(conn, "Bob", 32); // 查询记录 queryUsers(conn); // 更新记录 updateUser(conn, "Alice", 29); // 删除记录 deleteUser(conn, "Bob"); // 再次查询记录 queryUsers(conn); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } private static void createTable(Connection conn) throws SQLException { String sql = "CREATE TABLE IF NOT EXISTS users (" + "id INT AUTO_INCREMENT PRIMARY KEY," + "name VARCHAR(255) NOT NULL," + "age INT)"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.executeUpdate(); stmt.close(); } private static void insertUser(Connection conn, String name, int age) throws SQLException { String sql = "INSERT INTO users (name, age) VALUES (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); pstmt.setInt(2, age); pstmt.executeUpdate(); pstmt.close(); } private static void queryUsers(Connection conn) throws SQLException { String sql = "SELECT * FROM users"; PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age); } rs.close(); pstmt.close(); } private static void updateUser(Connection conn, String name, int age) throws SQLException { String sql = "UPDATE users SET age = ? WHERE name = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, age); pstmt.setString(2, name); int rowsUpdated = pstmt.executeUpdate(); System.out.println(rowsUpdated + " row(s) updated."); pstmt.close(); } private static void deleteUser(Connection conn, String name) throws SQLException { String sql = "DELETE FROM users WHERE name = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); int rowsDeleted = pstmt.executeUpdate(); System.out.println(rowsDeleted + " row(s) deleted."); pstmt.close(); } } ``` ### 6.2 数据库连接池(了解) #### 6.2.1 什么是数据库连接池? - **定义**: 数据库连接池是一种管理数据库连接的技术,用于提高性能和减少资源消耗。 - **优势**: 减少了创建和销毁连接的开销,提高了应用程序的响应速度。 #### 6.2.2 DataSource接口 - **定义**: JDBC 4.0 引入的`javax.sql.DataSource`接口,用于创建数据库连接池。 - **使用**: 通过`getConnection()`方法获取连接。 #### 6.2.3 常见数据库连接池实现 - **Apache Commons DBCP**: 早期的数据库连接池实现。 - **C3P0**: 一个免费的开源连接池实现。 - **HikariCP**: 一个高性能的数据库连接池实现。 - **DBUtils**: 一个轻量级的数据库工具类,支持连接池管理。 #### 6.2.4 使用HikariCP实现数据库连接池 - **配置**: 设置连接池的参数。 ```java HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase"); config.setUsername("username"); config.setPassword("password"); config.setMaximumPoolSize(10); config.setConnectionTimeout(30000); ``` - **创建连接池**: ```java HikariDataSource ds = new HikariDataSource(config); ``` - **获取连接**: ```java Connection conn = ds.getConnection(); ``` ### 6.3 SQL注入的预防措施(掌握) - **定义**: SQL注入是一种常见的安全攻击,通过在SQL语句中插入恶意代码来破坏数据库。 - **预防**: 使用预编译语句(PreparedStatement)来防止SQL注入。 - **创建PreparedStatement对象**: ```java PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users WHERE name = ?"); pstmt.setString(1, "John Doe"); ``` - **执行SQL查询**: ```java ResultSet rs = pstmt.executeQuery(); ``` ### 6.4 事务管理(了解) #### 6.4.1 事务管理的基本概念 在计算机科学中,特别是在数据库管理和分布式计算领域,事务(Transaction)是一种基本的操作单位,它确保了一系列操作要么全部成功,要么全部失败。事务的概念是数据库管理系统(DBMS)中用来保证数据完整性和一致性的重要机制之一。 事务具有以下几个核心特点,通常称为ACID属性 - **原子性 (Atomicity)**: 事务中的所有操作要么全部完成,要么一个也不完成。 - **一致性 (Consistency)**: 事务的执行不会破坏数据的一致性。 - **隔离性 (Isolation)**: 事务之间是隔离的,不会相互影响。 - **持久性 (Durability)**: 一旦事务提交,它的效果是持久的。 #### 6.4.2 Spring事务管理器 - **定义**: Spring提供了多种事务管理器,如`DataSourceTransactionManager`。 - **示例**: ```java @Configuration @EnableTransactionManagement public class AppConfig { @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } } ``` #### 6.4.3 使用@Transactional进行声明式事务管理 - **定义**: 使用@Transactional注解来声明式地管理事务,简化了事务控制代码。 - **示例**: ```java @Service @Transactional public class UserService { private final UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void createUser(User user) { userRepository.save(user); } } ``` #### 6.4.4 使用编程式事务管理 - **定义**: 通过编程的方式显式地管理事务,适用于需要更细粒度控制事务的情况。 - **示例**: ```java @Service public class UserService { private final UserRepository userRepository; private final PlatformTransactionManager transactionManager; @Autowired public UserService(UserRepository userRepository, PlatformTransactionManager transactionManager) { this.userRepository = userRepository; this.transactionManager = transactionManager; } public void createUser(User user) { TransactionDefinition def = new DefaultTransactionDefinition(); TransactionStatus status = transactionManager.getTransaction(def); try { userRepository.save(user); transactionManager.commit(status); } catch (Exception e) { transactionManager.rollback(status); throw e; } } } ``` ### 6.5 ORM(了解) #### 6.5.1 ORM基本概念 - **定义**: ORM (Object-Relational Mapping) 是一种编程技术,用于将对象模型映射到关系型数据库模型。 - **目的**: 简化数据库操作,提高开发效率。 #### 6.5.2 常见ORM框架介绍 - **JPA (Java Persistence API)** - **定义**: JPA 是Java EE标准的一部分,提供了一种对象持久化机制。 - **特点**: 支持实体管理和生命周期管理。 - **Hibernate** - **定义**: Hibernate 是一个流行的ORM框架,实现了JPA规范。 - **特点**: 提供了强大的映射能力和缓存机制。 - **MyBatis** - **定义**: MyBatis 是一个半自动的ORM框架,提供了SQL查询的灵活性。 - **特点**: 支持动态SQL和存储过程。 ### 6.6 NoSQL数据库(了解) #### 6.6.1 MongoDB介绍 - **定义**: MongoDB 是一个文档型NoSQL数据库,使用JSON-like文档存储数据。 - **特点**: 高性能、高可用性、易于水平扩展。 #### 6.6.2 Redis介绍 - **定义**: Redis 是一个开源的键值存储系统,支持多种数据结构。 - **特点**: 高性能、低延迟、持久化支持。 - **使用**: 存储会话数据、缓存、计数器等。