3

我正在使用Google App Engine(端点)来生成一个简单的API服务。如何在Google App Engine中使用CachedRowSet?

我目前正试图让我的查询更快,更高效,因此我决定仔细检查我在哪里调用ResultSet和Connections并关闭它们。

不过,我想用CachedRowSet,并赋予它看起来几乎是不可能的,当我尝试访问CachedRowSetImpl()记录仪的回报:

java.lang.NoClassDefFoundError: com.sun.rowset.CachedRowSetImpl is a restricted class. Please see the Google App Engine developer's guide for more details

所以我做了一些调查和Google App Engine's JRE whitelist包括:

javax.sql.rowset.CachedRowSet

但不是

com.sun.rowset.CachedRowSetImpl

这有什么意义吗?如何初始化/使用CachedRowSet

我的代码:

public ResultSet getRecordsWhereInt(String table, String where, int condition) throws SQLException { 

    c = DatabaseConnect(); 

    preStatement = c.prepareStatement("SELECT * FROM " + table + " WHERE " + where + " = ?"); 

    preStatement.setInt(1, condition); 

    CachedRowSet rowset = new CachedRowSetImpl(); 

    rowset.populate(preStatement.executeQuery()); 

    c.close(); 

    return rowset; 

} 

任何帮助/指导,将不胜感激。

更新1(2015年9月6日):
进一步调查,我发现,你可以使用RowSetProvider.newFactory().createCachedRowSet();

但是实现对CachedRowSetImpl的功能,谷歌已经限制使用到RowSetProvider()

这留下了我唯一的其他白名单图书馆RowSetFactory。所以我做了我自己,实现RowSetFactory中根据Oracle's implementation

public class CachedRowSetFactory implements RowSetFactory { 


    public CachedRowSet createCachedRowSet() throws SQLException { 
     return new CachedRowSetImpl(); 
    } 

    public FilteredRowSet createFilteredRowSet() throws SQLException { 
     return null; 
    } 

    public JdbcRowSet createJdbcRowSet() throws SQLException { 
     return null; 
    } 

    public JoinRowSet createJoinRowSet() throws SQLException { 
     return null; 
    } 

    public WebRowSet createWebRowSet() throws SQLException { 
     return null; 
    } 
} 

然后用它是这样的:

CachedRowSet crs = new CachedRowSetFactory().createCachedRowSet(); 

然而,即使失败。当我尝试用一​​个工作结果集填充它时,上面的例子返回一个空指针异常。我猜工厂的实施不是100%正确的,或者我正在跳过明显的事情。

更新2(2015年11月6日):
我试过我自己的滚动实施对CachedRowSetImpl,并通过手动复制一些库和消除未涵盖的应用程序引擎白名单库的RowSetProvider的。没有成功。我知道我需要放弃这一点,但我决心做到这一点。

回答

1

CahecRowSet是一个界面,很明显这是一个白名单。

Interface CachedRowSet

我猜你连接的是谷歌CLOUDSQL实例。

从的Javadoc:

A CachedRowSet object is a container for rows of data that caches its rows in memory, which makes it possible to operate without always being connected to its data source.

你正在尝试做没有意义IMO。 AppEngine不会在不同请求之间保持状态,当您的应用程序自动缩放和新实例旋转时,肯定不会。

为什么不将结果缓存在Memcache中,这会在后续请求和不同实例中保留。

+0

感谢您的回复。 我对使用CachedRowSet的兴趣主要在于上面实现的方法'getRecordsWhereInt'。如果我返回一个结果集,而不是一个缓存的行集,我该如何正确关闭结果集? 我已经对我的查询使用了memcache。 感谢您的帮助。 – markbratanov

+1

您必须复制DTO中结果集的元素,并在返回HTTP响应之前关闭结果集和连接。使DTO可串行化,以便将它们存储在Memcache中。在一天结束时,这是缓存连续... – koma