天天看点

jdbcTemplate 的update 和batchUpdate 方法的使用

update 方法

    首先来看update 方法

jdbcTemplate 的update 和batchUpdate 方法的使用

    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这个方法,遇到需要自己实现的接口总是在逃避

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

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

希望对你有所帮助!