你的目标
您在 cmets 中提到您的目标是为遗留数据库编写 SQL 请求:
类型:VARCHAR,数字:INT,字符串:VARCHAR,日期:DATETIME 和
ExclusiveField 将用作 getQueryRunner().query("CALL
sp_insert_parameter(?, ?, ?, ?, ?)", param.getNumericParam(), id,
类型,param.getStringParam(),param.getDateParam())
所以你的目标真的不是创建一个只有一个非空字段的类。
另类
您可以使用id, type, value 属性定义一个抽象类Field:
public abstract class Field
{
private int id;
private Class<?> type;
private Object value;
public Field(int id, Object value) {
this.id = id;
this.type = value.getClass();
this.value = value;
}
public abstract int getPosition();
}
为数据库中的每一列创建一个小的对应类,扩展Field。每个类都定义了它想要的类型和它在 SQL 命令中的位置:
import java.math.BigInteger;
public class BigIntegerField extends Field
{
public BigIntegerField(int id, BigInteger numericParam) {
super(id, numericParam);
}
@Override
public int getPosition() {
return 0;
}
}
你可以定义Field#toSQL:
public String toSQL(int columnsCount) {
List<String> rows = new ArrayList<>(Collections.nCopies(columnsCount, "NULL"));
rows.set(getPosition(), String.valueOf(value));
return String.format("SOME SQL COMMAND (%d, %s, %s)", id, type.getName(), String.join(", ", rows));
}
它将在除所需位置之外的所有位置输出 NULLS。
就是这样。
完整代码
Field.java
package com.stackoverflow.legacy_field;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public abstract class Field
{
private int id;
private Class<?> type;
private Object value;
public Field(int id, Object value) {
this.id = id;
this.type = value.getClass();
this.value = value;
}
public abstract int getPosition();
public static void main(String[] args) {
List<Field> fields = Arrays.asList(new BigIntegerField(3, BigInteger.TEN),
new StringField(17, "FooBar"),
new DateTimeField(21, LocalDateTime.now()));
for (Field field : fields) {
System.out.println(field.toSQL(3));
}
}
public String toSQL(int columnsCount) {
List<String> rows = new ArrayList<>(Collections.nCopies(columnsCount, "NULL"));
rows.set(getPosition(), String.valueOf(value));
return String.format("SOME SQL COMMAND (%d, %s, %s)", id, type.getName(), String.join(", ", rows));
}
}
BigIntegerField.java
package com.stackoverflow.legacy_field;
import java.math.BigInteger;
public class BigIntegerField extends Field
{
public BigIntegerField(int id, BigInteger numericParam) {
super(id, numericParam);
}
@Override
public int getPosition() {
return 0;
}
}
StringField.java
package com.stackoverflow.legacy_field;
public class StringField extends Field
{
public StringField(int id, String stringParam) {
super(id, stringParam);
}
@Override
public int getPosition() {
return 1;
}
}
DateTimeField.java
package com.stackoverflow.legacy_field;
import java.time.LocalDateTime;
public class DateTimeField extends Field
{
public DateTimeField(int id, LocalDateTime value) {
super(id, value);
}
@Override
public int getPosition() {
return 2;
}
}
结果
启动Field#main 输出:
SOME SQL COMMAND (3, java.math.BigInteger, 10, NULL, NULL)
SOME SQL COMMAND (17, java.lang.String, NULL, FooBar, NULL)
SOME SQL COMMAND (21, java.time.LocalDateTime, NULL, NULL, 2019-05-09T09:39:56.062)
这应该非常接近您想要的输出。如果需要,您可能会找到更好的名称并定义特定的 toString() 方法。