Java 如何使数据访问对象无阻塞?

Java 如何使数据访问对象无阻塞?,java,design-patterns,dao,Java,Design Patterns,Dao,我正在学习数据访问对象模式,它提供对数据源(如数据库)的访问。对于另一个问题,请提供以下示例: interface EmployeeDAO { List<Employee> findAll(); List<Employee> findById(); List<Employee> findByName(); boolean insertEmployee(Employee employee); boolean updateE

我正在学习数据访问对象模式,它提供对数据源(如数据库)的访问。对于另一个问题,请提供以下示例:

interface EmployeeDAO {
    List<Employee> findAll();
    List<Employee> findById();
    List<Employee> findByName();
    boolean insertEmployee(Employee employee);
    boolean updateEmployee(Employee employee);
    boolean deleteEmployee(Employee employee);
}
interface EmployeeDAO{
列出findAll();
列出findById();
列出findByName();
布尔插入员工(Employee);
布尔更新员工(Employee-Employee);
布尔删除员工(Employee-Employee);
}
我在互联网上的其他答案和文章中看到了类似的例子。让我困惑的是,从数据库中读取和写入数据通常需要一段时间,在这种情况下,就我所知,这些示例(尤其是
find…()
示例)并不实用。也就是说,在
find…()
调用期间阻塞可能不是所需的行为


我认为创建一个监听器接口(
EmployeeDAO.Listener
)是有意义的,它使用了
void-employeefind(Employee-Employee)
等方法,但我很惊讶我以前在DAO示例中没有看到这一点。我想知道我是否只是不了解数据访问对象和/或缺少一种更明显的方法。

在上面的界面中实现的方法将是简单的sql查询

  • “查找全部”将是“从表中选择*”
  • 按id查找将是“select*from table where id=:id”(这是表的主键,并已索引)

我在一个每天执行数百万条insert语句的应用程序中工作,我们不担心阻塞。如果您使用java并使用Spring框架,那么有一些库可以为您处理所有这些问题。查看java.persistence中的EntityManager和TransactionManager。

通常会采用许多不同的选项/方法:

  • 阻塞就像您展示的API一样。这是一个非常简单的API,通过在多线程应用程序中调用API仍然可以实现并行性

  • 在异步操作中接收/注册处理程序。这有时与阻塞API一起提供(事实上,可以通过生成后台线程,然后在最后调用处理程序来实现阻塞API)

  • 返回一个未来的或对象,这使接口更符合Java风格(通过在返回类型位置返回数据),但表示最终结果,而不是立即可用的结果。未来可以用于阻塞或非阻塞

  • 我个人的建议是:

    interface EmployeeDatabase {
       interface StringWhereClause {
         ListQueryBuilder is(String value);
         ListQueryBuilder contains(String value);
         ListQueryBUilder matchesRegex(String regex);
       }
    
       interface IntWhereClause {
         ListQueryBuilder is(int value);
         ListQueryBuilder isInRange(int min, int max);
         ListQueryBuilder isGreaterThan(int value);
         ListQueryBUilder isLessThan(int value);
         ListQueryBuilder isGreaterThanOrEqualTo(int value);
         ListQueryBUilder isLessThanOrEqualTo(int value);
       }
       // ... matchers for other types of properties ...
    
       interface ListQueryBuilder {
          // Generic restrict methods
          StringWhereClause whereStringProperty(String propertyName);
          IntWhereClause whereIntProperty(String propertyName);
          // ...
    
          // Named restrict methods
          StringWhereClause whereName();
          StringWhereClause whereJobTitle();
          IntWhereClause whereEmployeeNumber();
          // ...
    
          ListQueryBuilder limit(long maximumSize);
          ListQueryBuilder offset(long index);
    
          ResultSet<Employee> fetch();
       }
    
       ListQueryBuilder list();
       ListenableFuture<Employee> getById(Key key);
       ListenableFuture<KeyOrError> add(Employee employee);
       ListenableFuture<Status> update(Key key, Employee employee);
       ListenableFuture<Status> delete(Key key);
    }
    
    接口EmployeeDatabase{
    接口StringWhere子句{
    ListQueryBuilder为(字符串值);
    ListQueryBuilder包含(字符串值);
    ListQueryBUilder匹配regex(字符串regex);
    }
    接口INTWHERE子句{
    ListQueryBuilder为(int值);
    ListQueryBuilder isInRange(最小整数,最大整数);
    ListQueryBuilder大于(int值);
    ListQueryBUilder小于(int值);
    ListQueryBuilder比OreQualto(int值)更大;
    ListQueryBUilder isLessThanOrEqualTo(int值);
    }
    //…其他类型属性的匹配器。。。
    接口ListQueryBuilder{
    //一般限制方法
    StringWhere子句whereStringProperty(字符串属性名称);
    INTWHERE子句WHERINTPROPERTY(字符串属性名称);
    // ...
    //命名限制方法
    StringWhere子句whereName();
    StringWhere子句whereJobTitle();
    INTWHERE条款WHEREMPLOYEENUMBER();
    // ...
    ListQueryBuilder限制(长最大尺寸);
    ListQueryBuilder偏移量(长索引);
    ResultSet fetch();
    }
    ListQueryBuilder列表();
    ListenableFuture getById(Key);
    ListenableFuture添加(员工);
    ListenableFuture更新(密钥、员工);
    ListenableFuture删除(键);
    }
    
    与:

    接口结果集{
    Iterable asIterable();
    //…其他方法。。。
    }
    接口键错误{
    布尔isError();
    布尔isKey();
    Key getKey();
    可丢弃的getError();
    }
    接口状态{
    布尔isOk();
    布尔isError();
    可丢弃的getError();
    void verifyOk();
    }
    
    基本上,其思想是插入到数据库中会返回一个键对象(如果不成功,则返回一个错误)。此键可用于检索、删除或更新数据库中的条目。这些操作(add、update、delete和getById)都有一个结果,在这种情况下,将使用
    ListenableFuture
    而不是type
    T
    ;此future对象允许您阻止(通过调用future对象上的
    .get()
    )或异步检索对象(通过注册一个回调以在结果就绪时调用)

    对于list-y操作,有许多不同的方法可以对列表进行筛选、再选择、排序等。为了防止各种不同重载的组合爆炸,我们使用允许在多个组合中应用这些不同的限制。简而言之,生成器界面提供了一种方法,在调用
    fetch()
    之前,添加零个或多个选项(排序、筛选、限制等)以应用检索操作,从而执行列表查询并返回
    ResultSet
    。此操作返回一个
    ResultSet
    ,而不是
    ListenableFuture
    ,因为结果不会一次全部返回(例如,它们可能以流式方式从数据库返回);
    ResultSet
    实际上是一个界面,其行为类似于
    ListenableFuture
    ,但用于项目列表(项目可能在不同时间准备就绪)。为方便起见,重要的是要有一种方法可以轻松地迭代结果集的内容(例如,通过提供 interface ResultSet<T> { Iterable<T> asIterable(); // ... other methods ... } interface KeyOrError { boolean isError(); boolean isKey(); Key getKey(); Throwable getError(); } interface Status { boolean isOk(); boolean isError(); Throwable getError(); void verifyOk(); }