我有一个名为Item的类,除了其他所有内容之外,它还定义了这样的toString方法:
@Override
public String toString() {
return "Item [id=" + id + ", name=" + name + ", type=" + type + "]";
}
然后我有一个SQL连接器,用于转储表中的所有项目,如下所示:
public ArrayList<Item> dumpAll() {
ArrayList<Item> dump = new ArrayList<Item>();
connectDB();
try {
result = connectDB().prepareStatement("SELECT * FROM Items").executeQuery();
if (result != null) {
connectDB().close();
while (result.next()) {
Item item = new Item();
item.toString();
dump.add(item);
}
}
} catch (Exception e) {
System.out.println("Query failed.");
// e.printStackTrace();
}
return dump;
}
connectDB();
工作正常。当我在其他地方调用toString方法时,我可以看到如下结果:
Item [id=0, name=null, type=null]
这一行重复的次数与表中的项目一样多,即我有50个项目;我得到50行显示零和空值。格式完全按照我的要求,但显然结果不是。我想我错过了处理result
的明显问题,但尝试使用String itm = result.toString();
,Item.equals(result.toString());
等进行调试却没有成功。
答案 0 :(得分:2)
这是你的
createThing(panel)
.flatMap(channel -> createOrUpdateItem(channel).toObservable(),
(channel, item) -> linkItemToChannel(item.name, channel.uid))
.ignoreElements() // converts to Completable
线。这说:&#34;初始化一个没有的物品!&#34;所以你当然有空物品。它应该是:
Item item = new Item();
或者在SQL表中为它们提供的任何列名。
允许无效对象的不良做法。您不应该为Item对象设置默认构造函数,因为永远不会有包含无效数据的Item对象。相信我,当我说它从长远来看使一切变得更容易。
<小时/>
如果必须自动使用SQL列(无需指定每列),可以使用反射,但它相当脆弱。仅在满足以下条件时才有效:
可以将反射部分放入基类中以扩展到其他地方。在这里,我称之为SimpleSQL。 (这有一种明显的感觉,我对这个答案过于聪明。我对这段代码不负任何责任;它纯粹被表现为&#34;你可以这样做&#34;场景)
Item item = new Item(result.getInt(0), result.getString(1), result.getString(2));
(参见more on toString and reflection here。tl; dr,Apache Commons库提供了一个ReflectionToStringBuilder类,用于更好的toString()版本)
然后您可以将项目定义为:
import java.lang.reflect.*;
import java.sql.ResultSet;
public class SimpleSQL {
public SimpleSQL(ResultSet result) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
for (Field f: getClass().getDeclaredFields()) {
// Get the field type name, converting the first character to uppercase
String fTypNam = f.getType().getSimpleName();
fTypNam = fTypNam.substring(0,1).toUpperCase() + fTypNam.substring(1);
// Get an object that represents each of the methods we want to call
Method getM = result.getClass().getMethod("get" + fTypNam, String.class);
Method setM = f.getClass().getMethod("set", Object.class, Object.class);
// Set the property of this object using the field object's set
// and the ResultSet's get.
setM.invoke(f, this, getM.invoke(result, f.getName()));
// For a hypothetical 'id' field that is an int, this is equivalent to:
// this.id = result.getInt("id");
}
}
@Override
public String toString() {
String result = getClass().getName()+"[";
try {
Field[] fields = getClass().getDeclaredFields();
result += fields[0].getName() + ": " + fields[0].get(this);
for(int i = 1; i < fields.length; ++i) {
result += ", " + fields[i].getName() + ": " + fields[i].get(this);
}
} catch(IllegalAccessException e) {
// This happens if the field is private.
throw new RuntimeException(e.getMessage());
}
result += "]";
return result;
}
}
答案 1 :(得分:1)
你的Item类应该有setters()
,constructor()
,toString()
和public class Item {
private int id;
private String name;
private String type;
public Item(int id, String name, String type) {
this.id = id;
this.name = name;
this.type = type;
}
//...Getters and Setters
@Override
public String toString() {
return "Item [id=" + id + ", name=" + name + ", type=" + type + "]";
}
}
这样的方法:
while (result.next()) {
Item item = new Item(result.getInt("id"), result.getString("name"), result.getString("type"));
item.toString();
}
所以在那之后你应该创建一个像这样的对象:
@echo off
setlocal
set rand=%random%
md "dummy%rand%\empty%rand%"
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set /a y=%dt:~0,4%
set /a m=1%dt:~4,2%
set /a d=1%dt:~6,2%
REM set the number of days to substract
SET DAYS=4
FOR /L %%G IN (1,1,%days%) DO CALL :loop
set subdate=%y%%m:~-2%%d:~-2%
echo %subdate%
rd /s /q "dummy%rand%"
pause
endlocal
GOTO :EOF
:loop
set /a d-=1
if %d% lss 101 (
set d=131
set /a m-=1
if %m% lss 101 (
set m=112
set /a y-=1
)
)
xcopy /d:%m:~-2%-%d:~-2%-%y% /t "dummy%rand%\empty%rand%" "dummy%rand%" >nul 2>&1 || goto loop
GOTO :EOF
希望这可以帮到你。