[java手把手教程][第二季]java后端博客系统文章系统——No10

项目github地址:https://github.com/pc859107393/SpringMvcMybatis

实时项目同步的地址是国内的码云:https://git.oschina.net/859107393/mmBlog-ser

我的首页是:http://www.jianshu.com/users/86b79c50cfb3/latest_articles

上一期是:[手把手教程][第二季]java 后端博客系统文章系统——No9

[java手把手教程][第二季]java后端博客系统文章系统——No10_第1张图片
行走的java全栈

工具

  • IDE为idea2017.1.5
  • JDK环境为1.8
  • gradle构建,版本:2.14.1
  • Mysql版本为5.5.27
  • Tomcat版本为7.0.52
  • 流程图绘制(xmind)
  • 建模分析软件PowerDesigner16.5
  • 数据库工具MySQLWorkBench,版本:6.3.7build

本期目标

完成EhCache接入

Ehcache资源引入

在我们工程目录下面的build.gradle文件中引入gradle资源。

// ehcache核心依赖
compile group: 'net.sf.ehcache', name: 'ehcache', version: '2.10.3'

// mybatis-ehcache依赖
compile group: 'org.mybatis.caches', name: 'mybatis-ehcache', version: '1.1.0'

//shiro-ehcache依赖
compile group: 'org.apache.shiro', name: 'shiro-ehcache', version: '1.4.0'

开启Ehcache相关配置

本来按照道理来说,我们的Ehcache是二级缓存用来降低数据库压力,也就应该写入我们的spring-dao.xml中,但是Ehcache因为要和Shiro整合,我们顺带也就将其写入spring-web.xml中,如下:

    
    
        
        
        
    

    
    
        
        
    

    

    
    
        
        
        
        
        
        
        
        
        
        
            
                /static/*/** = anon
                
                /front/*/** = anon
                /index.jsp = anon
                /static/uploadFiles/** = anon
                /endSupport/*/** = authc
                /druid/*/** = authc
            
        
    

    

    
        
         
    

    
        
        
        
    

    

    

    
        
    
    
        
    
    

上面的配置中,我们可以将Ehcache的配置完全的拆分出来,如下:

    

    
        
         
    

    

在上面的配置中,我们开启了spring的cache,注入了‘org.springframework.cache.CacheManager’的子类作为我们的CacheManager。

CacheManager具体由EhCacheCacheManager实现。在EhCacheCacheManager中有以下的方法来实现CacheManager的注入。

    /**
     * Set the backing EhCache {@link net.sf.ehcache.CacheManager}.
     */
    public void setCacheManager(net.sf.ehcache.CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

所以最后我们通过实现具体的EhCacheManagerFactoryBean来引入cache的设置。当然在EhCacheManagerFactoryBean中我们可以找到对应的方法如:configLocation和shared。我们通过配置configLocation引入了shiro-ehcache.xml这个配置文件。

接着,我们在Shiro中引入Ehcache。配置如下:


    
    
    


    
    
    

从上面不难看出我们把Ehcache注入到了Shiro的securityManager中,同时我们的shiroCacheManager具体是由ehCacheManager来实现。

当然最上面的代码中出掉Ehcache相关的,剩下的就是Shiro的相关设置了。

Ehcache配置文件

我们从上面可以看到Ehcache配置文件是在config目录下的shiro-ehcache.xml文件,具体内容如下:


    
    
    
            
    

启用缓存

在上面我们已经把缓存相关的东西已经设置完成了,现在我们是需要对dao层启用缓存。这个时候我们需要怎么做呢?两种方法!

方法一:在mapper配置文件中直接粗暴的启用设置

我们直接编辑mapper配置文件加入以下内容:


    
    
    
    
    

对于我们不想启用缓存的方法,直接在末尾加上‘ useCache="false" ’,如:


方法二:在service层的方法处注解

我们先看看以前不加缓存的service方法是怎么样子的。

@Service("weichatService")
public class WeichatServiceImpl {

    @Autowired
    private SiteConfigDao siteConfigDao;

    @Autowired
    private WeChatDao weChatDao;

    public static String updateMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=";

    /**
     * 同步微信菜单到微信公众号上面
     *
     * @return
     */
    public String synWeichatMenu() {
        try {
            WeiChatMenuBean menuBean = creatWeMenuList();
            if (null == menuBean) return GsonUtils.toJsonObjStr(null, ResponseCode.FAILED, "菜单内容不能为空!");
            String menuJson = GsonUtils.toJson(menuBean);
            LogPrintUtil.getInstance(this.getClass()).logOutLittle(menuJson);
            WeiChatResPM pm = null; //微信响应的应答
            String responseStr = HttpClientUtil.doJsonPost(String.format("%s%s", updateMenuUrl, getAccessToken()), menuJson);
            LogPrintUtil.getInstance(this.getClass()).logOutLittle(responseStr);
            pm = GsonUtils.fromJson(responseStr, WeiChatResPM.class);
            if (pm.getErrcode() == 0) return GsonUtils.toJsonObjStr(null, ResponseCode.OK, "同步微信菜单成功!");
            else throw new Exception(pm.getErrmsg());
        } catch (Exception e) {
            e.printStackTrace();
            return GsonUtils.toJsonObjStr(null, ResponseCode.FAILED, "同步失败!原因:" + e.getMessage());
        }
    }

    public String getAccessToken() throws Exception {
        MyWeiConfig weiConfig = getWeiConfig();
        return WeiChatUtils.getSingleton(weiConfig.getAppid(), weiConfig.getAppsecret()).getWeAccessToken();
    }
    
    /**
     * 获取微信设置,包装了微信的appid,secret和token
     *
     * @return
     */
    public MyWeiConfig getWeiConfig() {
        String weiChatAppid = "", weichatAppsecret = "", token = "";
        MyWeiConfig apiConfig;
        try {
            List> siteInfo = getAllSiteInfo();
            LogPrintUtil.getInstance(this.getClass()).logOutLittle(siteInfo.toString());
            for (HashMap map : siteInfo) {

                Set> sets = map.entrySet();      //获取HashMap键值对

                for (Map.Entry set : sets) {             //遍历HashMap键值对
                    String mKey = set.getValue();
                    if (mKey.contains(MySiteMap.WECHAT_APPID)) {
                        weiChatAppid = map.get("option_value");
                    } else if (mKey.contains(MySiteMap.WECHAT_APPSECRET))
                        weichatAppsecret = map.get("option_value");
                    else if (mKey.contains(MySiteMap.WECHAT_TOKEN))
                        token = map.get("option_value");
                }
            }
            apiConfig = new MyWeiConfig(weiChatAppid, weichatAppsecret, token);
            return apiConfig;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 保存微信设置,内部遍历
     *
     * @param weiConfig 微信的设置信息
     * @throws Exception
     */
    public void saveConfig(MyWeiConfig weiConfig) throws Exception {
        if (weiConfig != null && !StringUtils.isEmpty(weiConfig.getAppid(), weiConfig.getAppsecret(), weiConfig.getToken())) {
            String[] key = {MySiteMap.WECHAT_APPID, MySiteMap.WECHAT_APPSECRET, MySiteMap.WECHAT_TOKEN};
            String[] value = {weiConfig.getAppid(), weiConfig.getAppsecret(), weiConfig.getToken()};
            for (int i = 0; i < key.length; i++)
                siteConfigDao.updateOneByKey(key[i], value[i]);
        } else {
            throw new Exception("微信相关设置不能为空!");
        }
    }

    public MyWeChatMenu findOneById(Integer id) {
        return weChatDao.findOneById(id);
    }
    
    ······
}

如果我们加上对应的cache注解后是什么样子呢?这里就不得不提spring-cache!

因为我们项目本身核心框架是spring,也就是依赖spring的相关框架都有对应的spring实现。也就是说这时候,我们在Ehcache下面找不到对应注解的时候我们打开spring-cache包后,可以找到注解了。这时候我们直接拿spring-cache会有什么效果呢?

其实这时候我们完全可以参考别人的写法,毕竟比人已经很完善了,我就不再一一搞出来了。

当然简单概括的说说主要是用了三个关键字:@Cacheable、@CachePut、@CacheEvict。详细介绍请查阅下面的介绍。

关于注解缓存的简单介绍:http://blog.csdn.net/wabiaozia/article/details/51596508

关于注解缓存的深度介绍:http://blog.csdn.net/wabiaozia/article/details/51596546


如果你认可我所做的事情,并且认为我做的事对你有一定的帮助,希望你也能打赏我一杯咖啡,谢谢。

[java手把手教程][第二季]java后端博客系统文章系统——No10_第2张图片
支付宝打赏

你可能感兴趣的:([java手把手教程][第二季]java后端博客系统文章系统——No10)