我有以下功能:
public Map<Integer, Product> fetchAllProducts() {
Map<Integer, Product> pArr = new HashMap();
try {
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT id, intro, content, price FROM Product");
while (rs.next()) {
pArr.put(rs.getInt("id"), new Product(rs));
}
st.close();
} catch (SQLException ex) {
//...
}
return pArr;
}
从mySQL表Product
获取所有行,并为每行创建一个新的Product
类。产品构造函数:
public Product(ResultSet rs) {
try {
price = rs.getInt("price");
content = rs.getString("content");
intro = rs.getString("intro");
} catch (SQLException ex) {
//...
}
}
我的问题是:有没有更好的方法将结果列分配给Product
中的变量?代码price = rs.getInt("price");
等似乎是多余的,不是吗?完美的是,如果我将查询语句更改为SELECT intro, content, tax, delivery FROM ...
,构造函数会自动将其分配给构造函数中的适当变量(即intro,content,tax,delivery)。这可以用Java完成,还是我只是在做梦?
答案 0 :(得分:3)
首先:你真的不应该将ResultSet
传递给Product
的构造函数!您应该从业务逻辑中干净地划分数据库访问代码。
通常我希望在您的代码中看到这一点:
private static final String TABLE_NAME = "product";
private static final String ID_COLUMN = "id";
private static final String INTRO_COLUMN = "intro";
private static final String CONTENT_COLUMN = "content";
private static final String PRICE_COLUMN = "price";
private static final String FETCHALLPRODUCTS_QUERY = String.format("SELECT %s, %s, %s, %s FROM %s", ID_COLUMN, INTRO_COLUMN, CONTENT_COLUMN, PRICE_COLUMN, TABLE_NAME);
public Map<Integer, Product> fetchAllProducts() {
Map<Integer, Product> pArr = new HashMap();
try {
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(FETCHALLPRODUCTS_QUERY);
while (rs.next()) {
Integer price = rs.getInt(PRICE_COLUMN);
String content = rs.getString(CONTENT_COLUMN);
String intro = rs.getString(INTRO_COLUMN);
Product product = new Product(price, content, intro);
Integer id = rs.getInt(ID_COLUMN);
pArr.put(id, product);
}
st.close();
} catch (SQLException ex) {
//...
}
return pArr;
}
但回答你的问题:在处理普通JDBC时,这样做很常见。你要找的是一个ORM框架,如Hibernate。
使用JDBC连接时我正在做的一件事是声明列名和表名的常量。这样我觉得它有点清洁。
答案 1 :(得分:3)
你可以在Reflection的帮助下实现这一目标,ResultSetMapper也是如此。
一个tutorial。
Apache BeanUtils有类似之处,但它会返回DynaBean。
如果你可以转向更复杂和完整的系统,你应该考虑使用像hibernate,JPA这样的ORM。
对于普通的JDBC,您可以使用自己的反射工具,也可以使用ResultMapper。
答案 2 :(得分:0)
我认为如果你使用例如hibernate,这是可能的。 但是像我的前言一样写:不要在Product的构造函数中设置ResultSet,因为你将在ResultSet的另一个副本上工作(ResultSet很重),如果你有很多数据,那就缩小了性能。
所以就这样做:
...
pArr.put(rs.getInt("id"), new Product(rs.getint("Price") ....));
...
public Product(int price ....) {
答案 3 :(得分:0)
我想使用一些或映射库(如Hibernate)会使代码更加愉快。正如我所听到的那样,它可以让你想要的东西很常见。但是,使用它涉及替换项目中的所有数据库交互代码。我认为你的代码并不是那么难看,可能这样做会让它变得更加愉快:
while (rs.next()) {
pArr.put(rs.getInt("id"), new Product(rs));
Integer id = rs.getInt("id");
Integer price = rs.getInt("price");
Integer content = rs.getString("content");
Integer intro = rs.getString("intro");
Product product = new Product(price, content, intro);
pArr.put(id, product);
}
嗯,似乎在我输入答案时,出现了三个相同的答案。对不起伙计:)
答案 4 :(得分:0)
Commons DbUtils,它是顶级JDBC上的一个薄层(不像Hibernate那样涉及)set bean properties from a ResultSet。