博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入浅出JDBC(四) - Insert与Spring SimpleJdbcInsert
阅读量:5903 次
发布时间:2019-06-19

本文共 4568 字,大约阅读时间需要 15 分钟。

hot3.png

Sql的Insert操作,因为表的主键一般都设置成自增的原因,相较于update操作,多了对自增id的获取。spring jdbc对insert操作的支持也很完善,不仅在JdbcTemplate的update方法中支持返回主键,更是单独提供SimpleJdbcInsert类帮助使用insert操作。

JdbcTemplate的Insert

spring使用KeyHolder作为自增列返回的持有器,update方法支持PreparedStatementCreator和KeyHolder两个参数,来完成insert操作并返回自增列的值。

@Testpublic void testInsertAutoGeneratedKey(){	final String insertSql = "insert into t_wms_goods_stock (warehouse_id, amount) values(?,?)";		// 创建自增key的持有器	KeyHolder keyHolder = new GeneratedKeyHolder();	int insertRow = jdbcTemplate.update(new PreparedStatementCreator() {				public PreparedStatement createPreparedStatement(Connection con) throws SQLException {			// 获取PreparedStatement,并指定返回自增key			PreparedStatement ps = con.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS);			ps.setLong(1, 1L);			ps.setDouble(2, 100.25);			return ps;		}	}, keyHolder);		if(insertRow > 0){		// getKey返回单一自增值		System.out.println("auto-generated key:" + keyHolder.getKey());	}}

KeyHolder的getKey方法返回的是Number类型

如果是批量insert,也可以支持

@Testpublic void testMultiInsertAutoGeneratedKey(){	final String insertSql = "insert into t_wms_goods_stock (warehouse_id, amount) values(?,?),(?,?)";		KeyHolder keyHolder = new GeneratedKeyHolder();	int insertRow = jdbcTemplate.update(new PreparedStatementCreator() {				public PreparedStatement createPreparedStatement(Connection con) throws SQLException {			PreparedStatement ps = con.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS);			ps.setLong(1, 1L);			ps.setDouble(2, 100.25);			ps.setLong(3, 2L);			ps.setDouble(4, 122.9);			return ps;		}	}, keyHolder);		if(insertRow > 0){		// getKeyList返回批量自增值		System.out.println("auto-generated key:" + keyHolder.getKeyList());	}}

但是返回的是List<Map<String, Object>>,map的key是ColumnKey,value就是自增列的值。笔者使用的是mysql,返回的数据如下:

[{GENERATED_KEY=17}, {GENERATED_KEY=18}]

由于mysql一张表里不允许设置两个自增列,是否返回的自增column key名称就是GENERATED_KEY,笔者不能确认,如果有明确知晓的朋友,还请告知。

SimpleJdbcInsert

为了简化insert操作,spring提供了一个简便的,基于流式api的支持表插入的类,就是SimpleJdbcInsert。SimpleJdbcInsert提供三个execute方法执行insert操作

// 普通insert,返回影响行数public int execute(Map
args) { return doExecute(args);}// 有自增id的单条insertpublic Number executeAndReturnKey(Map
args) { return doExecuteAndReturnKey(args);}// 有自增id的insert,返回KeyHolderpublic KeyHolder executeAndReturnKeyHolder(Map
args) { return doExecuteAndReturnKeyHolder(args);}

先来看普通的insert

@Testpublic void testInsertWithMap(){	SimpleJdbcInsert insert = new SimpleJdbcInsert(jdbcTemplate)			.withTableName("t_wms_goods_stock");		Map
params = new HashMap<>(); params.put("id", 3); params.put("warehouse_id", 1); params.put("amount", 15d); int insertCount = insert.execute(params); System.out.println("insertCount:" + insertCount);}

传入JdbcTemplate构造SimpleJdbcInsert,然后赋予操作的表名,使用map构造insert的column name和对应的column value,调用execute执行,返回影响的行数。简单深入下源码,可以看到底层执行的还是JdbcTemplate的方法。

getJdbcTemplate().update(getInsertString(), values.toArray(), getInsertTypes());

再来看有主键递增的insert

@Testpublic void testInsertWithMapAndGeneratedKey(){	SimpleJdbcInsert insert = new SimpleJdbcInsert(jdbcTemplate)			.withTableName("t_wms_goods_stock")			// 设置自增column			.usingGeneratedKeyColumns("id");		Map
params = new HashMap<>(); params.put("warehouse_id", 1); params.put("amount", 32d); Number newId = insert.executeAndReturnKey(params); System.out.println("insert new id:" + newId);}

构造SimpleJdbcInsert时,设置了自增column,然后调用executeAndReturnKey方法,返回Number类型的自增列的值。

对于executeAndReturnKeyHolder方法,由于参数是map方式,并不能支持批量insert。

至于execute的参数,spring还提供除map外的其他方式:SqlParameterSource,并提供两种常用的实现。

MapSqlParameterSource

类似于Map的一种参数

@Testpublic void testMapSqlParameterSource(){	SimpleJdbcInsert insert = new SimpleJdbcInsert(jdbcTemplate)			.withTableName("t_wms_goods_stock")			.usingGeneratedKeyColumns("id");		SqlParameterSource parameterSource = new MapSqlParameterSource()			.addValue("warehouse_id", 1l)			.addValue("amount", 23d);	Number newId = insert.executeAndReturnKey(parameterSource);	System.out.println("insert new id:" + newId);}

BeanPropertySqlParameterSource

传入对于的java对象,映射对象属性名称到数据库表的列名称(将java的驼峰式名称转换成sql的下划线分隔的名称)

public void testBeanPropertySqlParameterSource(){	SimpleJdbcInsert insert = new SimpleJdbcInsert(jdbcTemplate)			.withTableName("t_wms_goods_stock")			.usingGeneratedKeyColumns("id");		SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(new GoodsStock(1l, 23d));	Number newId = insert.executeAndReturnKey(parameterSource);	System.out.println("insert new id:" + newId);}

此种方式,对于对象属性和表字段名称一致的是非常方便的。

转载于:https://my.oschina.net/u/2377110/blog/1603428

你可能感兴趣的文章
Github简介
查看>>
存储过程—导出table数据为inser sqlt语句
查看>>
Windows 7下Maven3.0.3的安装
查看>>
CISCO2691的OSPF点对点密文测评测试
查看>>
POJ 1661 Help Jimmy(递推DP)
查看>>
Node.js 中文学习资料和教程导航
查看>>
查找(AVL平衡二叉树)
查看>>
Javascript函数调用的四种模式
查看>>
用 Asterisk 搭建自己的免费 VoIP 服务器
查看>>
lua笔记二 赋值语句
查看>>
Android 中 Internal Storage 和 External Storage 的区别
查看>>
移动端拖拽(模块化开发,触摸事件,webpack)
查看>>
spring配置和注解事务同时存在导致的事务嵌套
查看>>
AE要素选择(点选和拉框选择)
查看>>
AJAX-初学AJAX本地环境配置
查看>>
VSCode调试配置
查看>>
前端MVC学习总结(三)——AngularJS服务、路由、内置API、jQueryLite
查看>>
Selenium Web 自动化 - 项目持续集成(进阶)
查看>>
java&javaweb学习笔记
查看>>
UML统一建模语UML2和EnterpriseArchitect
查看>>