mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add upsert
This commit is contained in:
parent
27e5f58692
commit
b63dbe7a9a
@ -10,7 +10,8 @@
|
|||||||
* 【core 】 增加KetamaHash(issue#2084@Github)
|
* 【core 】 增加KetamaHash(issue#2084@Github)
|
||||||
* 【crypto 】 增加SignUtil
|
* 【crypto 】 增加SignUtil
|
||||||
* 【json 】 JSONGetter增加getBeanList方法
|
* 【json 】 JSONGetter增加getBeanList方法
|
||||||
* 【core 】 ObjectUtil 添加三个defaultIfXxxx方法,用于节省CPU及内存损耗。(pr#2094@Github)
|
* 【core 】 ObjectUtil 添加三个defaultIfXxxx方法,用于节省CPU及内存损耗(pr#2094@Github)
|
||||||
|
* 【db 】 增加单条数据原生upsert语义支持(pr#501@Gitee)
|
||||||
*
|
*
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【core 】 修复setter重载导致匹配错误(issue#2082@Github)
|
* 【core 】 修复setter重载导致匹配错误(issue#2082@Github)
|
||||||
|
@ -96,6 +96,7 @@ public class DialectRunner implements Serializable {
|
|||||||
* @param keys 需要检查唯一性的字段
|
* @param keys 需要检查唯一性的字段
|
||||||
* @return 插入行数
|
* @return 插入行数
|
||||||
* @throws SQLException SQL执行异常
|
* @throws SQLException SQL执行异常
|
||||||
|
* @since 5.7.20
|
||||||
*/
|
*/
|
||||||
public int upsert(Connection conn, Entity record, String... keys) throws SQLException {
|
public int upsert(Connection conn, Entity record, String... keys) throws SQLException {
|
||||||
PreparedStatement ps = getDialect().psForUpsert(conn, record, keys);
|
PreparedStatement ps = getDialect().psForUpsert(conn, record, keys);
|
||||||
@ -106,12 +107,26 @@ public class DialectRunner implements Serializable {
|
|||||||
DbUtil.close(ps);
|
DbUtil.close(ps);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final Entity where = record.filter(keys);
|
return insertOrUpdate(conn, record, keys);
|
||||||
if (MapUtil.isNotEmpty(where) && count(conn, where) > 0) {
|
}
|
||||||
return update(conn, record, where);
|
}
|
||||||
} else {
|
|
||||||
return insert(conn, record).length;
|
/**
|
||||||
}
|
* 插入或更新数据<br>
|
||||||
|
* 此方法不会关闭Connection
|
||||||
|
*
|
||||||
|
* @param conn 数据库连接
|
||||||
|
* @param record 记录
|
||||||
|
* @param keys 需要检查唯一性的字段
|
||||||
|
* @return 插入行数
|
||||||
|
* @throws SQLException SQL执行异常
|
||||||
|
*/
|
||||||
|
public int insertOrUpdate(Connection conn, Entity record, String... keys) throws SQLException {
|
||||||
|
final Entity where = record.filter(keys);
|
||||||
|
if (MapUtil.isNotEmpty(where) && count(conn, where) > 0) {
|
||||||
|
return update(conn, record, where);
|
||||||
|
} else {
|
||||||
|
return insert(conn, record)[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package cn.hutool.db;
|
package cn.hutool.db;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.map.MapUtil;
|
|
||||||
import cn.hutool.db.dialect.Dialect;
|
import cn.hutool.db.dialect.Dialect;
|
||||||
import cn.hutool.db.dialect.DialectFactory;
|
import cn.hutool.db.dialect.DialectFactory;
|
||||||
import cn.hutool.db.handler.EntityListHandler;
|
import cn.hutool.db.handler.EntityListHandler;
|
||||||
@ -15,7 +14,6 @@ import cn.hutool.db.sql.SqlUtil;
|
|||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -23,7 +21,8 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* SQL执行类<br>
|
* SQL执行类<br>
|
||||||
* 此执行类只接受方言参数,不需要数据源,只有在执行方法时需要数据库连接对象<br>
|
* 此执行类只接受方言参数,不需要数据源,只有在执行方法时需要数据库连接对象<br>
|
||||||
* 此对象存在的意义在于,可以由使用者自定义数据库连接对象,并执行多个方法,方便事务的统一控制或减少连接对象的创建关闭
|
* 此对象存在的意义在于,可以由使用者自定义数据库连接对象,并执行多个方法,方便事务的统一控制或减少连接对象的创建关闭<br>
|
||||||
|
* 相比{@link DialectRunner},此类中提供了更多重载方法
|
||||||
*
|
*
|
||||||
* @author Luxiaolei
|
* @author Luxiaolei
|
||||||
*/
|
*/
|
||||||
@ -83,25 +82,6 @@ public class SqlConnRunner extends DialectRunner {
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------- CRUD start
|
//---------------------------------------------------------------------------- CRUD start
|
||||||
|
|
||||||
/**
|
|
||||||
* 插入或更新数据<br>
|
|
||||||
* 此方法不会关闭Connection
|
|
||||||
*
|
|
||||||
* @param conn 数据库连接
|
|
||||||
* @param record 记录
|
|
||||||
* @param keys 需要检查唯一性的字段
|
|
||||||
* @return 插入行数
|
|
||||||
* @throws SQLException SQL执行异常
|
|
||||||
*/
|
|
||||||
public int insertOrUpdate(Connection conn, Entity record, String... keys) throws SQLException {
|
|
||||||
final Entity where = record.filter(keys);
|
|
||||||
if (MapUtil.isNotEmpty(where) && count(conn, where) > 0) {
|
|
||||||
return update(conn, record, where);
|
|
||||||
} else {
|
|
||||||
return insert(conn, record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量插入数据<br>
|
* 批量插入数据<br>
|
||||||
* 需要注意的是,批量插入每一条数据结构必须一致。批量插入数据时会获取第一条数据的字段结构,之后的数据会按照这个格式插入。<br>
|
* 需要注意的是,批量插入每一条数据结构必须一致。批量插入数据时会获取第一条数据的字段结构,之后的数据会按照这个格式插入。<br>
|
||||||
|
@ -144,13 +144,15 @@ public interface Dialect extends Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建用于upsert的PreparedStatement
|
* 构建用于upsert的PreparedStatement<br>
|
||||||
|
* 方言实现需实现此默认方法,默认返回{@code null}
|
||||||
*
|
*
|
||||||
* @param conn 数据库连接对象
|
* @param conn 数据库连接对象
|
||||||
* @param entity 数据实体类(包含表名)
|
* @param entity 数据实体类(包含表名)
|
||||||
* @param keys 查找字段
|
* @param keys 查找字段
|
||||||
* @return PreparedStatement
|
* @return PreparedStatement
|
||||||
* @throws SQLException SQL执行异常
|
* @throws SQLException SQL执行异常
|
||||||
|
* @since 5.7.20
|
||||||
*/
|
*/
|
||||||
default PreparedStatement psForUpsert(Connection conn, Entity entity, String... keys) throws SQLException {
|
default PreparedStatement psForUpsert(Connection conn, Entity entity, String... keys) throws SQLException {
|
||||||
return null;
|
return null;
|
||||||
|
@ -310,7 +310,6 @@ public class SqlBuilder implements Builder<String> {
|
|||||||
|
|
||||||
if (null != wrapper) {
|
if (null != wrapper) {
|
||||||
// 包装表名
|
// 包装表名
|
||||||
// entity = wrapper.wrap(entity);
|
|
||||||
entity.setTableName(wrapper.wrap(entity.getTableName()));
|
entity.setTableName(wrapper.wrap(entity.getTableName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import cn.hutool.core.util.CharUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.db.Entity;
|
import cn.hutool.db.Entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@ -17,7 +18,8 @@ import java.util.Map.Entry;
|
|||||||
* @author Looly
|
* @author Looly
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Wrapper {
|
public class Wrapper implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 前置包装符号 */
|
/** 前置包装符号 */
|
||||||
private Character preWrapQuote;
|
private Character preWrapQuote;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user