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这个方法,遇到需要自己实现的接口总是在逃避
所以自己的水平总是在一个阶段
这次通过介绍这样的一个实现,也是对自己的一个提高,算是一次记录笔记
希望对你有所帮助!