mybatis / mybatis-3

MyBatis SQL mapper framework for Java
http://mybatis.github.io/mybatis-3/
Apache License 2.0
19.72k stars 12.83k forks source link

Why not provide a configuration to close the first-level cache #1278

Open zhangweidavid opened 6 years ago

zhangweidavid commented 6 years ago

Why not provide a configuration to close the first-level cache, I think whether to use the first-level cache can also be controlled by the user.

When the localCacheScope is set to the statement ,the simple query will create a CacheKey object, save the current result to the cache, and finally clean up

MyBatis version

3.3.1

Database vendor and version

Test case or example project

Steps to reproduce

Expected result

Actual result

harawata commented 6 years ago

Hi @zhangweidavid ,

Local cache is used by some basic functionality (association/collection mapping, circular references). Besides, the current result mapping code heavily relies on CacheKey, so it may be quite difficult (if possible) to add such option.

If localCacheScope="statement" is not good enough for you, you should consider using SqlSession#selectCursor(), probably (see #1174 ).

zhangweidavid commented 6 years ago

Thank you so much for your answer @harawata ! My project dose not use association/collection. If it does not use L1 cache, it may be save memory and reduce GC count.

zhangweidavid commented 6 years ago

@harawata How to become a Mybatis contributor?

harawata commented 6 years ago

@zhangweidavid , You mean a committer? The team invites a contributor who is contributing mergeable patches continuously or an owner of a subproject, I think.

wwulfric commented 4 years ago

@harawata is it possible to cache raw result rather than the final result? For example:

list = mapper.selectMyList(params)
list.removeAll()
// in another method
list2 = mapper.selectMyList(params)
// list2 would be empty, but it's not my expectation.
harawata commented 4 years ago

Hello @wwulfric ,

I'm not sure what you mean by 'cache raw result'. Are you proposing to add another cache before local cache? If yes, it wouldn't improve the situation. If no, could you elaborate?

Regarding the behavior you observe, it should not happen if you set localCacheScope="statement". Please try it if you haven't.

wwulfric commented 4 years ago

@harawata Sorry, I try to explain myself explicitly. I want to use session scope cache, i know it's useful for me. But the current cache mechanism cannot prevent developer from misusing it. The example is as above. Right now my solution is:

list = mapper.selectMyList(params)
list = Lists.newArrayList(list)
list.removeAll()

But others wouldn't understand it clearly. The problem is that developers may destroy cache without realizing it.

So I guess if mybatis saves raw result in cache, rather than the org.apache.ibatis.executor.SimpleExecutor#doQuery's return. I don't know much about mybatis source code, maybe the raw result is ResultSetWrapper in org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets.

I am not asking whether mybatis provide raw result cache or not, but asking why mabtis choose org.apache.ibatis.executor.SimpleExecutor#doQuery's return value as local cache, not the raw result. Because If we choose raw result to cache, users won't desctroy cache unconsciously

harawata commented 4 years ago

Thank you for the explanation, @wwulfric . But you cannot get values out of ResultSet once it is closed, so it may not be possible to cache 'raw result', I'm afraid.

This issue is about disabling local cache, so it may be a little bit off-topic. Please use the mailing list if you have further questions.