0

我是 Java 新手,我正在尝试实现一个基本的数据库访问层。我正在使用 Apache DBUtils 来减少 JDBC 样板代码,这非常有效。

问题是我的实现对数据库中的每个表都使用了一个单独的 CRUD 类,并且复制这么多功能感觉不对。

这是一个可接受的设计吗?如果不是,我可以做些什么来减少代码重复?
我可以重构我的解决方案以某种方式使用泛型吗?

我意识到我可以使用 ORM(myBatis、Hibernate 等)作为解决方案,但如果我能提供帮助,我想尝试坚持使用 DBUtils 和纯 JDBC。

只是为了澄清:
假设我有 2 张桌子......

---------------------  
User    |  File  
---------------------  
userId  |  fileId  
name    |  path  
age     |  size  
---------------------  

在我当前的解决方案中,我将创建 2 个类(UserStore、FileStore),每个类都将实现类似的基本 CRUD 方法:

protected boolean Create(User newUser)
{
    QueryRunner run = new QueryRunner(dataSource);
    try 
    {
        run.update("INSERT INTO User (name, age) " +
                "VALUES (?, ?)", newUser.getName(), newUser.getAge()); 
    }
    catch (SQLException ex) 
    {
        Log.logException(ex);
        return false;
    }
    return true;
}

protected User Read(int userId)
{
    try
    {
        User user = run.query("SELECT * FROM User WHERE userId = ? ", userId);
        return user;
    }
    catch (SQLException ex) 
    {
        Log.logException(ex);
        return null;
    }
}

protected update(User user)
{
    ... perform database query etc
}

protected delete(int userId)
{
    ... perform database query etc
}
4

4 回答 4

0

mybatis 允许您将结果类型作为 hashmap 返回:

<select id="mCount" resultType="hashmap"> select managerName, count(reportees) AS count from mgr_employee group by managerName; </select>

所以你可以有效地写出这样的工作流程:1)开发接口2a)使用mybatis注释定义所需的查询或2b)将接口链接到xml并编写查询

请注意,这不会涉及任何 DAO 和其他样板文件,如上所述

于 2013-06-01T14:25:43.657 回答
0

使用 DBUtils,您已经抽象出许多样板代码。剩下的主要是实体之间不同的工作:正确的 sql 语句,将实体对象转换为 UPDATE 参数,反之亦然,SELECT,异常处理。

不幸的是,要为这些剩余任务创建一个足够灵活的通用抽象并不容易。这就是 ORM 映射器的全部意义所在。我仍然建议研究其中之一。如果您坚持使用 JPA API,那么您仍然处于标准领域,并且能够更轻松地切换 ORM 提供程序(尽管总是存在一些耦合)。SpringData 的 Repository 抽象给我留下了深刻的印象。在简单的用例中,它们为您提供代码 DAO。如果您已经在使用 Spring 并且只想保留您的对象模型,那么您绝对应该研究它。

或者,我用jooq做了一些很好的体验。它还可以根据架构中的表创建 DTO 和相应的 DAO。与 ORM 映射器相比,它更接近关系模式,这可能是优点或缺点。

于 2013-05-13T09:14:46.933 回答
0

看起来我可以为您的问题提供一些简单的建议。

1)

与其像您正在做的那样管理 DAO 内部的查询,不如创建一个包含满足您需求的查询列表的工厂类。

喜欢

class QueryFactory {
  static String INSERT_BOOK = "BLAH";
  static String DELETE_BOOK = "BLAH";
}

这会将查询与 DAO 代码分开并使其更易于管理。

2)

实现一个通用的 DAO

http://www.codeproject.com/Articles/251166/The-Generic-DAO-pattern-in-Java-with-Spring-3-and

3) 正如你上面提到的,使用 ORM 来帮助自己将 bean 绑定到数据库和更多功能。

于 2013-05-13T09:14:38.123 回答
0

你问我如何使用模板方法来做到这一点。这是一个示例,您可以如何做到这一点:

public class AbstractDAO<T> {
private String table;
private String id_field;

public AbstractDAO(String table, String id_field){
this.table = table;
...
}

public T read(int id){
    try
{
    T user = run.query("SELECT * FROM "+ table + " WHERE "+id_field +" = ? ", id);
    return user;
}
catch (SQLException ex) 
{
    Log.logException(ex);
    return null;
}
}

这个看起来很简单,创建呢?

public boolean Create(T user){
    QueryRunner run = new QueryRunner(dataSource);
try 
{
    run.update("INSERT INTO "+table+ getFields() +
            "VALUES " + getParameters(user)); 
}
catch (SQLException ex) 
{
    Log.logException(ex);
    return false;
}

    return true;
}

protected abstract String getFields(); 
protected abstract String getParameters(T user);

丑陋,不安全,但可以传播这个想法。

于 2013-05-13T09:41:14.993 回答