Java& SQL - 带有'toString()方法

时间:2016-12-08 18:41:34

标签: java sql resultset tostring

我有一个名为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());等进行调试却没有成功。

2 个答案:

答案 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对象。相信我,当我说它从长远来看使一切变得更容易。

https://softwareengineering.stackexchange.com/questions/261585/should-a-getter-throw-an-exception-if-its-object-has-invalid-state

<小时/>

实验解决方案

如果必须自动使用SQL列(无需指定每列),可以使用反射,但它相当脆弱。仅在满足以下条件时才有效:

  • Java对象上的属性名称与SQL列
  • 完全相同
  • Java对象上的属性类型是ResultSet中的默认类型(原语到Wrapper类都可以)

可以将反射部分放入基类中以扩展到其他地方。在这里,我称之为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

希望这可以帮到你。