io.github.jinghui70.rainbow.dbaccess.Dba Maven / Gradle / Ivy
The newest version!
package io.github.jinghui70.rainbow.dbaccess;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.db.dialect.DriverUtil;
import io.github.jinghui70.rainbow.dbaccess.dialect.Dialect;
import io.github.jinghui70.rainbow.dbaccess.dialect.DialectDefault;
import io.github.jinghui70.rainbow.dbaccess.dialect.DialectOracle;
import io.github.jinghui70.rainbow.dbaccess.object.ObjectDao;
import io.github.jinghui70.rainbow.dbaccess.object.ObjectSql;
import io.github.jinghui70.rainbow.utils.StringBuilderX;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static io.github.jinghui70.rainbow.dbaccess.DbaUtil.INSERT_INTO;
import static io.github.jinghui70.rainbow.dbaccess.DbaUtil.MERGE_INTO;
@SuppressWarnings({"unused", "UnusedReturnValue"})
public class Dba {
protected JdbcTemplate jdbcTemplate;
protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;
protected TransactionTemplate transactionTemplate;
protected Dialect dialect = DialectDefault.INSTANCE;
protected Dba() {
}
protected void initDataSource(DataSource dataSource, Dialect dialect) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
this.transactionTemplate = new TransactionTemplate(transactionManager);
if (dialect != null)
this.dialect = dialect;
else
initDialect();
}
public Dba(DataSource dataSource) {
initDataSource(dataSource, null);
}
public Dba(DataSource dataSource, Dialect dialect) {
initDataSource(dataSource, dialect);
}
public Dba(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate,
TransactionTemplate transactionTemplate) {
this.jdbcTemplate = jdbcTemplate;
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
this.transactionTemplate = transactionTemplate;
initDialect();
}
public Dba(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate,
TransactionTemplate transactionTemplate, Dialect dialect) {
this.jdbcTemplate = jdbcTemplate;
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
this.transactionTemplate = transactionTemplate;
this.dialect = dialect;
}
public String getDriver() {
DataSource dataSource = Objects.requireNonNull(jdbcTemplate.getDataSource());
return DriverUtil.identifyDriver(dataSource);
}
protected void initDialect() {
String driver = getDriver();
if (driver == null) return;
if (driver.toLowerCase().contains("oracle"))
this.dialect = new DialectOracle();
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
return namedParameterJdbcTemplate;
}
public TransactionTemplate getTransactionTemplate() {
return transactionTemplate;
}
public Dialect getDialect() {
return dialect;
}
public Sql sql() {
return new Sql(this);
}
public Sql sql(String sql) {
return sql().append(sql);
}
public Sql select() {
return sql("SELECT ");
}
public Sql selectAll() {
return select("*");
}
public Sql select(String select) {
return sql("SELECT ").append(select);
}
public ObjectSql select(Class selectClass) {
return new ObjectSql<>(this, selectClass).append("SELECT * FROM ").append(DbaUtil.tableName(selectClass));
}
public ObjectSql select(Class selectClass, Map replaceMap) {
return new ObjectSql<>(this, selectClass).selectFields(replaceMap);
}
public Sql update(String table) {
return sql("UPDATE ").append(table);
}
public ObjectSql update(Class updateClass) {
return new ObjectSql<>(this, updateClass).append("UPDATE ").append(DbaUtil.tableName(updateClass));
}
public ObjectSql insertInto(Class insertClass) {
return new ObjectSql<>(this, insertClass).insertInto();
}
public Sql deleteFrom(String table) {
return sql("DELETE FROM ").append(table);
}
public ObjectSql deleteFrom(Class deleteClass) {
return new ObjectSql<>(this, deleteClass).append("DELETE FROM ").append(DbaUtil.tableName(deleteClass));
}
public NamedSql namedSql() {
return new NamedSql(this);
}
public NamedSql namedSql(String sql) {
return new NamedSql(this).append(sql);
}
/**
* 插入一个对象
*
* @param bean 需要插入的对象
* @param 对象泛型
* @return 插入改变的行数,正常应该是1
*/
@SuppressWarnings("unchecked")
public int insert(T bean) {
Assert.notNull(bean, "can't insert null object");
return new ObjectDao<>(this, (Class) bean.getClass()).insert(bean);
}
/**
* 插入一个对象,如果已经存在就更新。这个函数H2支持,别的数据库未必支持
*
* @param bean 需要插入的对象
* @param 对象泛型
* @return 插入改变的行数,正常应该是1
*/
@SuppressWarnings("unchecked")
public int merge(T bean) {
Assert.notNull(bean, "can't insert null object");
return new ObjectDao<>(this, (Class) bean.getClass()).merge(bean);
}
/**
* 插入一组数据
*
* @param beans 数据的集合
* @param 对象泛型
*/
public void insert(List beans) {
insert(beans, 0);
}
@SuppressWarnings("unchecked")
public void insert(List beans, int batchSize) {
if (CollUtil.isEmpty(beans)) return;
new ObjectDao<>(this, (Class) beans.get(0).getClass()).insert(beans, batchSize);
}
/**
* 插入一组数据,如果已经存在就更新。这个函数H2支持,别的数据库未必支持
*
* @param beans 数据的集合
* @param 对象泛型
*/
@SuppressWarnings("unchecked")
public void merge(List beans) {
if (CollUtil.isEmpty(beans)) return;
new ObjectDao<>(this, (Class) beans.get(0).getClass()).merge(beans);
}
/**
* 插入一个map到一个数据表中
*
* @param tableName 表名
* @param map map对象
* @return 插入改变的行数,正常应该是1
*/
public int insert(String tableName, Map map) {
return doInsert(tableName, map, INSERT_INTO);
}
/**
* 插入一条记录到指定的表里,如果已经存在就更新。这个函数H2支持,别的数据库未必支持
*
* @param tableName 数据表名
* @param map map对象
* @return 插入改变的行数,正常应该是1
*/
public int merge(String tableName, Map map) {
return doInsert(tableName, map, MERGE_INTO);
}
public int doInsert(String tableName, Map map, String action) {
Sql sql = sql(action).append(tableName).append("(");
for (Map.Entry entry : map.entrySet()) {
sql.append(entry.getKey()).appendTempComma().addParam(entry.getValue());
}
sql.clearTemp().append(") values (").repeat("?", map.size()).append(")");
return sql.execute();
}
/**
* 插入一组Map到指定的表里
*
* @param tableName 数据表名
* @param data 数据列表
*/
public void insert(String tableName, List