开发者

Caching data in grails

开发者 https://www.devze.com 2023-01-24 14:07 出处:网络
I have a site where users will first enter their search criteria.The search combines data from 2 sources, one of which is not a database. The search results are generally large enough to be paged.

I have a site where users will first enter their search criteria. The search combines data from 2 sources, one of which is not a database. The search results are generally large enough to be paged.

Since the initial query is expensive, I would like to cache the search results 开发者_如何学Pythonif the search criteria doesn't change for subsequent page views.

My current method looks like:

def search(criteriaMap, offset, pagesize)

What is the best way of caching the search results in groovy/grails? How would I expire the search results?

Note, I see there is a springcache plugin but I am not sure if this will work for paged results. I also know that grails is packaged with ehcache but I haven't seen an API I directly have access to, I have only seen it used for 2nd level caching with GORM.

Update: I took part of @mfloryan's solution to solve this.

I created two methods in the searchService:

@Cacheable("searchCache")
def searchResults(uid, trimmedParams)
def trimParams(params)

(One is cached and the other is not.)

My code in the searchController:

def trimmedParams = searchService.trimParams(params)
def results = searchService.searchResults(trimmedParams)

//Page results
results = HelperService.pageResults(results, params.offset, params.max)

[results: results, searchParams : trimmedParams]

As a results, I invoked the search service with a trimmed list of parameters that do not include paging params. The cached search results can be returned.

The searchController takes care of the paging.

note: I didn't cache the hibernate results because I would end up with double the data in the cache. I only cached the combined results from searchService.searchResults (which hits a REST API and my local database)


Firstly, if you want to cache the query, then perhaps using the Hibernate query cache is a good start (Set cache:true in the mappings and pass cache: true to the executeQuery)

Using the SpringCache plug-in will allow you to cache the entire response from the controller. All you would need to do is decorate the controller like that: @Cacheable("searchMethodCache") or only decorate individual methods that you want results of cached. The cache will save response by query string so it should work well with paging. The @CacheFlush annotation allows to set when the cache should be cleared.

The EH Cache itself is configured in grails-app/conf/spring/resources.groovy

-- UPDATE --

Following you comment I begin to suspect your might be thinking of a slightly different solution. So there is a query that returns a list of results and that list is then paged and displayed. With standard Grails approach Hibernate will generate one query for each page (returning a subset from the full list thus running the potentially expensive query once for each page). Presumably you want the query to be run once - to return the full result set that gets cached and then serve individual pages from the it. If that's the case, far as I know, you will have to page the results manually either from the Hibernate cache or caching the result set somewhere else (Session context?)

0

精彩评论

暂无评论...
验证码 换一张
取 消