溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot 中怎么利用JdbcTemplate操作數據庫

發布時間:2021-07-14 16:59:08 來源:億速云 閱讀:248 作者:Leah 欄目:編程語言
# SpringBoot 中怎么利用JdbcTemplate操作數據庫

## 一、JdbcTemplate 概述

### 1.1 什么是 JdbcTemplate
JdbcTemplate 是 Spring 框架提供的一個核心 JDBC 工具類,它封裝了原生 JDBC API 的復雜操作,提供了更簡潔的數據庫訪問方式。主要特點包括:

- 自動管理資源(Connection/Statement/ResultSet)
- 簡化異常處理(將檢查異常轉換為運行時異常)
- 提供豐富的 CRUD 操作方法
- 支持命名參數和預編譯語句

### 1.2 與 MyBatis/JPA 的對比
| 特性          | JdbcTemplate       | MyBatis            | JPA/Hibernate      |
|--------------|--------------------|--------------------|--------------------|
| 學習曲線       | 低                 | 中                 | 高                 |
| 靈活性        | 極高               | 高                 | 中                 |
| 自動化程度     | 低(手動寫SQL)     | 中(XML/注解)      | 高(自動生成SQL)   |
| 適用場景       | 簡單CRUD/復雜SQL   | 復雜SQL映射        | 對象關系映射       |

## 二、SpringBoot 集成 JdbcTemplate

### 2.1 添加依賴
在 `pom.xml` 中添加 starter 和數據庫驅動:

```xml
<dependencies>
    <!-- Spring Boot JDBC  starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    
    <!-- 數據庫驅動(以MySQL為例) -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>
</dependencies>

2.2 配置數據源

application.yml 配置示例:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    # HikariCP 連接池配置(默認)
    hikari:
      maximum-pool-size: 10
      minimum-idle: 5
      connection-timeout: 30000

三、基礎 CRUD 操作

3.1 初始化 JdbcTemplate

通過構造器注入:

@Repository
public class UserDaoImpl implements UserDao {
    
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public UserDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}

3.2 插入數據

public int insert(User user) {
    String sql = "INSERT INTO user(name, age, email) VALUES(?, ?, ?)";
    return jdbcTemplate.update(
        sql, 
        user.getName(), 
        user.getAge(), 
        user.getEmail()
    );
}

// 批量插入
public int[] batchInsert(List<User> users) {
    String sql = "INSERT INTO user(name, age, email) VALUES(?, ?, ?)";
    return jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
            User user = users.get(i);
            ps.setString(1, user.getName());
            ps.setInt(2, user.getAge());
            ps.setString(3, user.getEmail());
        }
        
        @Override
        public int getBatchSize() {
            return users.size();
        }
    });
}

3.3 查詢操作

查詢單條記錄

public User getById(Long id) {
    String sql = "SELECT * FROM user WHERE id = ?";
    return jdbcTemplate.queryForObject(sql, new Object[]{id}, (rs, rowNum) -> {
        User user = new User();
        user.setId(rs.getLong("id"));
        user.setName(rs.getString("name"));
        user.setAge(rs.getInt("age"));
        user.setEmail(rs.getString("email"));
        return user;
    });
}

查詢列表

public List<User> listAll() {
    String sql = "SELECT * FROM user";
    return jdbcTemplate.query(sql, (rs, rowNum) -> {
        User user = new User();
        user.setId(rs.getLong("id"));
        // 其他字段設置...
        return user;
    });
}

查詢單個值

public int countUsers() {
    String sql = "SELECT COUNT(*) FROM user";
    return jdbcTemplate.queryForObject(sql, Integer.class);
}

3.4 更新與刪除

// 更新
public int update(User user) {
    String sql = "UPDATE user SET name=?, age=?, email=? WHERE id=?";
    return jdbcTemplate.update(
        sql, 
        user.getName(),
        user.getAge(),
        user.getEmail(),
        user.getId()
    );
}

// 刪除
public int delete(Long id) {
    String sql = "DELETE FROM user WHERE id=?";
    return jdbcTemplate.update(sql, id);
}

四、高級功能

4.1 命名參數

使用 NamedParameterJdbcTemplate

@Autowired
private NamedParameterJdbcTemplate namedJdbcTemplate;

public User getByName(String name) {
    String sql = "SELECT * FROM user WHERE name = :name";
    Map<String, Object> params = new HashMap<>();
    params.put("name", name);
    
    return namedJdbcTemplate.queryForObject(sql, params, (rs, rowNum) -> {
        // 對象映射...
    });
}

4.2 存儲過程調用

public void callProcedure() {
    jdbcTemplate.execute("{call update_user_status(?, ?)}", 
        (CallableStatementCallback<Void>) cs -> {
            cs.setLong(1, 1001L);
            cs.registerOutParameter(2, Types.INTEGER);
            cs.execute();
            log.info("Out parameter: {}", cs.getInt(2));
            return null;
        });
}

4.3 事務管理

在 Service 層添加 @Transactional

@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserDao userDao;
    
    public void transferBalance(Long fromId, Long toId, BigDecimal amount) {
        userDao.deductBalance(fromId, amount);
        // 模擬業務異常
        if (amount.compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("金額不能為負");
        }
        userDao.addBalance(toId, amount);
    }
}

五、最佳實踐

5.1 SQL 管理建議

  1. 將 SQL 語句集中管理(如 sql.properties 或常量類)
  2. 復雜 SQL 使用 MyBatis 更合適
  3. 動態 SQL 可使用 StringBuilder 或 JOOQ

5.2 性能優化

// 1. 使用預編譯語句
jdbcTemplate.setFetchSize(100); // 設置批量獲取大小

// 2. 結果集處理優化
jdbcTemplate.query(sql, new ResultSetExtractor<List<User>>() {
    @Override
    public List<User> extractData(ResultSet rs) throws SQLException {
        // 自定義高效處理邏輯
    }
});

// 3. 連接池配置
spring.datasource.hikari.maximum-pool-size=20

5.3 異常處理

try {
    jdbcTemplate.update("INSERT...");
} catch (DuplicateKeyException e) {
    // 處理唯一鍵沖突
} catch (DataAccessException e) {
    // 處理其他數據庫異常
}

六、完整示例

6.1 DAO 層實現

@Repository
public class UserDaoImpl implements UserDao {
    
    private static final String INSERT_SQL = "INSERT...";
    private static final String SELECT_BY_ID_SQL = "SELECT...";
    
    private final JdbcTemplate jdbcTemplate;

    @Override
    public List<User> findByAgeGreaterThan(int age) {
        return jdbcTemplate.query(
            "SELECT * FROM user WHERE age > ? ORDER BY name",
            new BeanPropertyRowMapper<>(User.class),
            age
        );
    }
}

6.2 單元測試

@SpringBootTest
class UserDaoTest {
    
    @Autowired
    private UserDao userDao;
    
    @Test
    @Transactional // 測試后自動回滾
    void testInsert() {
        User user = new User("test", 25, "test@example.com");
        int affected = userDao.insert(user);
        assertEquals(1, affected);
    }
}

總結

JdbcTemplate 在 SpringBoot 中的優勢: - 輕量級,無額外學習成本 - 適合簡單CRUD和存儲過程調用 - 與 Spring 生態完美集成

適用場景建議: - 小型項目或微服務中的簡單數據訪問 - 需要執行原生SQL的復雜查詢 - 與其他ORM框架混合使用 “`

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女