Postgresql 根据model类自动生成插入语句,批量插入数据
Posted 程序媛一枚~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Postgresql 根据model类自动生成插入语句,批量插入数据相关的知识,希望对你有一定的参考价值。
Postgresql 根据model类自动生成插入语句,批量插入数据
- 所有的类可以继承自一个BaseObject类(非必需);
- 数据库表中的字段名及类型必须与Object类中的一一对应;
- 调用通用的方法(对数据进行批量插入);
String.format(“insert into %s(%s) values(%s)”, tableName, fieldNames, marks);
主要涉及到应用反射,获取model类的所有字段名;
拼接sql中的字段名,及占位符;
然后再次利用反射对每一个字段设置值。
源码
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.StringJoiner;
/*************************************
* Class Name: CommonDao
* Description:〈通用数据Dao〉
* @author Seminar
* @Date 2023.01.18
************************************/
@Slf4j
public class CommonDao
@Autowired
JdbcTemplate jdbcTemplate;
/**
* 根据字段数组拼接问号
*
* @param fields 字段数组
* @return
*/
protected String getQueryMark(String fields)
String[] arr = fields.split(",");
int len = arr.length;
StringJoiner joiner = new StringJoiner(",");
while (len-- > 0)
joiner.add("?");
return joiner.toString();
/**
* 获取表记录总数
*
* @param tableName 表名
* @return 记录总数
*/
public Integer getTotal(String tableName)
return getTotal(tableName, null);
/**
* 根据条件获取表记录总数
*
* @param tableName 表名
* @param whereSql 关键字
* @return 记录总数
*/
public Integer getTotal(String tableName, String whereSql)
String sql = String.format("select count(*) as total from %s", tableName);
if (!StringUtils.isEmpty(whereSql))
sql += " where " + whereSql;
return jdbcTemplate.queryForObject(sql, Integer.class);
/**
* 判断查询结果集中是否存在某列
*
* @param rs 查询结果集
* @param columnName 列名
* @return true 存在; false 不存咋
*/
public boolean isExistColumn(ResultSet rs, String columnName)
try
if (rs.findColumn(columnName) > 0)
return true;
catch (SQLException e)
return false;
return false;
/**
* 根据字段名获取按?拼接的字符串
*
* @param fields 字段名,每一个占位一个?,特殊的集合类型,特殊处理
* @return
*/
protected String getQueryMark2(String fields)
String[] fieldNames = fields.split(",");
String delimeter = ",";
StringBuilder sb = new StringBuilder();
for (String field : fieldNames)
if ("geometry".equals(field) || "s_index".equals(field))
sb.append("ST_GeomFromText(?)" + delimeter);
else
sb.append("?" + delimeter);
return sb.substring(0, sb.length() - 1);
/**
* 批量插入通用方法(注意需要Object类中所有字段名与数据库中表列名的一致)
*
* @param objs 对象lists
* @param tableName 插入的表名
* @param <T> 通用BaseObject类
*/
public <T> void batchInsertRdClassT(List<T> objs, String tableName)
if (objs == null || objs.isEmpty())
return;
String fieldNames = getFieldNames(objs.get(0).getClass());
String marks = getQueryMark2(fieldNames);
String sql = String.format("insert into %s(%s) values(%s)", tableName, fieldNames, marks);
log.info("", sql);
int[] res = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter()
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException
T item = objs.get(i);
Field[] fieldVals = item.getClass().getDeclaredFields();
for (int j = 0; j < fieldVals.length; j++)
Field field = fieldVals[j];
field.setAccessible(true);
try
setValue(ps, j + 1, field.get(item));
catch (IllegalAccessException e)
throw new RuntimeException(e);
@Override
public int getBatchSize()
return objs.size();
);
/**
* 对每一个字段设置值
*
* @param ps
* @param index
* @param column
* @throws SQLException
*/
private void setValue(PreparedStatement ps, int index, Object column) throws SQLException
if (column == null)
ps.setNull(index, 0);
else
if (column instanceof Long)
ps.setLong(index, (Long) column);
else if (column instanceof String)
ps.setLong(index, (Long) column);
else if (column instanceof Integer)
ps.setInt(index, (Integer) column);
else if (column instanceof Double)
ps.setDouble(index, (Double) column);
else if (column instanceof Boolean)
ps.setBoolean(index, (Boolean) column);
/**
* 获取类的所有字段名,并,拼接
*
* @param clazz 实体类名
* @return
*/
private static String getFieldNames(Class clazz)
Field[] fields = clazz.getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i = 0; i < fields.length; i++)
fieldNames[i] = fields[i].getName();
return StringUtils.join(fieldNames, ",");
以上是关于Postgresql 根据model类自动生成插入语句,批量插入数据的主要内容,如果未能解决你的问题,请参考以下文章
在 PostgreSQL 和 Slick 中使用自动递增字段