Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

讨论一下Dao的缓存实现 #844

Closed
wendal opened this issue Apr 21, 2015 · 11 comments
Closed

讨论一下Dao的缓存实现 #844

wendal opened this issue Apr 21, 2015 · 11 comments
Milestone

Comments

@wendal
Copy link
Member

wendal commented Apr 21, 2015

代码存放到nutzmore项目中

基本步骤:

  1. 如果是select语句,且存在Entity的情况下, 先判断缓存再数据库取值
  2. 如果是其他语句,清空对应表的缓存

依赖:
druid的sql处理器

需要添加/修改的内容:

  1. 缓存配置注解, 定义缓存名,key组合
  2. 缓存实现的接口
  3. 捕捉select语句生成的对象(以存入缓存实现中)

可能遇到的问题:

  1. 自定义sql对缓存状态的破坏
@fangoxyz
Copy link

var ioc = {

    cache : {

        type : "com.youfang.dao.cache.CacheExecExterior",

        fields : {

                    cacheController : [{refer : 'cacheController'}],

                    clazzList : [
                        ["com.youfang.biz.model.City",100000]
                        ,["com.youfang.biz.model.XiaoQu",100000]
                        ,["com.youfang.biz.model.QuXian",100000]
                        ,["com.youfang.biz.model.UserGroup",100000]
                        ,["com.youfang.biz.model.Zone",100000]
                        ,["com.youfang.biz.model.User",100000]
                        ,["com.youfang.biz.model.Permission",100000]
                        ,["com.youfang.biz.model.KeyWordsPool",100000]
                        ,["com.youfang.biz.model.BlackList",100000]],

                    isEnableCache : true

        },
        events : {
            depose : "shutDown"
        } 

    },

    cacheController : {

        type : "com.youfang.dao.cache.MemeoryCacheImpl",

    },

    daoExecutorImpl : {

        type : 

            "org.nutz.dao.DaoExecutorImpl",

        fields : {

            list : [{refer : 'cache'}]

        }  


    },

dataSource : {
    type : "com.alibaba.druid.pool.DruidDataSource",

    events : {
        depose : "close"
    },
    fields : { 
        driverClassName : "com.mysql.jdbc.Driver",
        url : "jdbc:mysql://192.168.0.253:3306/youfang?useUnicode=true&characterEncoding=utf-8",
        username : "root",
        password : ""

    }
},

dao : {
    type : "org.nutz.dao.impl.NutDao",
    fields : {
        dataSource : {
            refer : 'dataSource'
        },
        executor : {
            refer : 'daoExecutorImpl'
        }
    }
}

};

@fangoxyz
Copy link

为了保持代码的扩展性,我是直接通过配置的方式,而不用注解的方式来实现

@fangoxyz
Copy link

缓存的同步机制与缓存粒度的问题如何解决?
这里可能需要引入主键数据和散装数据的概念。
主键数据是按主键形式存放的数据,如select * from t_user where id=1执行后,取得数据是存在主键数据序列中的,我们可以定义为一级缓存,而当select * from t_user where id>1则是存放在散装数据序列中,我们可以定义为二级缓存,一级缓存是根据主键查询出的只有一条记录,二级缓存可能有一条记录也可能是一个记录集,非主键数据都存放在这里。
1.当delete update时如何根据缓存粒度来保持数据同步
2.当insert时也涉及到缓存粒度的问题,相对于散装数据,insert时需要全部清空,而相对于根据主键存放的数据是不需要清除缓存的。
缓存存放的结构与缓存粒度很重要,好的结构可以提高缓存的效率,否则可能比不用缓存效率更差

@zozoh
Copy link
Member

zozoh commented Apr 23, 2015

厄,缓存的需求很旺盛?

@Rekoe
Copy link
Member

Rekoe commented Apr 23, 2015

@zozoh
值得搞搞
确实用的挺多的

@fangoxyz
Copy link

@zozoh nutz和ssh相比少一个hibernate的缓存,为什么有人用mybatis+nutz mvc,肯定有原因

@wendal
Copy link
Member Author

wendal commented Apr 23, 2015

@Wizzercn 这不是讨论mybatis 的issue

@wendal
Copy link
Member Author

wendal commented Apr 28, 2015

受限于 #849 ,等待之

@fangoxyz
Copy link

fangoxyz commented May 9, 2015

fetchlinks的问题解决了,继续 多表查询 自定义sql 和视图的问题

@fangoxyz
Copy link

https://github.com/fangoxyz/DaoCache
实现了一二三级缓存以及多表查询缓存
1.缓存分为一二缓存的意义在于减少缓存清除操作的粒度,当根据主键update或delete时 ,清除一级缓存中的一条数据以及清除二级缓存中的所有数据。

2.一级缓存的key是主键值,缓存命名:t_user的一级缓存为t_user_L1___ ,一级缓存中存放的是单条记录。
比如 select * from t_user where id=1。判断此条sql语句的数据是否存放在一级缓存中的条件有:
(a).select部分必须是“*”,如select id from t_user where id=1 的数据是不放在一级缓存中的,而是放在二级缓存中。
(b). t_user必须是一个基本表,不是视图。
(c). select 语句中只涉及一个表,如果select * from t_user inner join t_usergoup on (id);这是不允许存在一级缓存中。
(d).where条件 必须是"=" 且 "="号左边字段属于t_user表的主键

3.二级缓存中存放的是基本表的非主键查询的数据,比如select * from t_user where id>0。二级缓存不包括视图和多表查询的缓存。

4.三级缓存存放视图和多表查询数据,并且使用cacheLinks的关系关联与二级缓存关联。 多表查询时缓存名使用##连接,如t_user##t_usergroup,当清除t_user表的缓存时会清除缓存名为t_user##t_usergroup的缓存.

5.二三级缓存的key是sql的sha值

@wendal
Copy link
Member Author

wendal commented Aug 22, 2015

恩, 算是ok了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants