SpringBoot 中怎么利用JdbcTemplate操作数据库

发布时间:2021-07-14 16:59:08 作者:Leah
来源:亿速云 阅读:246
# 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框架混合使用 “`

推荐阅读:
  1. 如何使用SpringBoot  jdbctemplate
  2. Springboot集成jdbcTemplate的用法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot jdbctemplate

上一篇:TreeSet中怎么实现子类排序操作

下一篇:VB.NET中怎么创建一个类

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》