首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Spring JdbcTemplate query 完整用法:RowMapper 實作、參數綁定與最佳實踐

     編輯:Java 綜合教學

核心 API

JdbcTemplate.query(String sql, Object[] args, RowMapper<T> rowMapper) 是查詢多筆資料並映射為物件列表的標準方法。

完整實作範例

@Repository
public class TaskDaoImpl implements TaskDao {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Override
    public List findTaskList(int flag, int limit, int max) {
        String sql = "SELECT t.* FROM task t WHERE t.flag = ? LIMIT ?, ?";
        
        // 參數綁定 (防止 SQL 注入)
        Object[] params = new Object[] { flag, limit, max };
        
        // 執行查詢並映射
        List taskList = jdbcTemplate.query(sql, params, new RowMapper() {
            @Override
            public Task mapRow(ResultSet rs, int rowNum) throws SQLException {
                Task task = new Task();
                task.setId(rs.getLong("id"));
                task.setWorkorderid(rs.getInt("workorderid"));
                task.setFlag(rs.getInt("flag"));
                // 其他欄位...
                return task;
            }
        });
        
        return taskList;
    }
}

RowMapper 實作模式比較

1. 匿名內部類 (傳統)

new RowMapper() {
    @Override public Task mapRow(ResultSet rs, int rowNum) throws SQLException {
        Task t = new Task();
        t.setId(rs.getLong("id"));
        // ...
        return t;
    }
}

2. Lambda 表達式 (Java 8+ 推薦)

(rs, rowNum) -> {
    Task t = new Task();
    t.setId(rs.getLong("id"));
    t.setWorkorderid(rs.getInt("workorderid"));
    t.setFlag(rs.getInt("flag"));
    return t;
}

3. 獨立類別 (複用、測試友善)

public class TaskRowMapper implements RowMapper {
    @Override
    public Task mapRow(ResultSet rs, int rowNum) throws SQLException {
        Task task = new Task();
        task.setId(rs.getLong("id"));
        task.setWorkorderid(rs.getInt("workorderid"));
        task.setFlag(rs.getInt("flag"));
        return task;
    }
}

// 使用
jdbcTemplate.query(sql, params, new TaskRowMapper());

4. BeanPropertyRowMapper (自動映射,慎用)

// 需資料庫欄位名與 Java 屬性名完全對應 (駝峰/下劃線)
jdbcTemplate.query(sql, params, new BeanPropertyRowMapper<>(Task.class));

參數綁定最佳實踐

方式範例適用場景
Object[] 陣列new Object[]{flag, limit, max}固定參數數量、簡單查詢
List 轉陣列params.toArray()動態構建參數
MapSqlParameterSourcenew MapSqlParameterSource().addValue("flag", flag)命名參數 (需 NamedParameterJdbcTemplate)
PreparedStatementSetterps -> { ps.setInt(1, flag); ... }複雜型別 (Blob, Clob, Array 等)

常見查詢變體

查詢單筆 (queryForObject)

Task task = jdbcTemplate.queryForObject(
    "SELECT * FROM task WHERE id = ?", 
    new Object[]{id}, 
    new TaskRowMapper()
);

查詢標量值 (queryForObject)


分頁查詢 (MySQL LIMIT)


異常處理與交易

  • EmptyResultDataAccessException:queryForObject 查無資料時拋出
  • DataAccessException:Spring 統一資料存取異常體系,非檢查型異常
  • 搭配 @Transactional 進行交易管理

效能優化建議

  1. 使用連線池:HikariCP (Spring Boot 預設)
  2. 批次操作:batchUpdate 大量寫入
  3. Fetch Size:大結果集設定 jdbcTemplate.setFetchSize(1000)
  4. 避免 SELECT *:明確列出欄位,減少網路傳輸
  5. 索引優化:WHERE/ORDER BY/JOIN 欄位建立索引

Spring Boot 整合配置

# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5

# 自動注入 JdbcTemplate,無需額外配置
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved