(二期)12、开源博客项目mblog解读(二)

【课程12】freema...模板.xmind77.9KB

【课程12】hibernat...arch.xmind0.1MB

freemarker模板技术
模板技术

FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。

FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序。

对于FreeMarker而言,显示能力要比Jsp强一些,方便一些。

FreeMarker提供模板,开发人员利用后台语言提供数据,两者一结合,出现内容。

优点

1.freemark不支持写java代码,实现严格的mvc分离

2.性能非常不错

3.对jsp标签支持良好

4.内置大量常用功能,使用非常方便

5.宏定义(类似jsp标签)非常方便

6.使用表达式语言

基本语法

常用指令和宏

freemarker中使用指令时必须要在指令前面用#(如果是自定义指令用@,后面说),assign指令是用来声明变量的,注意:如果是布尔值,输出时一定要带?c,表示定义的变量是布尔值,不然会报错。

freemarker宏 macro , nested , 函数

macro可以理解为一个函数,根据输入的参数来生成结果

nested 功能是自定义marco的模板片段

在调用macro的时候可以传入自定义的模板片段

springboot集成freemarker

步骤一、导入pom文件

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

步骤二、在src/main/resource/创建一个templates文件夹,后缀为*.ftl,如新建一个index.ftl的文件。

步骤三、如果自定义标签什么的,需要定义全局配置FreemarkerConfig,引入自定义的标签。

@Component
public class FreemarkerConfig {
    @Autowired
    private Configuration configuration;
    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void setSharedVariable() throws TemplateModelException {
        configuration.setSharedVariable("author_contents", applicationContext.getBean(AuthorContentsDirective.class));
    }
}

Configuration

是一个存放应用级别(application level)公共配置信息,以及模版(Template)可使用的全局共享变量的一个对象。同时它还负责模版(Template)实例的创建以及缓存。

前端静态化

准备工作:

  • 需要静态化的页面模板
  • util工具类
  • 模板需要的参数

工具类:

import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.util.Map;  
  
/** 
 * 创建人: leon 
 * 创建时间: 2014年11月28日 上午10:07:51 
 * 类描述:Freemarker的工具类 
 */  
public class FreemarkerUtil {
      
    /** 
     * 通过指定的文件目录和文件名生成相应的文件 
     * @param fileDir 
     * @param fileName 
     */  
    public static Boolean printToFile(Template template,String fileDir,String fileName,Map<String,Object> root) {
        boolean done = false;  
        Writer writer = null;  
        try {  
            //判断多级目录是否存在,不存在则一级级创建  
            String[] paths = fileDir.split("\\\\");//注意:此处“\\”是错误的,必须要“\\\\”才能分割字符串  
            String dir = paths[0];  
            for (int i = 1; i < paths.length; i++) {  
                dir = dir + File.separator + paths[i];  
                File file=new File(dir.toString());  
                if (!file.exists()) {  
                    file.mkdir();  
                }  
            }  
            //创建输出流  
            File file = new File(fileDir +File.separator+ fileName);    
                 
            //设置生成的文件编码为UTF-8     
            //服务器不支持UTF-8格式HTML时候使用ANSI格式HTML文件,即系统默认编码     
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));  // 编码设置3  
            //writer = new FileWriter(fileDir +File.separator+ fileName);  
            //输出模板和数据模型都对应的文件  
            template.process(root, writer);  
            done = true;  
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (TemplateException e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                if(writer!=null){  
                    writer.close();  
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        return done;  
    }
}  

页面模板:可以选择博客详情页作为需要静态化的模板

templates/default/channel/view.ftl

静态化过程:写了一个controller用于静态化。


@RestController
public class ToHtmlController extends BaseController {

    @Autowired
    private PostService postService;
    @Autowired
    private Configuration configuration;

    @ResponseBody
    @RequestMapping("/view/tohtml/{id}")
    public boolean toHtml(@PathVariable Long id, HttpServletRequest req) throws IOException {
        Template template = configuration.getTemplate("/default/channel/view.ftl");

        String fileName = id + ".html";
        String htmlDir = "D:/git-second/course-11-mblog/mblog/web/src/main/resources/static/html";

        PostVO view = postService.get(id);
        Map<String, Object> params = new HashMap<>();
        params.put("view", view);
        return FreemarkerUtil.printToFile(template, htmlDir, fileName, params);
    }
}

需要注意的是,由于这个模板有些数据是通过模板标签来活得数据的,所以静态化过程中不能活得,需要重写模板,还有登录状态,阅读数等问题~~

自定义标签

重要的几个类:

  • TemplateDirectiveModel:java中freemarker通过实现TemplateDirectiveModel接口,用户可以自定义标签(指令)进行任意操作,任意文本写入模板的输出。也就是说要实现自定义标签需要实现这个接口。重新execute方法。
  • TemplateDirective : 抽象类,实现TemplateDirectiveModel接口,并拓展execute的参数封装到DirectiveHandler类里面。统一页面使用的结果参数名称。
  • DirectiveHandler :模板处理中心接口中心,根据execute方法的几个参数拓展出一系列方法,提高模板定义的效率。
  • TemplateModelUtils : freemarker模板工具类。
  • ChannelDirective : 自定义的模板,需实现TemplateDirective接口,重新getName和execute方法。并在execute方法中写业务逻辑
  • FreemarkerConfig :freemarker自定义标签、函数全局配置。

1. Freemarker自定义标签需要自定义一个类,然后实现TemplateDirectiveModel,重写execute方法,完成获取参数,根据参数设置不通属性等等。

2. Freemarker自定义标签中,如果标签内什么也没有,开始标签和结束标签绝对不能再同一行,不然会报错。

自定义函数

TemplateMethodModelEx

覆盖该接口的Object exec(java.util.List arguments)方法,该方法里写的就是我们自己想要实现的效果,当使用方法表达式调用一个方法(exec)时,实际上就是在执行这个exec方法,页面中方法表达式的参数就是该方法的参数,方法的返回值就是方法表达式的返回值。

步骤一、TemplateMethodModelEx接口。

步骤二、实现exec这个方法。

步骤三、在controller中将这个实现类的对象,放入ModelAndView对象中

步骤四、在模板文件中调用这个方法

或者在FreemarkerConfig中全局配置。

hibernate search
lucene全文搜索

Lucene是一个全文搜索引擎。

Lucene不是一个完整的应用程序,而是一个能够轻松集添加搜索功能到一个应用程序中的核心代码库和API。

通过hibernate search 创建 lucene全文索引。

Hibernate Search是在apache Lucene的基础上建立的主要用于Hibernate的持久化模型的全文检索工具。像Lucene这样的检索引擎能够给我们的项目在进行检索的时候带来非常高的效率,但是它们在基本对象的检索时会有一些问题,比如不能实现检索内容跟实体的转换,Hibernate Search正是在这样的情况下发展起来的,基于对象的检索引擎,能够很方便的将检索出来的内容转换为具体的实体对象。此外Hibernate Search能够根据需要进行同步或异步的索引更新。

Hibernate Search是 hibernate 对著名的全文检索系统 Lucene 的一个集成方案,作用在于对数据表中某些内容庞大的字段(如声明为text的字段)建立全文索引,它这样通过hibernate search就可以对这些字段进行全文检索后获得相应的POJO,从而加快了对内容庞大字段进行模糊搜索的速度(sql语句中like匹配)。

Hibernate Search主要有以下功能特点:

1,功能强大,配置简单 - 配置只需要修改persistence.xml(JPA),hibernate.cfg.xml(Hibernate)

2,支持Hibernate,以及EJB3 JPA标准应用

3,集成全文搜索引擎Lucene - Lucene是Apache项目组下的一个功能强大的全文搜索引擎项目

4,可以简单透明索引查询过的数据

5,支持复杂检索 - 支持Wild Card(诸如*, ?等通配符号),多关键字,模糊查询,排序等

6,支持Clustering

7,支持直接访问Lucene API

8,对Lucene索引,API的高效管理。

原理:

Hibernate Search是给Hibernate持久化模型架构来使用的一套全文检索工具,其全文检索依赖于Lucence引擎。全文搜索引擎(lucence)会将你要查询的这个字段的词语,进行分词,直接匹配分词。

hibernate search常用注解

@Indexed

-> index 指定索引名称

@Field

-> name 指定当前属性在Lucene Document中存储的名称,默认为属性名

@NumericField

@Field的联合注解,用于Integer, Long, Float和Double属性,索引时采用字典树结构(Trie structure).

@Fields

同一个域采用不同的索引策略。需要为每个Field指定name属性(非强制).

@Analyzer

-> impl 指定具体的Analyzer实现类

-> definition 指向@AnalyzerDef标注中name属性定义的值

使用过程

步骤一、导入pom,注意:lucence版本必须和Hibernate版本对应!

<!--hibernate search orm-->
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-search-orm</artifactId>
   <version>5.6.3.Final</version>
</dependency>
<!--hibernate search dependency-->
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
</dependency>

<!--处理中文的分析器-->
<dependency>
   <groupId>org.apache.lucene</groupId>
   <artifactId>lucene-analyzers-smartcn</artifactId>
   <version>5.5.4</version>
</dependency>
<!--查询结果的高亮处理-->
<dependency>
   <groupId>org.apache.lucene</groupId>
   <artifactId>lucene-highlighter</artifactId>
   <version>5.5.4</version>
</dependency>
<!-- /end -->

步骤二、在yml文件中配置hibernate search信息

spring
  jpa:
    database: mysql
    show-sql: false
    hibernate:
        ddl-auto: update
    properties:
        hibernate.format_sql: true
        hibernate.naming.physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
        hibernate.cache.use_second_level_cache: false
        #把索引的文件保存在文件系统中
        hibernate.search.default.directory_provider: filesystem
        #指定索引保存的路径
        hibernate.search.default.indexBase: ./indexes


步骤三、索引的内容配置(通过注解方式配置实体类,可对哪些数据进行索引)

@Indexed //hibernatesearch,将该类型的对象建立索引,放到luncene中

@DocumentId//数据表的主键字段对应的属性

@Field//对该字段的生成索引

@Analyzer//引入分词器

步骤四、Hibernate Search是基于lucence的,无需手动编写lucence代码即可进行Hibernate操作,会自动创建索引、修改索引、删除索引。所以这里重启服务器,查看索引

运行原理:

1、构造LuceneQuery查询索引库

2、EntityManager 构造 FullTextEntityManager 查询数据库

3、合并EntityManager 和 LuceneQuery —– FullTextQuery 查询索引库和数据库

4、查询索引库 fullTextQuery.getResultSize(); 查询索引,去重id

5、查询数据库 fullTextQuery.getResultList(); 根据索引库返回 id ,查询数据库

项目优化方向
前端静态化
单独设置CDN
优化慢sql-explain
多数据源或分库分表

(转)mblog解读(二)的更多相关文章

  1. (转)mblog解读(一)

    (二期)11.开源博客项目mblog解读(一) [课程11]图片上传模块.xmind54.6KB [课程11]消息发...通知.xmind55.2KB [课程11]异常处理分析.xmind95.4KB ...

  2. jQuery.Callbacks 源码解读二

    一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...

  3. java多线程解读二(内存篇)

    线程的内存结构图 一.主内存与工作内存 1.Java内存模型的主要目标是定义程序中各个变量的访问规则.此处的变量与Java编程时所说的变量不一样,指包括了实例字段.静态字段和构成数组对象的元素,但是不 ...

  4. mybatis源码解读(二)——构建Configuration对象

    Configuration 对象保存了所有mybatis的配置信息,主要包括: ①. mybatis-configuration.xml 基础配置文件 ②. mapper.xml 映射器配置文件 1. ...

  5. java8完全解读二

    继续着上次的java完全解读一 继续着上次的java完全解读一1.强大的Stream API1.1什么是Stream1.2 Stream操作的三大步骤1.2.1 创建Stream1.2.2 Strea ...

  6. (转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin

    转自:http://www.baiyuxiong.com/?p=886 ---------------------------------------------------------------- ...

  7. cJONS序列化工具解读二(数据解析)

    cJSON数据解析 关于数据解析部分,其实这个解析就是个自动机,通过递归或者解析栈进行实现数据的解析 /* Utility to jump whitespace and cr/lf *///用于跳过a ...

  8. NSObject头文件解析 / 消息机制 / Runtime解读 (二)

    本章接着NSObject头文件解析 / 消息机制 / Runtime解读(一)写 给类添加属性: BOOL class_addProperty(Class cls, const char *name, ...

  9. Nginx 小入门记录 之 Nginx 配置文件解读(二)

    上一小节主要是记录一些环境准备和Nginx的安装,接下来对Nginx基本配置进行记录. 查看配置文件安装记录 可以通过以下Linux命令进行查看: rpm -ql nginx rpm 是liunx的包 ...

随机推荐

  1. SVN—使用总结

    SVN使用教程总结 为什么要使用SVN? 在程序的编写过程中,每个程序员都会负责开发一个或多个模块,且开发中会生成很多不同的版本, 这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版 ...

  2. 如何登录Sitecore CMS

    这是关于学习如何使用和开发Sitecore CMS的系列文章中的第一篇. 在使用Sitecore CMS之前,必须先登录.新Sitecore开发人员常见的一个问题是“我该在哪里登录?” 安装任何版本的 ...

  3. mysql 查看版本和是否支持分区

    命令行界面: 查看版本: select version(); 结果: +------------+| version() |+------------+| 5.6.31-log |+--------- ...

  4. [openjudge-动态规划]怪盗基德的滑翔翼

    题目描述 描述 怪盗基德是一个充满传奇色彩的怪盗,专门以珠宝为目标的超级盗窃犯.而他最为突出的地方,就是他每次都能逃脱中村警部的重重围堵,而这也很大程度上是多亏了他随身携带的便于操作的滑翔翼. 有一天 ...

  5. 网易新网 spider

    # -*- coding: utf-8 -*- import os import sys import urllib.request import requests import re from lx ...

  6. Linux 操作系统镜像下载

    http://mirror.centos.orghttp://mirrors.163.comhttp://mirrors.suhu.com 例如:下载centos http://mirrors.163 ...

  7. 设计模式之Interpreter(解释器)(转)

    Interpreter定义: 定义语言的文法 ,并且建立一个解释器来解释该语言中的句子. Interpreter似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造 ...

  8. 转:【专题二】HTTP协议详解

    我们在用Asp.net技术开发Web应用程序后,当用户在浏览器输入一个网址时就是再向服务器发送一个HTTP请求,此时就使用了应用层的HTTP协议,在上一个专题我们简单介绍了网络协议的知识,主要是为了后 ...

  9. 外网上传到NAS速度很慢是什么情况?上行1M都不到,但是测试有4M

    外网上传到NAS速度很慢是什么情况?上行1M都不到,但是测试有4M NAS可以将自己的影片,图片,音乐都放在NAS中.在家中就能无线共享了.在其他地方要下载自己nas里的影片,下载速度主要取决于家里宽 ...

  10. jenkins1

    持续集成工具: Jenkins  和 Hudson是同源的. 甲骨文和开源社区之间的关系破裂,该项目被分成两个独立的项目. Jenkins:由大部分原始开发人员组成,Hudson:由甲骨文公司继续管理 ...