我正在开发Java 6(及更高版本)中的玩具数据访问机制。每个模型类都应该有一个findById
静态方法,该方法应该从具有指定id的行中实例化一个对象。我想出了下面显示的方法。我的方法被认为是好的做法吗?如果没有,可以改进什么?
数据库(MySQL)引导脚本:
create database test;
create user test identified by 'test';
grant all on test.* to test;
use test;
create table products(id integer,name varchar(10));
insert into products values(1,'led');
源代码:
import java.sql.*;
class Test {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
Product p = Product.findById(1);
System.out.println(p.id + " " + p.name);
}
}
class Database {
static <T extends Model<T>> T findById(T m, String sql, int id) throws SQLException {
try (Connection conn = DriverManager.getConnection("jdbc:mysql:///test", "test", "test");
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, id);
try (ResultSet rs = stmt.executeQuery()) {
rs.next();
m.load(rs);
}
}
return m;
}
}
abstract class Model<T> {
abstract void load(ResultSet rs) throws SQLException;
}
class Product extends Model<Product> {
int id;
String name;
static Product findById(int id) throws SQLException {
return Database.findById(new Product(), "select * from products where id=?", id);
}
@Override
void load(ResultSet rs) throws SQLException {
this.id = rs.getInt("id");
this.name = rs.getString("name");
}
}
答案 0 :(得分:2)
我宁愿使用基于DAO的方法。您需要使用基本的CRUD方法创建一个GenericDao<T>
类,并且所有派生的DAO类都将具有指定实体类的开箱即用CRUD功能。
这里有两篇展示所描述技术的文章: http://www.codeproject.com/Articles/251166/The-Generic-DAO-pattern-in-Java-with-Spring-3-and http://www.ibm.com/developerworks/java/library/j-genericdao/index.html
答案 1 :(得分:2)
您正在混淆顾虑和责任,在您的实体(Product
)和数据访问层之间引入紧密耦合。
你应该分开
ProductDao
)提供接口,以及要执行的方法来检索/存储/删除实体。然后,您可以使用您选择的技术(在您的情况下为JDBC)具体实现这些。因此,如果您以后想要更改数据访问技术,则可以使用其他实现(JdbcProductDao
和HibernateProductDao
)。您甚至可能希望更进一步,并将DAO层与实际存储库层分离,但这可能被视为过早优化,具体取决于系统中不同实体类的数量。
这有很多好处:
此外,尝试在任何地方使用通用方法并不一定是个好主意:通常你会发现你想要的findById
对于你的每个实体都略有不同,其中一些不适合你在Database
中描述的泛型方法(我甚至没有提到它是一种静态方法,这是一种难闻的气味)。在我现在的团队中,我们使用三个规则:只有当你编写系统中可以从中受益的第三个元素时,才会引入重构的泛型类/方法。另外我们认为它过早优化。
答案 2 :(得分:1)
我喜欢基本设计。但是对于一个真正的生产项目,我会做3个改变:
答案 3 :(得分:0)
您正在重新发明对象关系映射(ORM)和数据访问对象(DAO)方法。存在许多Java库,它们完全按照您在此处执行的操作,例如Hibernate。我想你可能会发现这个库比得到这个问题的正确答案更有用。