diff --git a/CHANGELOG.md b/CHANGELOG.md index c2c4a89ec..40478a2d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Bug修复 * 【core】 修复DateUtil.offset导致的时区错误问题(issue#I1294O@Gitee) * 【core】 修复RuntimeUtil.exec重载导致的问题(issue#544@Github) +* 【db】 修复StatementUtil.getGeneratedKeys返回主键数量不足问题 ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java b/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java index aea1b21c6..7e7918f1b 100644 --- a/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java +++ b/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java @@ -94,7 +94,7 @@ public abstract class AbstractDb implements Serializable{ * @since 3.2.2 */ public List query(String sql, Class beanClass, Object... params) throws SQLException { - return query(sql, new BeanListHandler(beanClass), params); + return query(sql, new BeanListHandler<>(beanClass), params); } /** @@ -148,8 +148,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return SqlExecutor.query(conn, sql, rsh, params); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -169,8 +167,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return SqlExecutor.execute(conn, sql, params); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -190,8 +186,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return SqlExecutor.executeForGeneratedKey(conn, sql, params); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -210,8 +204,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return SqlExecutor.executeBatch(conn, sql, paramsBatch); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -230,8 +222,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return SqlExecutor.executeBatch(conn, sqls); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -250,8 +240,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.insert(conn, record); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -272,8 +260,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.insertOrUpdate(conn, record, keys); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -293,8 +279,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.insert(conn, records); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -312,8 +296,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.insertForGeneratedKeys(conn, record); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -331,8 +313,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.insertForGeneratedKey(conn, record); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -363,8 +343,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.del(conn, where); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -384,8 +362,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.update(conn, record, where); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -436,8 +412,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.find(conn, fields, where, rsh); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -450,7 +424,6 @@ public abstract class AbstractDb implements Serializable{ * @param fields 返回的字段列表,null则返回所有字段 * @param where 条件实体类(包含表名) * @return 结果Entity列表 - * @return 结果对象 * @throws SQLException SQL执行异常 * @since 4.5.16 */ @@ -474,8 +447,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.find(conn, query, rsh); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -613,8 +584,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.count(conn, where); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -638,8 +607,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.page(conn, fields, where, page, numPerPage, rsh); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -724,8 +691,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.page(conn, fields, where, page, rsh); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -747,8 +712,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.page(conn, fields, where, page, numPerPage); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } @@ -769,8 +732,6 @@ public abstract class AbstractDb implements Serializable{ try { conn = this.getConnection(); return runner.page(conn, fields, where, page); - } catch (SQLException e) { - throw e; } finally { this.closeConnection(conn); } diff --git a/hutool-db/src/main/java/cn/hutool/db/SqlConnRunner.java b/hutool-db/src/main/java/cn/hutool/db/SqlConnRunner.java index 3cfb5c945..4ebe95d0a 100644 --- a/hutool-db/src/main/java/cn/hutool/db/SqlConnRunner.java +++ b/hutool-db/src/main/java/cn/hutool/db/SqlConnRunner.java @@ -101,15 +101,13 @@ public class SqlConnRunner{ try { ps = dialect.psForInsert(conn, record); return ps.executeUpdate(); - } catch (SQLException e) { - throw e; } finally { DbUtil.close(ps); } } /** - * 插入数据
+ * 插入或更新数据
* 此方法不会关闭Connection * * @param conn 数据库连接 @@ -191,8 +189,6 @@ public class SqlConnRunner{ ps = dialect.psForInsert(conn, record); ps.executeUpdate(); return StatementUtil.getGeneratedKeys(ps); - } catch (SQLException e) { - throw e; } finally { DbUtil.close(ps); } @@ -217,8 +213,6 @@ public class SqlConnRunner{ ps = dialect.psForInsert(conn, record); ps.executeUpdate(); return StatementUtil.getGeneratedKeyOfLong(ps); - } catch (SQLException e) { - throw e; } finally { DbUtil.close(ps); } @@ -244,8 +238,6 @@ public class SqlConnRunner{ try { ps = dialect.psForDelete(conn, query); return ps.executeUpdate(); - } catch (SQLException e) { - throw e; } finally { DbUtil.close(ps); } @@ -282,8 +274,6 @@ public class SqlConnRunner{ try { ps = dialect.psForUpdate(conn, record, query); return ps.executeUpdate(); - } catch (SQLException e) { - throw e; } finally { DbUtil.close(ps); } @@ -308,8 +298,6 @@ public class SqlConnRunner{ try { ps = dialect.psForFind(conn, query); return SqlExecutor.query(ps, rsh); - } catch (SQLException e) { - throw e; } finally { DbUtil.close(ps); } @@ -444,8 +432,6 @@ public class SqlConnRunner{ try { ps = dialect.psForCount(conn, query); return SqlExecutor.query(ps, new NumberHandler()).intValue(); - } catch (SQLException e) { - throw e; } finally { DbUtil.close(ps); } @@ -531,7 +517,7 @@ public class SqlConnRunner{ //查询全部 if(null == page){ List entityList = this.find(conn, fields, where, new EntityListHandler()); - final PageResult pageResult = new PageResult(0, entityList.size(), entityList.size()); + final PageResult pageResult = new PageResult<>(0, entityList.size(), entityList.size()); pageResult.addAll(entityList); return pageResult; } diff --git a/hutool-db/src/main/java/cn/hutool/db/StatementUtil.java b/hutool-db/src/main/java/cn/hutool/db/StatementUtil.java index 65938ad74..b093dbb13 100644 --- a/hutool-db/src/main/java/cn/hutool/db/StatementUtil.java +++ b/hutool-db/src/main/java/cn/hutool/db/StatementUtil.java @@ -24,15 +24,15 @@ import cn.hutool.db.sql.SqlUtil; /** * Statement和PreparedStatement工具类 - * + * * @author looly * @since 4.0.10 */ public class StatementUtil { /** * 填充SQL的参数。 - * - * @param ps PreparedStatement + * + * @param ps PreparedStatement * @param params SQL参数 * @return {@link PreparedStatement} * @throws SQLException SQL执行异常 @@ -44,8 +44,8 @@ public class StatementUtil { /** * 填充SQL的参数。
* 对于日期对象特殊处理:传入java.util.Date默认按照Timestamp处理 - * - * @param ps PreparedStatement + * + * @param ps PreparedStatement * @param params SQL参数 * @return {@link PreparedStatement} * @throws SQLException SQL执行异常 @@ -84,15 +84,7 @@ public class StatementUtil { ps.setObject(paramIndex, param); } } else { - final ParameterMetaData pmd = ps.getParameterMetaData(); - int sqlType = Types.VARCHAR; - try { - sqlType = pmd.getParameterType(paramIndex); - } catch (SQLException e) { - // ignore - // log.warn("Null param of index [{}] type get failed, by: {}", paramIndex, e.getMessage()); - } - ps.setNull(paramIndex, sqlType); + ps.setNull(paramIndex, getTypeOfNull(ps, paramIndex)); } } return ps; @@ -100,8 +92,8 @@ public class StatementUtil { /** * 创建{@link PreparedStatement} - * - * @param conn 数据库连接 + * + * @param conn 数据库连接 * @param sqlBuilder {@link SqlBuilder}包括SQL语句和参数 * @return {@link PreparedStatement} * @throws SQLException SQL异常 @@ -113,9 +105,9 @@ public class StatementUtil { /** * 创建{@link PreparedStatement} - * - * @param conn 数据库连接 - * @param sql SQL语句,使用"?"做为占位符 + * + * @param conn 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 * @param params "?"对应参数列表 * @return {@link PreparedStatement} * @throws SQLException SQL异常 @@ -127,9 +119,9 @@ public class StatementUtil { /** * 创建{@link PreparedStatement} - * - * @param conn 数据库连接 - * @param sql SQL语句,使用"?"做为占位符 + * + * @param conn 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 * @param params "?"对应参数列表 * @return {@link PreparedStatement} * @throws SQLException SQL异常 @@ -149,12 +141,12 @@ public class StatementUtil { } return fillParams(ps, params); } - + /** * 创建批量操作的{@link PreparedStatement} - * - * @param conn 数据库连接 - * @param sql SQL语句,使用"?"做为占位符 + * + * @param conn 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 * @param paramsBatch "?"对应参数批次列表 * @return {@link PreparedStatement} * @throws SQLException SQL异常 @@ -166,9 +158,9 @@ public class StatementUtil { /** * 创建批量操作的{@link PreparedStatement} - * - * @param conn 数据库连接 - * @param sql SQL语句,使用"?"做为占位符 + * + * @param conn 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 * @param paramsBatch "?"对应参数批次列表 * @return {@link PreparedStatement} * @throws SQLException SQL异常 @@ -189,9 +181,9 @@ public class StatementUtil { /** * 创建{@link CallableStatement} - * - * @param conn 数据库连接 - * @param sql SQL语句,使用"?"做为占位符 + * + * @param conn 数据库连接 + * @param sql SQL语句,使用"?"做为占位符 * @param params "?"对应参数列表 * @return {@link CallableStatement} * @throws SQLException SQL异常 @@ -210,15 +202,13 @@ public class StatementUtil { /** * 获得自增键的值
* 此方法对于Oracle无效 - * + * * @param ps PreparedStatement * @return 自增键的值 * @throws SQLException SQL执行异常 */ - public static Long getGeneratedKeyOfLong(PreparedStatement ps) throws SQLException { - ResultSet rs = null; - try { - rs = ps.getGeneratedKeys(); + public static Long getGeneratedKeyOfLong(Statement ps) throws SQLException { + try(final ResultSet rs = ps.getGeneratedKeys()) { Long generatedKey = null; if (rs != null && rs.next()) { try { @@ -228,34 +218,50 @@ public class StatementUtil { } } return generatedKey; - } catch (SQLException e) { - throw e; - } finally { - DbUtil.close(rs); } } /** - * 获得所有主键
- * + * 获得所有主键 + * * @param ps PreparedStatement * @return 所有主键 * @throws SQLException SQL执行异常 */ - public static List getGeneratedKeys(PreparedStatement ps) throws SQLException { - List keys = new ArrayList(); - ResultSet rs = null; - int i = 1; - try { - rs = ps.getGeneratedKeys(); - if (rs != null && rs.next()) { - keys.add(rs.getObject(i++)); + public static List getGeneratedKeys(Statement ps) throws SQLException { + final List keys = new ArrayList<>(); + try (final ResultSet rs = ps.getGeneratedKeys()) { + if (null != rs) { + int i = 1; + while (rs.next()) { + keys.add(rs.getObject(i++)); + } } return keys; - } catch (SQLException e) { - throw e; - } finally { - DbUtil.close(rs); } } + + /** + * 获取null字段对应位置的数据类型
+ * 有些数据库对于null字段必须指定类型,否则会插入报错,此方法用于获取其类型,如果获取失败,使用默认的{@link Types#VARCHAR} + * + * @param ps {@link Statement} + * @param paramIndex 参数位置,第一位从1开始 + * @return 数据类型,默认{@link Types#VARCHAR} + * @since 4.6.7 + */ + public static int getTypeOfNull(PreparedStatement ps, int paramIndex) { + int sqlType = Types.VARCHAR; + + final ParameterMetaData pmd; + try { + pmd = ps.getParameterMetaData(); + sqlType = pmd.getParameterType(paramIndex); + } catch (SQLException ignore) { + // ignore + // log.warn("Null param of index [{}] type get failed, by: {}", paramIndex, e.getMessage()); + } + + return sqlType; + } }