恢复GeneratedValue功能

This commit is contained in:
redkale
2023-07-26 15:57:41 +08:00
parent f2769dc182
commit 5b8f797b33
5 changed files with 181 additions and 6 deletions

View File

@@ -0,0 +1,62 @@
/** *****************************************************************************
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
*
***************************************************************************** */
package org.redkale.persistence;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* Provides for the specification of generation strategies for the
* values of primary keys.
*
* <p>
* The <code>GeneratedValue</code> annotation
* may be applied to a primary key property or field of an entity or
* mapped superclass in conjunction with the {@link Id} annotation.
* The use of the <code>GeneratedValue</code> annotation is only
* required to be supported for simple primary keys. Use of the
* <code>GeneratedValue</code> annotation is not supported for derived
* primary keys.
*
* <pre>
*
* Example 1:
*
* &#064;Id
* &#064;GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ")
* &#064;Column(name="CUST_ID")
* public Long getId() { return id; }
*
* Example 2:
*
* &#064;Id
* &#064;GeneratedValue(strategy=TABLE, generator="CUST_GEN")
* &#064;Column(name="CUST_ID")
* Long id;
* </pre>
*
* @see Id
*
* @since Java Persistence 1.0
*/
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue {
}

View File

@@ -442,7 +442,9 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
sqltype = column.length >= 65535 ? "TEXT" : ("VARCHAR(" + column.length + ")");
sqlnull = !column.nullable ? "NOT NULL DEFAULT ''" : "NULL";
}
sb.append(" `").append(column.column).append("` ").append(sqltype).append(" ").append(sqlnull);
sb.append(" `").append(column.column).append("` ").append(sqltype)
.append(column.primary && info.isAutoGenerated() ? " AUTO_INCREMENT " : " ")
.append(column.primary && info.isAutoGenerated() ? "" : sqlnull);
if (column.comment != null && !column.comment.isEmpty()) {
sb.append(" COMMENT '").append(column.comment.replace('\'', '"')).append("'");
}
@@ -552,7 +554,11 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
sqltype = column.length >= 65535 ? "TEXT" : ("VARCHAR(" + column.length + ")");
sqlnull = !column.nullable ? "NOT NULL DEFAULT ''" : "NULL";
}
sb.append(" ").append(column.column).append(" ").append(sqltype).append(" ").append(sqlnull);
if (column.primary && info.isAutoGenerated()) {
sqltype = "SERIAL";
}
sb.append(" ").append(column.column).append(" ").append(sqltype).append(" ")
.append(column.primary && info.isAutoGenerated() ? "" : sqlnull);
if (column.comment != null && !column.comment.isEmpty()) {
//postgresql不支持DDL中直接带comment
comments.add("COMMENT ON COLUMN " + info.getOriginTable() + "." + column.column + " IS '" + column.comment.replace('\'', '"') + "'");

View File

@@ -135,7 +135,9 @@ public class DataJdbcSource extends AbstractDataSqlSource {
final List<PreparedStatement> prestmts = new ArrayList<>();
for (Map.Entry<String, PrepareInfo<T>> en : prepareInfos.entrySet()) {
PrepareInfo<T> prepareInfo = en.getValue();
PreparedStatement prestmt = conn.prepareUpdateStatement(prepareInfo.prepareSql);
PreparedStatement prestmt = info.isAutoGenerated()
? conn.prepareUpdateStatement(prepareInfo.prepareSql, Statement.RETURN_GENERATED_KEYS)
: conn.prepareUpdateStatement(prepareInfo.prepareSql);
for (final T value : prepareInfo.entitys) {
bindStatementParameters(conn, prestmt, info, attrs, value);
prestmt.addBatch();
@@ -147,7 +149,9 @@ public class DataJdbcSource extends AbstractDataSqlSource {
protected <T> PreparedStatement prepareInsertEntityStatement(SourceConnection conn, String sql, EntityInfo<T> info, T... entitys) throws SQLException {
Attribute<T, Serializable>[] attrs = info.insertAttributes;
final PreparedStatement prestmt = conn.prepareUpdateStatement(sql);
final PreparedStatement prestmt = info.isAutoGenerated()
? conn.prepareUpdateStatement(sql, Statement.RETURN_GENERATED_KEYS)
: conn.prepareUpdateStatement(sql);
for (final T value : entitys) {
bindStatementParameters(conn, prestmt, info, attrs, value);
prestmt.addBatch();
@@ -341,6 +345,8 @@ public class DataJdbcSource extends AbstractDataSqlSource {
PreparedStatement prestmt = null;
List<PreparedStatement> prestmts = null;
Map<String, PrepareInfo<T>> prepareInfos = null;
final Attribute primary = info.getPrimary();
final Class primaryType = primary.type();
Attribute<T, Serializable>[] attrs = info.insertAttributes;
if (info.getTableStrategy() == null) { //单库单表
presql = info.getInsertQuestionPrepareSQL(entitys[0]);
@@ -352,6 +358,23 @@ public class DataJdbcSource extends AbstractDataSqlSource {
try {
if (info.getTableStrategy() == null) { //单库单表
c = Utility.sum(prestmt.executeBatch());
if (info.isAutoGenerated()) { //由数据库自动生成主键值
ResultSet set = prestmt.getGeneratedKeys();
int i = -1;
while (set.next()) {
T entity = entitys[++i];
if (primaryType == int.class || primaryType == Integer.class) {
primary.set(entity, set.getInt(1));
} else if (primaryType == long.class || primaryType == long.class) {
primary.set(entity, set.getLong(1));
} else if (primaryType == String.class) {
primary.set(entity, set.getString(1));
} else {
primary.set(entity, set.getObject(1));
}
}
set.close();
}
conn.offerUpdateStatement(prestmt);
} else { //分库分表
int c1 = 0;
@@ -359,6 +382,28 @@ public class DataJdbcSource extends AbstractDataSqlSource {
c1 += Utility.sum(stmt.executeBatch());
}
c = c1;
if (info.isAutoGenerated()) { //由数据库自动生成主键值
int j = -1;
for (Map.Entry<String, PrepareInfo<T>> en : prepareInfos.entrySet()) {
PrepareInfo<T> prepareInfo = en.getValue();
PreparedStatement stmt = prestmts.get(++j);
ResultSet set = stmt.getGeneratedKeys();
int i = -1;
while (set.next()) {
T entity = prepareInfo.entitys.get(++i);
if (primaryType == int.class || primaryType == Integer.class) {
primary.set(entity, set.getInt(1));
} else if (primaryType == long.class || primaryType == long.class) {
primary.set(entity, set.getLong(1));
} else if (primaryType == String.class) {
primary.set(entity, set.getString(1));
} else {
primary.set(entity, set.getObject(1));
}
}
set.close();
}
}
for (PreparedStatement stmt : prestmts) {
conn.offerUpdateStatement(stmt);
}
@@ -490,6 +535,23 @@ public class DataJdbcSource extends AbstractDataSqlSource {
conn.offerUpdateStatement(prestmt);
prestmt = prepareInsertEntityStatement(conn, presql, info, entitys);
c = Utility.sum(prestmt.executeBatch());
if (info.isAutoGenerated()) { //由数据库自动生成主键值
ResultSet set = prestmt.getGeneratedKeys();
int i = -1;
while (set.next()) {
T entity = entitys[++i];
if (primaryType == int.class || primaryType == Integer.class) {
primary.set(entity, set.getInt(1));
} else if (primaryType == long.class || primaryType == long.class) {
primary.set(entity, set.getLong(1));
} else if (primaryType == String.class) {
primary.set(entity, set.getString(1));
} else {
primary.set(entity, set.getObject(1));
}
}
set.close();
}
conn.offerUpdateStatement(prestmt);
} else { //分库分表
for (PreparedStatement stmt : prestmts) {
@@ -501,6 +563,28 @@ public class DataJdbcSource extends AbstractDataSqlSource {
c1 += Utility.sum(stmt.executeBatch());
}
c = c1;
if (info.isAutoGenerated()) { //由数据库自动生成主键值
int j = -1;
for (Map.Entry<String, PrepareInfo<T>> en : prepareInfos.entrySet()) {
PrepareInfo<T> prepareInfo = en.getValue();
PreparedStatement stmt = prestmts.get(++j);
ResultSet set = stmt.getGeneratedKeys();
int i = -1;
while (set.next()) {
T entity = prepareInfo.entitys.get(++i);
if (primaryType == int.class || primaryType == Integer.class) {
primary.set(entity, set.getInt(1));
} else if (primaryType == long.class || primaryType == long.class) {
primary.set(entity, set.getLong(1));
} else if (primaryType == String.class) {
primary.set(entity, set.getString(1));
} else {
primary.set(entity, set.getObject(1));
}
}
set.close();
}
}
for (PreparedStatement stmt : prestmts) {
conn.offerUpdateStatement(stmt);
}
@@ -2897,6 +2981,10 @@ public class DataJdbcSource extends AbstractDataSqlSource {
return conn.prepareStatement(sql);
}
public PreparedStatement prepareUpdateStatement(String sql, int resultSetType) throws SQLException {
return conn.prepareStatement(sql, resultSetType);
}
public void offerUpdateStatement(final PreparedStatement stmt) throws SQLException {
stmt.close();
}

View File

@@ -67,4 +67,11 @@ public interface DataSqlSource extends DataSource {
});
}
default Map<String, String> executeQueryStrStrMap(String sql) {
return executeQueryMap(String.class, String.class, sql);
}
default Map<Integer, String> executeQueryIntStrMap(String sql) {
return executeQueryMap(Integer.class, String.class, sql);
}
}

View File

@@ -72,6 +72,9 @@ public final class EntityInfo<T> {
//DDL字段
final EntityColumn[] primaryColumnOneArray;
//是否由数据库生成主键值
private final boolean autoGenerated;
//DDL字段集合
final EntityColumn[] ddlColumns;
@@ -381,6 +384,7 @@ public final class EntityInfo<T> {
} catch (Exception e) {
logger.log(Level.SEVERE, type + " cannot find ConstructorParameters Creator", e);
}
boolean auto = false;
String[] constructorParameters = cps;
Attribute idAttr0 = null;
Map<String, String> aliasmap = null;
@@ -431,9 +435,12 @@ public final class EntityInfo<T> {
boolean idFlag = field.getAnnotation(Id.class) != null || field.getAnnotation(javax.persistence.Id.class) != null;
if (idFlag && idAttr0 == null) {
auto = field.getAnnotation(GeneratedValue.class) != null;
idAttr0 = attr;
insertCols.add(sqlField);
insertAttrs.add(attr);
if (!auto) {
insertCols.add(sqlField);
insertAttrs.add(attr);
}
RedkaleClassLoader.putReflectionField(cltmp.getName(), field);
} else {
if (col == null || col.insertable()) {
@@ -488,6 +495,7 @@ public final class EntityInfo<T> {
} while ((cltmp = cltmp.getSuperclass()) != Object.class);
this.jsonConvert = convert == null ? DEFAULT_JSON_CONVERT : convert;
this.autoGenerated = auto;
this.primary = idAttr0;
this.primaryOneArray = new Attribute[]{this.primary};
List<EntityColumn> ddls = new ArrayList<>();
@@ -777,6 +785,10 @@ public final class EntityInfo<T> {
return table == null;
}
public boolean isAutoGenerated() {
return autoGenerated;
}
public DistributeTableStrategy<T> getTableStrategy() {
return tableStrategy;
}