jdbcTemplate 的update 和batchUpdate 方法的使用

update 方法

    首先来看update 方法

    1.  sql的生成:

这个方法有三个实现,每一个方法都包含一个sql 和另外的一个参数

我们就拿第一个方法为例子: 第一个sql 应该怎么写

比如插入:insert into table_name(column1,column2) values(?,?)

        更新:update table_name set column1=?,column2=? where column3=? and ..

其实我们可以看出来的是第一个参数sql 和我们平时编写的语句并无差异,就是里面的值我们先用? 进行代替 下面是我写的一个生成insert  语句的方法,传入的是对象的class 


	/**
	 * 生成insert sql 
	 * @param clazz
	 * @return
	 */

	public static String generateInsertSql(Class<?> clazz) {
		Table annotation = clazz.getAnnotation(Table.class);
		if (annotation == null || StrUtil.isStrBlank(annotation.name())) {
			throw new RuntimeErrorException(new Error(), MESS.EntityAnnotationIsNull);
		}
		String tablename = annotation.name();
		// 获取相关的,属性
		String sql_prex="insert into "+tablename+"(";
		String sql_suffix="values(";
		Field[] fs = clazz.getDeclaredFields();
		if(fs==null || fs.length==0) {
			throw new RuntimeErrorException(new Error(), MESS.EntityPropertiesIsNull);
		}
		for (int i = 0; i < fs.length; i++) {
			Field f=fs[i];
			sql_prex=sql_prex+f.getName()+",";
			sql_suffix=sql_suffix+"?,";
		}
		sql_prex=sql_prex.substring(0, sql_prex.lastIndexOf(","))+")";
		sql_suffix=sql_suffix.substring(0, sql_suffix.lastIndexOf(","))+")";
		return sql_prex+" "+sql_suffix;
	}

需要注意的是:实体需要有注释 ,比如:name的值是对应的表名

    2. 参数PreparedStatementSetter是一个待实现的接口,作用是给上面我们生成的语句里面的?进行赋值,并且需要按照顺序进行赋值,比如我们按照上面的方法生成了sql 下面我们需要对立面的? 进行赋值

	public <T> void addEntity(T entity) {
		Connection conn=null;
		Savepoint point=null;
		try {
			logger.info("****添加实体类addEntity*******");
			conn=jdbcTemplate.getDataSource().getConnection();
			conn.setAutoCommit(false);
			if (entity == null) {
				throw new RuntimeErrorException(new Error(), MESS.EntityCanNotNull);
			}
			logger.info("生成插入sql");
			point = conn.setSavepoint();
			String sql = generateInsertSql(entity.getClass());
			Field[] fields = entity.getClass().getDeclaredFields();
			PreparedStatementSetter setter = new PreparedStatementSetter() {
				@Override
				public void setValues(PreparedStatement ps) throws SQLException {
					for (int j = 0; j < fields.length; j++) {
						// 获取方法
						PropertyDescriptor pd = null;
						try {
							pd = new PropertyDescriptor(fields[j].getName(), entity.getClass());
						} catch (IntrospectionException e1) {
							e1.printStackTrace();
						}
						Method getMethod = pd.getReadMethod();
						try {
							ps.setObject(j + 1, getMethod.invoke(entity));
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						} catch (InvocationTargetException e) {
							e.printStackTrace();
						}
					}
				}
			};
			jdbcTemplate.update(sql, setter);
			conn.commit();
		} catch (Exception e) {
			try {
				conn.rollback(point);
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			logger.error("****添加实体失败{}*****", e.getMessage());
			throw new RuntimeErrorException(new Error(), e.getMessage());
		}
		logger.info("****结束实体类addEntity*******");

	}

我们实现的其实是这个接口的setValue 方法 

注意:的是赋值的时候是从 下标 1开始的

batchUpdate 方法

 这个方法和update 很类似,update 是单条语句的更新,但是batchupdate是多条语句的批量操作

    比如,还是使用上面的生成sql的方法:

	/**
	 * V1.1
	 *********** 批量更新 **
	 * date 2021-03-15
	 */

	@Override
	public <T> void batchAddObjectList(List<T> list) {

		logger.info("*************开始执行批量增加**************");
		if (list == null || list.size() == 0) {
			throw new RuntimeErrorException(new Error(), MESS.ListIsEmpty);
		}
		T obj_1 = list.get(0);
		String sql = generateInsertSql(obj_1.getClass());
		try {
			BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter() {
		
				@Override
				public void setValues(PreparedStatement ps, int i) throws SQLException {
					    T obj=list.get(i);
						Field[] fields = obj.getClass().getDeclaredFields();
						for (int j = 0; j < fields.length; j++) {
							// 获取方法
							PropertyDescriptor pd = null;
							try {
								pd = new PropertyDescriptor(fields[j].getName(), obj.getClass());
							} catch (IntrospectionException e1) {
								e1.printStackTrace();
							}
							Method getMethod = pd.getReadMethod();
							try {
								ps.setObject(j + 1, getMethod.invoke(obj));
							} catch (IllegalAccessException e) {
								e.printStackTrace();
							} catch (IllegalArgumentException e) {
								e.printStackTrace();
							} catch (InvocationTargetException e) {
								e.printStackTrace();
							}
						}
				}

				@Override
				public int getBatchSize() {
					return list.size();
				}
			};
			jdbcTemplate.batchUpdate(sql, setter);
			logger.info("****************结束调用批量更新****************");
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeErrorException(new Error(), e.getMessage());
		}

	}

这个的参数是 BatchPreparedStatementSetter  这个也是一个需要实现的接口,我们需要实现里面的setValues和getBatchSize ()   其实就是返回批量更新的条数

上面是对jdbcTemplate中的两个方法的介绍,以及自己实现的通用的方法

其实之前用jdbcTemplate主要是自己拼接sql语句,一个完整的SQL语句 然后调用jdbctemplate的execute这个方法,遇到需要自己实现的接口总是在逃避

所以自己的水平总是在一个阶段

这次通过介绍这样的一个实现,也是对自己的一个提高,算是一次记录笔记

希望对你有所帮助!

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值