SpringBoot高级篇JdbcTemplate之数据更新与删除

六月ゝ 毕业季﹏ 提交于 2019-11-29 07:17:40

前面介绍了JdbcTemplate的插入数据和查询数据,占用CURD中的两项,本文则将主要介绍数据更新和删除。从基本使用上来看,姿势和前面的没啥两样

<!-- more -->

I. 环境准备

环境依然借助前面一篇的配置,链接如: 190407-SpringBoot高级篇JdbcTemplate之数据插入使用姿势详解

或者直接查看项目源码: https://github.com/liuyueyi/spring-boot-demo/blob/master/spring-boot/101-jdbctemplate

我们查询所用数据,正是前面一篇插入的结果,如下图

II. 更新使用说明

对于数据更新,这里会分为两种进行说明,单个和批量;这个单个并不是指只能一条记录,主要针对的是sql的数量而言

1. update 方式

看过第一篇数据插入的童鞋,应该也能发现,新增数据也是用的这个方法,下面会介绍三种不同的使用姿势

先提供一个数据查询的转换方法,用于对比数据更新前后的结果

private MoneyPO queryById(int id) {     return jdbcTemplate.queryForObject(             "select id, `name`, money, is_deleted as isDeleted, unix_timestamp(create_at) as " +                     "created, unix_timestamp(update_at) as updated from money where id=?",             new BeanPropertyRowMapper<>(MoneyPO.class), id); } 

a. 纯sql更新

这个属于最基本的方式了,前面几篇博文中大量使用了,传入一条完整的sql,执行即可

 int id = 10;  // 最基本的sql更新 String sql = "update money set money=money + 999 where id =" + id; int ans = jdbcTemplate.update(sql); System.out.println("basic update: " + ans + " | db: " + queryById(id)); 

b. 占位sql

问好占位,实际内容通过参数传递方式

// 占位方式 sql = "update money set money=money + ? where id = ?"; ans = jdbcTemplate.update(sql, 888, id); System.out.println("placeholder update: " + ans + " | db: " + queryById(id)); 

c. statement

从前面的几篇文章中可以看出,使用statement的方式,最大的好处有几点

  • 可以点对点的设置填充参数
  • PreparedStatementCreator 方式可以获取db连接,主动设置各种参数

下面给出两个常见的使用方式

// 通过 PreparedStatementCreator 方式更新 ans = jdbcTemplate.update(new PreparedStatementCreator() {     @Override     public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {         // 设置自动提交,设置100ms的超时,这种方式最大的好处是可以控制db连接的参数         try {             connection.setAutoCommit(true);             connection.setNetworkTimeout(Executors.newSingleThreadExecutor(), 10);             PreparedStatement statement =                     connection.prepareStatement("update money set money=money + ? where id " + "= ?");             statement.setInt(1, 777);             statement.setInt(2, id);             return statement;         } catch (Exception e) {             e.printStackTrace();             return null;         }     } }); System.out.println("statementCreator update: " + ans + " | db: " + queryById(id));   // 通过 PreparedStatementSetter 来设置占位参数值 ans = jdbcTemplate.update(sql, new PreparedStatementSetter() {     @Override     public void setValues(PreparedStatement preparedStatement) throws SQLException {         preparedStatement.setInt(1, 666);         preparedStatement.setInt(2, id);     } }); System.out.println("statementSetter update: " + ans + " | db: " + queryById(id)); 

注意下第一种调用中,设置了超时时间,下面给出一个动图,演示超时的使用姿势

在上图中,

  • 首先是一个开启一个事物,并修改了一条记录,这个时候这条记录会加上写锁
  • 然后JdbcTemplate中修改上面的这条记录,尝试加写锁,但是会失败,所以一直阻塞,当超时之后,抛出异常

2. batchUpdate 方式

批量方式,执行多个sql,从使用上看和前面没有太大的区别,先给出一个查询的通用方法

private List<MoneyPO> queryByIds(List<Integer> ids) {     StringBuilder strIds = new StringBuilder();     for (Integer id : ids) {         strIds.append(id).append(",");     }     return jdbcTemplate.query("select id, `name`, money, is_deleted as isDeleted, unix_timestamp(create_at) as " +             "created, unix_timestamp(update_at) as updated from money where id in (" +             strIds.substring(0, strIds.length() - 1) + ")", new BeanPropertyRowMapper<>(MoneyPO.class)); } 

a. 纯sql更新

// 批量修改, // 执行多条sql的场景 int[] ans = jdbcTemplate         .batchUpdate("update money set money=1300 where id =10", "update money set money=1300 where id = 11"); System.out.println(         "batch update by sql ans: " + Arrays.asList(ans) + " | db: " + queryByIds(Arrays.asList(10, 11))); 

b. 占位sql

// 占位替换方式 ans = jdbcTemplate.batchUpdate("update money set money=money + ? where id = ?",         Arrays.asList(new Object[]{99, 10}, new Object[]{99, 11})); System.out.println("batch update by placeHolder ans: " + Arrays.asList(ans) + " | db: " +         queryByIds(Arrays.asList(10, 11))); 

c. statement

// 通过 statement ans = jdbcTemplate         .batchUpdate("update money set money=money + ? where id = ?", new BatchPreparedStatementSetter() {             @Override             public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {                 preparedStatement.setInt(1, 99);                 preparedStatement.setInt(2, i + 10);             }              @Override             public int getBatchSize() {                 return 2;             }         }); System.out.println(         "batch update by statement ans: " + Arrays.asList(ans) + " | db: " + queryByIds(Arrays.asList(10, 11))); 

注意下上面的方法中,getBatchSize返回实际的sql条数,setValues中的i从0开始

3. 测试

原始数据中,money都是300,通过一系列的修改,输出如下

III. 数据删除

删除的操作姿势和上面基本一样,也就是sql的写法不同罢了,因此没有太大的必要重新写一篇,下面给出一个简单的demo

@Component public class DeleteService {     @Autowired     private JdbcTemplate jdbcTemplate;      public void delete() {         int ans = jdbcTemplate.update("delete from money where id = 13");         System.out.println("delete: " + ans);     } } 

IV. 其他

相关博文

2. 声明

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!