mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
#74 fixed null handling in batch inserts
This commit is contained in:
parent
a3ab07f9fe
commit
aa4e49cf9a
@ -1,7 +1,7 @@
|
||||
----------------------------------------------------------------
|
||||
Sun Nov 20 21:21:36 EET 2011:
|
||||
Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0133-c26d-3187-000002b80608
|
||||
on database directory /home/tiwe/work/querydsl/querydsl-sql/target/demoDB with class loader sun.misc.Launcher$AppClassLoader@1a16869
|
||||
Wed Feb 08 17:05:09 EET 2012:
|
||||
Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0135-5d7f-29ad-000002c981b8
|
||||
on database directory /home/tiwe/work/querydsl/querydsl-sql/target/demoDB with class loader sun.misc.Launcher$AppClassLoader@1cde100
|
||||
Loaded from file:/home/tiwe/.m2/repository/org/apache/derby/derby/10.8.2.2/derby-10.8.2.2.jar
|
||||
java.vendor=Sun Microsystems Inc.
|
||||
java.runtime.version=1.6.0_26-b03
|
||||
|
||||
@ -21,6 +21,8 @@ import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mysema.query.sql.types.Null;
|
||||
|
||||
/**
|
||||
* JDBCTypeMapping defines a mapping from JDBC types to Java classes.
|
||||
*
|
||||
@ -76,7 +78,7 @@ public final class JDBCTypeMapping {
|
||||
registerDefault(Types.DISTINCT, Object.class);
|
||||
registerDefault(Types.DATALINK, Object.class);
|
||||
registerDefault(Types.JAVA_OBJECT, Object.class);
|
||||
registerDefault(Types.NULL, Object.class);
|
||||
registerDefault(Types.NULL, Null.class);
|
||||
registerDefault(Types.OTHER, Object.class);
|
||||
registerDefault(Types.REF, Object.class);
|
||||
registerDefault(Types.ROWID, Object.class);
|
||||
|
||||
@ -20,7 +20,27 @@ import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mysema.commons.lang.Pair;
|
||||
import com.mysema.query.sql.types.*;
|
||||
import com.mysema.query.sql.types.BigDecimalType;
|
||||
import com.mysema.query.sql.types.BlobType;
|
||||
import com.mysema.query.sql.types.BooleanType;
|
||||
import com.mysema.query.sql.types.ByteType;
|
||||
import com.mysema.query.sql.types.BytesType;
|
||||
import com.mysema.query.sql.types.CharacterType;
|
||||
import com.mysema.query.sql.types.ClobType;
|
||||
import com.mysema.query.sql.types.DateType;
|
||||
import com.mysema.query.sql.types.DoubleType;
|
||||
import com.mysema.query.sql.types.FloatType;
|
||||
import com.mysema.query.sql.types.IntegerType;
|
||||
import com.mysema.query.sql.types.LongType;
|
||||
import com.mysema.query.sql.types.NullType;
|
||||
import com.mysema.query.sql.types.ObjectType;
|
||||
import com.mysema.query.sql.types.ShortType;
|
||||
import com.mysema.query.sql.types.StringType;
|
||||
import com.mysema.query.sql.types.TimeType;
|
||||
import com.mysema.query.sql.types.TimestampType;
|
||||
import com.mysema.query.sql.types.Type;
|
||||
import com.mysema.query.sql.types.URLType;
|
||||
import com.mysema.query.sql.types.UtilDateType;
|
||||
import com.mysema.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
@ -53,6 +73,7 @@ public class JavaTypeMapping {
|
||||
registerDefault(new TimeType());
|
||||
registerDefault(new URLType());
|
||||
registerDefault(new UtilDateType());
|
||||
registerDefault(new NullType());
|
||||
|
||||
// initialize joda time converters only if joda time is available
|
||||
try {
|
||||
|
||||
@ -36,7 +36,8 @@ public class ForeignKeyBuilder {
|
||||
|
||||
private final SQLTemplates templates;
|
||||
|
||||
public ForeignKeyBuilder(CreateTableClause clause, SQLTemplates templates, List<ForeignKeyData> foreignKeys, String name, String[] columns) {
|
||||
public ForeignKeyBuilder(CreateTableClause clause, SQLTemplates templates,
|
||||
List<ForeignKeyData> foreignKeys, String name, String[] columns) {
|
||||
this.clause = clause;
|
||||
this.templates = templates;
|
||||
this.foreignKeys = foreignKeys;
|
||||
|
||||
@ -47,7 +47,8 @@ public class AbstractSQLClause {
|
||||
* @param constantPaths list of paths related to the constants
|
||||
* @param params map of param to value for param resolving
|
||||
*/
|
||||
protected void setParameters(PreparedStatement stmt, List<?> objects, List<Path<?>> constantPaths, Map<Param<?>, ?> params) {
|
||||
protected void setParameters(PreparedStatement stmt, List<?> objects,
|
||||
List<Path<?>> constantPaths, Map<Param<?>, ?> params) {
|
||||
if (objects.size() != constantPaths.size()) {
|
||||
throw new IllegalArgumentException("Expected " + objects.size() + " paths, but got " + constantPaths.size());
|
||||
}
|
||||
|
||||
@ -42,9 +42,9 @@ import com.mysema.query.sql.Configuration;
|
||||
import com.mysema.query.sql.RelationalPath;
|
||||
import com.mysema.query.sql.SQLSerializer;
|
||||
import com.mysema.query.sql.SQLTemplates;
|
||||
import com.mysema.query.sql.types.Null;
|
||||
import com.mysema.query.types.ConstantImpl;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.NullExpression;
|
||||
import com.mysema.query.types.Path;
|
||||
import com.mysema.query.types.SubQueryExpression;
|
||||
import com.mysema.query.types.expr.Param;
|
||||
@ -84,12 +84,14 @@ public class SQLInsertClause extends AbstractSQLClause implements InsertClause<S
|
||||
this(connection, new Configuration(templates), entity);
|
||||
}
|
||||
|
||||
public SQLInsertClause(Connection connection, SQLTemplates templates, RelationalPath<?> entity, AbstractSQLSubQuery<?> subQuery) {
|
||||
public SQLInsertClause(Connection connection, SQLTemplates templates, RelationalPath<?> entity,
|
||||
AbstractSQLSubQuery<?> subQuery) {
|
||||
this(connection, new Configuration(templates), entity);
|
||||
this.subQueryBuilder = subQuery;
|
||||
}
|
||||
|
||||
public SQLInsertClause(Connection connection, Configuration configuration, RelationalPath<?> entity, AbstractSQLSubQuery<?> subQuery) {
|
||||
public SQLInsertClause(Connection connection, Configuration configuration, RelationalPath<?> entity,
|
||||
AbstractSQLSubQuery<?> subQuery) {
|
||||
this(connection, configuration, entity);
|
||||
this.subQueryBuilder = subQuery;
|
||||
}
|
||||
@ -225,7 +227,8 @@ public class SQLInsertClause extends AbstractSQLClause implements InsertClause<S
|
||||
serializer.serializeForInsert(metadata, entity, columns, values, subQuery);
|
||||
stmt = prepareStatementAndSetParameters(serializer, withKeys);
|
||||
} else {
|
||||
serializer.serializeForInsert(metadata, entity, batches.get(0).getColumns(), batches.get(0).getValues(), batches.get(0).getSubQuery());
|
||||
serializer.serializeForInsert(metadata, entity, batches.get(0).getColumns(),
|
||||
batches.get(0).getValues(), batches.get(0).getSubQuery());
|
||||
stmt = prepareStatementAndSetParameters(serializer, withKeys);
|
||||
|
||||
// add first batch
|
||||
@ -243,7 +246,8 @@ public class SQLInsertClause extends AbstractSQLClause implements InsertClause<S
|
||||
return stmt;
|
||||
}
|
||||
|
||||
private PreparedStatement prepareStatementAndSetParameters(SQLSerializer serializer, boolean withKeys) throws SQLException {
|
||||
private PreparedStatement prepareStatementAndSetParameters(SQLSerializer serializer,
|
||||
boolean withKeys) throws SQLException {
|
||||
queryString = serializer.toString();
|
||||
logger.debug(queryString);
|
||||
PreparedStatement stmt;
|
||||
@ -252,7 +256,8 @@ public class SQLInsertClause extends AbstractSQLClause implements InsertClause<S
|
||||
} else {
|
||||
stmt = connection.prepareStatement(queryString);
|
||||
}
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), Collections.<Param<?>,Object>emptyMap());
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(),
|
||||
Collections.<Param<?>,Object>emptyMap());
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@ -322,7 +327,8 @@ public class SQLInsertClause extends AbstractSQLClause implements InsertClause<S
|
||||
}else if (value != null) {
|
||||
values.add(new ConstantImpl<T>(value));
|
||||
} else {
|
||||
values.add(new NullExpression<T>(path.getType()));
|
||||
//values.add(new NullExpression<T>(path.getType()));
|
||||
values.add(Null.CONSTANT);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -337,7 +343,8 @@ public class SQLInsertClause extends AbstractSQLClause implements InsertClause<S
|
||||
@Override
|
||||
public <T> SQLInsertClause setNull(Path<T> path) {
|
||||
columns.add(path);
|
||||
values.add(new NullExpression<T>(path.getType()));
|
||||
//values.add(new NullExpression<T>(path.getType()));
|
||||
values.add(Null.CONSTANT);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -349,7 +356,7 @@ public class SQLInsertClause extends AbstractSQLClause implements InsertClause<S
|
||||
} else if (value != null) {
|
||||
values.add(new ConstantImpl<Object>(value));
|
||||
} else {
|
||||
values.add(NullExpression.DEFAULT);
|
||||
values.add(Null.CONSTANT);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
||||
@ -186,7 +186,8 @@ public class SQLMergeClause extends AbstractSQLClause implements StoreClause<SQL
|
||||
queryString = serializer.toString();
|
||||
logger.debug(queryString);
|
||||
stmt = connection.prepareStatement(queryString);
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), Collections.<Param<?>,Object>emptyMap());
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(),
|
||||
Collections.<Param<?>,Object>emptyMap());
|
||||
} else {
|
||||
serializer.serializeForMerge(metadata, entity,
|
||||
batches.get(0).getKeys(), batches.get(0).getColumns(),
|
||||
@ -194,7 +195,8 @@ public class SQLMergeClause extends AbstractSQLClause implements StoreClause<SQL
|
||||
queryString = serializer.toString();
|
||||
logger.debug(queryString);
|
||||
stmt = connection.prepareStatement(queryString);
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), Collections.<Param<?>,Object>emptyMap());
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(),
|
||||
Collections.<Param<?>,Object>emptyMap());
|
||||
|
||||
// add first batch
|
||||
stmt.addBatch();
|
||||
|
||||
@ -128,7 +128,8 @@ public class SQLUpdateClause extends AbstractSQLClause implements UpdateClause<
|
||||
queryString = serializer.toString();
|
||||
logger.debug(queryString);
|
||||
stmt = connection.prepareStatement(queryString);
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), Collections.<Param<?>,Object>emptyMap());
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(),
|
||||
Collections.<Param<?>,Object>emptyMap());
|
||||
} else {
|
||||
SQLSerializer serializer = new SQLSerializer(configuration.getTemplates(), true);
|
||||
serializer.serializeForUpdate(batchMetadata.get(0), entity, batchUpdates.get(0));
|
||||
@ -137,14 +138,16 @@ public class SQLUpdateClause extends AbstractSQLClause implements UpdateClause<
|
||||
|
||||
// add first batch
|
||||
stmt = connection.prepareStatement(queryString);
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), Collections.<Param<?>,Object>emptyMap());
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(),
|
||||
Collections.<Param<?>,Object>emptyMap());
|
||||
stmt.addBatch();
|
||||
|
||||
// add other batches
|
||||
for (int i = 1; i < batchUpdates.size(); i++) {
|
||||
serializer = new SQLSerializer(configuration.getTemplates(), true, true);
|
||||
serializer.serializeForUpdate(batchMetadata.get(i), entity, batchUpdates.get(i));
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), Collections.<Param<?>,Object>emptyMap());
|
||||
setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(),
|
||||
Collections.<Param<?>,Object>emptyMap());
|
||||
stmt.addBatch();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2011, Mysema Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mysema.query.sql.types;
|
||||
|
||||
import com.mysema.query.types.Constant;
|
||||
import com.mysema.query.types.ConstantImpl;
|
||||
|
||||
/**
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public final class Null {
|
||||
|
||||
public static final Null DEFAULT = new Null();
|
||||
|
||||
public static final Constant<Null> CONSTANT = new ConstantImpl<Null>(DEFAULT);
|
||||
|
||||
private Null() {}
|
||||
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2011, Mysema Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mysema.query.sql.types;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public class NullType extends AbstractType<Null> {
|
||||
|
||||
public NullType() {
|
||||
super(Types.OTHER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Null> getReturnedClass() {
|
||||
return Null.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Null getValue(ResultSet rs, int startIndex) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(PreparedStatement st, int startIndex, Null value) throws SQLException {
|
||||
int type = st.getParameterMetaData().getParameterType(startIndex);
|
||||
st.setNull(startIndex, type);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -60,8 +60,7 @@ public abstract class InsertBaseTest extends AbstractBaseTest{
|
||||
|
||||
@Test
|
||||
public void Insert_Without_Columns() {
|
||||
assertEquals(1, insert(survey)
|
||||
.values(4, "Hello").execute());
|
||||
assertEquals(1, insert(survey).values(4, "Hello").execute());
|
||||
|
||||
}
|
||||
|
||||
@ -109,6 +108,22 @@ public abstract class InsertBaseTest extends AbstractBaseTest{
|
||||
assertEquals(1l, query().from(survey).where(survey.name.eq("66")).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Insert_Nulls_In_Batch() {
|
||||
// QFoo f= QFoo.foo;
|
||||
// SQLInsertClause sic = new SQLInsertClause(c, new H2Templates(), f);
|
||||
// sic.columns(f.c1,f.c2).values(null,null).addBatch();
|
||||
// sic.columns(f.c1,f.c2).values(null,1).addBatch();
|
||||
// sic.execute();
|
||||
SQLInsertClause sic = insert(survey);
|
||||
sic.columns(survey.id, survey.name).values(null, null).addBatch();
|
||||
sic.columns(survey.id, survey.name).values(null, 1).addBatch();
|
||||
System.out.println("start batch");
|
||||
sic.execute();
|
||||
System.out.println("end batch");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Like_with_Escape(){
|
||||
SQLInsertClause insert = insert(survey);
|
||||
|
||||
@ -76,7 +76,7 @@ public class SerializationTest {
|
||||
SQLInsertClause insertClause = new SQLInsertClause(connection,SQLTemplates.DEFAULT,survey);
|
||||
insertClause.set(survey.id, 1);
|
||||
insertClause.set(survey.name, (String)null);
|
||||
assertEquals("insert into SURVEY(ID, NAME)\nvalues (?, null)", insertClause.toString());
|
||||
assertEquals("insert into SURVEY(ID, NAME)\nvalues (?, ?)", insertClause.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
Reference in New Issue
Block a user