[英]Automatically opening and closing connection
instead of multiple vargs . 注意:请忽略我使用而不是多个vargs
Java中有这样做的标准方法吗?
我所拥有的是从远程服务器返回的资源。 但是在每个查询之前,必须打开远程连接,并在返回返回之后–必须关闭它。
因此,执行此操作的自然方法是:
Connection c = config.configureConnection();
c.open(); //open
List<Car> cars;
try{
cars = c.getCars();
}finally{
c.close(); //close
}
现在,我想实现一些在资源本身级别上运行的操作,而不必担心连接,例如:
List<Car> cars = new CarResource().all(); //opens and closes connection
and , which any class extending it must implement. 我目前的操作方式是通过一个抽象类AbstractQueriable调用抽象方法和 ,任何扩展它的类都必须实现。
, and - which are the public facing methods. AbstractQuerieable实现了Queriable接口,从而使它公开了三个公共方法 , 和 -它们是面向公众的方法。
这是Queriable接口:
public interface Queriable <T>{
public T get(String id);
/** Simply returns all resources */
public Collection<T> all();
public Collection<T> filter(MultivaluedMap<String, String> args);
}
这是实现它的AbstractQueriable类:
public abstract class AbstractQueriable<T> implements Queriable<T> {
@Override
public final T get(String id) {
setup();
try {
return query(id);
} finally {
cleanup();
}
}
@Override
public final Collection<T> filter(MultivaluedMap<String, String> args) {
setup();
try {
return query(args);
} finally {
cleanup();
}
}
/**
* Returns all resources.
*
* This is a convenience method that is equivalent to passing an empty
* arguments list to the filter function.
*
* @return The collection of all resources if possible
*/
@Override
public final Collection<T> all() {
return filter(null);
}
/**
* Queries for a resource by id.
*
* @param id
* id of the resource to return
* @return
*/
protected abstract T query(String id);
/**
* Queries for a resource by given arguments.
*
* @param args
* Map of arguments, where each key is the argument name, and the
* corresponing values are the values
* @return The collection of resources found
*/
protected abstract Collection<T> query(MultivaluedMap<String, String> args);
private void cleanup() {
Repository.close();
}
private void setup() {
Repository.open();
}
最后,例如,我想在代码中使用的资源必须扩展AbstractQueriable类(请注意,这些方法的细节并不重要):
public class CarRepositoryResource extends AbstractQueriable<Car> {
@Override
protected Car query(String id) {
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
params.add("CarID", id);
// Delegate the query to the parametarized version
Collection<cars> cars = query(params);
if (cars == null || cars.size() == 0) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
if (cars.size() > 1) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return cars.iterator().next();
}
@Override
protected Collection<Car> query(MultivaluedMap<String, String> params) {
Collection<Car> cars = new ArrayList<Car>();
Response response = Repository.getConnection().doQuery("Car");
while (response.next()) {
Returned returned = response.getResult();
if (returned != null) {
cars.add(returned);
}
}
return cars;
}
}
最后,我可以在代码中使用:
Collection<Car> cars = new CarRepositoryResource().all();
//... display cars to the client etc...
对于这种设置,我有些不满意的地方:
我正在使用的连接不支持/实现JDBC api,也不基于sql。
基本上可以归结为:
实现起来并不难(将连接存储在静态ThreadLocal中以使其成为线程安全),并且肯定会省去一些打开/关闭调用(在性能方面可能会获得很大的收益,具体取决于连接的强度)。
上下文类可能类似于(考虑此伪代码);
public class MyContext{
private static final
ThreadLocal<Connection> connection = new ThreadLocal<Connection>();
public static void enter() {
connection.set(initializeConnection());
// this is eager initialization
// if you think it will often the case that no connection is actually
// required inside a context, you can defer the actual initialization
// until the first call to get()
}
public static void exit() {
try { connection.close(); }
catch(Throwable t) { /* panic! */ }
finally { connection.set(null); }
}
public static Connection get() {
Connection c = connection.get();
if (c == null) throw new IllegalStateException("blah blah");
return c;
}
}
然后,您将使用如下连接:
MyContext.enter();
try {
// connections are available here:
// anything that calls MyContext.get()
// gets (the same) valid connection instance
} finally {
MyContext.exit();
}
此块可以放在任何位置(在webapp中,它通常包装每个请求的处理)-从main方法开始(如果您要编写一个简单的案例,当您希望在整个应用程序的整个生命周期中都可以使用单个连接时) API中的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.