Java课代表

Java课代表 查看完整档案

淄博编辑  |  填写毕业院校  |  填写所在公司/组织 javahelper.top 编辑
编辑

JavaWeb一线开发,5年编程经验
微信公众号:Java课代表
专注分享 JavaWeb 开发实战技巧

个人动态

Java课代表 回答了问题 · 3月6日

解决新手学Springboot的第一个例子hello world为什么报错404?怎么改?

从你贴出来的代码来看,没有发现问题,直接运行你第一张截图里的main方法就可以了,或者你可以去我代码库里下载项目自己运行看看:Java课代表的GitHub,万事开头难,加油!有不明白的欢迎私信我

关注 4 回答 3

Java课代表 回答了问题 · 3月1日

为什么abc.html请求能匹配上 @GetMapping("/abc")?

你这应该是老版本的SpringBoot了,首先你要知道SpringBoot是基于Spring的。
版本对应如下表:

序号SpringBootSpringframework
12.45.3
22.35.2
32.25.2
42.15.1
52.05

下面说一下你这个问题,这个特性叫做后缀匹配 SuffixMatch

在老版本中,这个特性是用来识别资源类型的,比如你问题描述中,虽然代码写的是@GetMapping("/abc"),但因为后缀匹配,实际上可以匹配"abc.html","abc.pdf","abc.json"等等,这个特性在以前是很有帮助的,但是现在浏览器可以使用"Accept" head头来指明资源类型,也就不需要SpringFramework再"多此一举"了,而且因为这个特性的存在,很多人认为是个bug,纷纷给Spring提了很多 issue

所以,从Spring5.3开始,这个特性就默认关闭了,所以如果你使用的是目前最新的SpringBoot2.4,就不会遇到这个问题。

当然,既然你碰到了,想要在老版本中关闭,官方也提供了关闭办法,原文如下:

To completely disable the use of path extensions in versions prior to 5.3, set the following:

既然都说到了这里,就顺便把配置类也一块给你贴上吧:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseSuffixPatternMatch(false);
    }
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }

}

自己粘贴到代码里试试吧,有问题欢迎私信我

关注 3 回答 2

Java课代表 赞了文章 · 2月22日

java项目中的classpath到底是什么

java项目中的classpath到底是什么

在java项目中,你一定碰到过classpath,通常情况下,我们是用它来指定配置/资源文件的路径。在刚开始学习的时候,自己也糊里糊涂,但是现在,是时候弄清楚它到底是指什么了。

顾名思义,classpath就是class的path,也就是类文件(*.class的路径)。一谈到文件的路径,我们就很有必要了解一个java项目(通常也是web项目)它在真正运行时候,这个项目内部的目录、文件的结构;这样,我们才好分析、理解classpath。

开发时期的web项目结构

下面,我以一个ssm的项目为例,我先把开发时候的项目的目录结构图放出来。根据maven的约定,一般我们的项目结构就像下面这样。

clipboard.png

classpath用在哪里了?

而我们经常用到classpath的地方,就是在指定一些配置/资源文件的时候会使用到。比如说,我们在web.xml中指定springmvc的配置文件,如下图,我们使用:classpath:entry/dev/spring-mvc.xml;再比如,当我们把*Mapper.xml文件放在了main/java/../mapping/文件夹下时,在mybatis的配置文件中配置其位置,我们使用:

classpath*:**/mapper/mapping/*Mapper.xml

clipboard.png

clipboard.png

很显然,上面这2个classpath的配置,是为了告诉配置文件,去哪里寻找我们要指定的配置文件。要想弄清楚为什么是上面这样写的,我们就要来看看项目运行时(或者是发布后)的目录结构了。

web项目发布后的目录结构

我们使用IDEA对项目进行打包,一种是war包,一种是explorer的文件夹,war包解压后就是explorer了。我们来对解压后的目录结构进行分析。

clipboard.png

经过对比,我们要注意到,开发时期的项目里,src/main/下面的javaresources文件夹都被(编译)打包到了生产包的WEB-INF/classes/目录下;而原来WEB-INF下面的views和web.xml则仍然还是在WEB-INF下面。同时由maven引入的依赖都被放入到了WEB-INF/lib/下面。最后,编译后的class文件和资源文件都放在了classes目录下。

clipboard.png

classpath原来是这个

在编译打包后的项目中,根目录是META-INFWEB-INF 。这个时候,我们可以看到classes这个文件夹,它就是我们要找的classpath。

在第1个例子里,classpath:entry/dev/spring-mvc.xml 中,classpath就是指WEB-INF/classes/这个目录的路径。需要声明的一点是,使用classpath:这种前缀,就只能代表一个文件

在第2个例子里,classpath*:**/mapper/mapping/*Mapper.xml,使用classpath*:这种前缀,则可以代表多个匹配的文件**/mapper/mapping/*Mapper.xml,双星号**表示在任意目录下,也就是说在WEB-INF/classes/下任意层的目录,只要符合后面的文件路径,都会被作为资源文件找到。

查看原文

赞 94 收藏 51 评论 16

Java课代表 回答了问题 · 2月5日

解决mysql索引问题

时间和空间的权衡,如果搞俩索引都存完整数据,相当于浪费了存储空间
其次,由于二分查找的时间复杂度为O(logN),从辅助索引再去找聚簇索引中的那一行数据也是非常快的!

关注 2 回答 2

Java课代表 发布了文章 · 2月4日

Freemarker 教程(一)-模板开发手册

本文是Freemarker系列的第一篇,面向模板开发人员,主要介绍 FreeMarker 所使用的 FTL(FreeMarker Template Language) 语法,了解 Freemarker 的基本概念,介绍基本的 FTL 术语 及内置函数,内置指令,方便作为开发手册速查(文中演示所用版本为 2.3.30,实际使用中请根据自己项目版本自查官网)。

本文不会罗列官网API,只在必要时演示其语法,代码工程中有课代表整理的 freemarker api 思维导图,配合此文食用可使功力大增!请到 课代表的 github自取。

1.FreeMarker 是什么

Freemarker是一款纯 Java编写的模板引擎软件,可以用来生成各种文本,包括但不限于:HTMLE-Mail以及各种源代码等等。

它的主要任务就是:把模板和数据组装在一起,生成文档,这个过程又叫渲染(Render)。流程如图:

freemarker-overview.png

由于大部分模板开发人员都是用它来生成HTML页面,所以本文将基于 SpringBoot(2.4.1)+Freemarker(2.3.30)+SpringWeb演示 HTML 页面的渲染

2.最简单的模板

假设我想要一个简单页面用来欢迎当前用户,模板代码:

<html>
<head>
  <title>index</title>
</head>
<body>
    <p>你好,${userName}</p>
</body>
</html>

${userName}是 FTL 的插值语法,他会把userName的值替换到生成的 HTML 中,从而根据当前登录者,显示不同的用户名,这个值由后端代码放到Model中,对应的 Controlelr 代码:

@Controller
public class HelloWorld {
    @GetMapping("hello")
    public String hello(Model model) {
        model.addAttribute("userName","Java 课代表");
        // 返回模板名称
        return "index";
    }
}

访问页面:

freemarker-hello.png
数据由后端代码通过数据模型(Model)传递,模板只关心数据如何展示(View),二者的关联关系由 Controller 来控制,这就是 MVC。

3.数据模型(data-model)

Controller中添加到 model 中的数据是如何组织的呢?这就需要了解一下FTL的数据模型(data-model)。

FTL 的数据模型在结构上是一个树形:

(root)
  |
  +- animals
  |   |
  |   +- mouse
  |   |   |
  |   |   +- size = "small"
  |   |   |
  |   |   +- price = 50
  |   |
  |   +- elephant
  |   |   |
  |   |   +- size = "large"
  |   |   |
  |   |   +- price = 5000
  |   |
  |   +- python
  |       |
  |       +- size = "medium"
  |       |
  |       +- price = 4999
  |
  +- message = "It is a test"
  |
  +- misc
      |
      +- foo = "Something"

其中的root 可以理解为 Controller 中的 model ,通过 model.addAttribute("userName","Java 课代表");就可以往数据模型中添加数据。

数据模型中可以像目录一样展开的变量,如:root, animals, mouse, elephant, python, misc称之为哈希(hash)。哈希的 key 就是变量名,value 就是变量存储的值,通过.分隔的路径可以访问变量值,比如访问 mouse 的 price :animals.mouse.price.

animals.mouse.price这样存储单个值的变量叫做标量(scalar),标量有四种具体类型:string,boolean,date-like,number;

还有一种变量叫做序列(sequence),可以类比为 Java 中的数组,序列中的每个项没有名字,可以通过遍历,或者下标的方式访问(后面会演示序列的访问),它的数据结构看起来是这样的:

(root)
  |
  +- animals
  |   |
  |   +- (1st)
  |   |   |
  |   |   +- name = "mouse"
  |   |   |
  |   |   +- size = "small"
  |   |   |
  |   |   +- price = 50
  |   |
  |   +- (2nd)
  |   |   |
  |   |   +- name = "elephant"
  |   |   |
  |   |   +- size = "large"
  |   |   |
  |   |   +- price = 5000
  |   |
  |   +- (3rd)
  |       |
  |       +- name = "python"
  |       |
  |       +- size = "medium"
  |       |
  |       +- price = 4999
  |
  +- misc
      |
      +- fruits
          |
          +- (1st) = "orange"
          |
          +- (2nd) = "banana"

FTL 里常用的数据类型就这三类:哈希(hashe),标量(scalar),序列(sequence)。

有了数据,还要有语法来组织这些数据,下面介绍 FTL 中的常用语法。

4.FTL 语法

FreeMarker 只认如下三种语法:

  1. 插值:${...} ,Freemarker 会将里面的变量替换为实际值
  2. FTL 标签(tags):结构上类似HTML的标签,都是用<>包裹起来,普通标签以<#开头,用户自定义标签以<@开头,如<#if true>true thing<#/if><@myDirect></@myDirect>
你会看到两种叫法,1:标签(tags),2:指令(directive)。举个例子:<#if></#if>叫标签; 标签里面的if是指令,可以类比于html中的标签(如:<table></table>)和元素(如:table)。不过,把标签和指令认为是同义词也没有问题。
  1. 注释(Comments):FTL 中的注释是这样的:<#-- 被注释掉的内容 -->,对于注释,FTL会自动跳过,所以不会显示在生成的文本中(这点有别于 HTML 的注释)
注意:除以上三种语法之外的所有内容,皆被 FreeMarker 视为普通文本,普通文本会被原样输出

插值就是单纯的替换变量的值,注释更没啥好说的,下面主要介绍几个最常用的 FTL 标签(指令)并结合代码演示其用法。

if 指令

if 可以根据条件跳过模板中的某块代码,以前文为例,当 userName 值为 "Java课代表" 或zhengxl5566时,用特殊样式展示,相关模板代码如下:

<p>你好,
    <#if userName == "Java 课代表">
        <strong>${userName}</strong>
    <#elseif userName == "zhengxl5566">
        <h1>${userName}</h1>
    <#else>
        ${userName}
    </#if>
</p>

list 指令

list用来遍历序列,其语法为:

<#list sequence as loopVariable>
    repeatThis
</#list>

比如后台往 model 里放入一个 allUsers 的集合

model.addAttribute("allUsers",userService.getAllUser());

可以直接使用下标访问集合中的某个元素:${allUsers[0].name}

也可以在模板中直接遍历展示:

<ol>
<#list allUsers as user>
    <li>
        姓名:${user.name},年龄:${user.age}
    </li>
</#list>
</ol>

实际渲染出来的 HTML:

<ol>
  <li>
    姓名:zxl,年龄:18
  </li>
  <li>
    姓名:ls,年龄:19
  </li>
  <li>
    姓名:zs,年龄:16
  </li>
</ol>
注意:假设 allUsers 是空的,渲染出来的页面会是<ol></ol>,如果需要规避这个情况,可以使用 items 标签
<#list allUsers>
    <ol>
        <#items as user>
            <li>
                姓名:${user.name},年龄:${user.age}
            </li>
        </#items>
    </ol>
</#list>

此时,假设 allUsers是空的,list 标签中的 html 内容就不会被渲染出来。

include 指令

include 指令可以把一个模板的内容插入到另一个模板中(官方建议使用 import 代替,参见下文的最佳实践)。
假设我们每个页面都需要一个 footer,可以写一个公共的footer.ftlh模板,其余需要footer的页面只需要引用footer.ftlh模板即可:

<#include "footer.ftlh">

import 指令

import 可以将模板中定义的变量引入当前模板,并在当前模板中使用。它和 include 的主要区别就是 import 可以将变量封装到新的命名空间中(后文会介绍 import 和 include 的对比)。

例如:模板 /libs/commons.ftl 里面写了很多公共方法,想在其他模板里引用,只需要在其他模板的开头写上:

<#import "/libs/commons.ftl" as com>

后续想使用/libs/commons.ftl 中的 copyright 方法,可以直接使用:

<@com.copyright date="1999-2002"/>

assign 指令

assign 可以用来创建新的变量并为其赋值,语法如下:

<#assign name1=value1 name2=value2 ... nameN=valueN>
or
<#assign name1=value1 name2=value2 ... nameN=valueN in namespacehash>
or
<#assign name>
  capture this
</#assign>
or
<#assign name in namespacehash>
  capture this
</#assign>

举例:

<#--创建字符串-->
<#assign myStr = "Java 课代表">
<#--使用插值语法显示字符串-->
myStr:${myStr}

macro 指令

macro 用来从模板上创建用户自定义指令(Java后端可以通过实现TemplateDirectiveModel接口自定义指令,将在下一篇:《Freemarker 教程(二)-后端开发指南》中介绍)

macro 创建的也是变量,该变量可以做为用户自定义指令使用,比如下面的模板定义了 greet指令:

<#macro greet>
  <h1>hello 课代表</h1>
</#macro>

使用 greet 指令

<@greet></@greet>
或者
<@greet/>

指令还可以附带参数:

<#macro greet person>
  <h1>hello ${person}</h1>
</#macro>

使用时传入 person 变量:

<@greet person="Java课代表"/> and <@greet person="zhengxl5566"/>

5.内置函数(Built-ins)

所谓内置函数,就是 FreeMarker 针对不同数 据类型为我们提供的一些内置方法,有了这些方法,可以让数据在模板中的展示更加方便。使用内置函数时,只需要在变量后面使用?加相应函数名即可。篇幅有限,这里不打算罗列所有内置函数,只挑几个简单例子展示其语法。

例子一:字符串的内置函数

<#--创建字符串-->
<#assign myStr = "Java 课代表">
<#--首字母小写-->
${myStr?uncap_first}
<#--保留指定字符后面的字符串-->
${myStr?keep_after("Java")}
<#--替换指定字符-->
${myStr?replace("Java","Freemarker")}

例子二:时间类型内置函数

<#--获取当前时间(如果是后端将时间传入data-model,只需要传Date类型即可)-->
<#assign currentDateTime = .now>
<#--展示日期部分-->
${currentDateTime?date}<br>
<#--展示时间部分-->
${currentDateTime?time}<br>
<#--展示日期和时间部分-->
${currentDateTime?datetime}<br>
<#--按指定格式展示时间日期-->
${currentDateTime?string("yyyy-MM-dd HH:mm a")}<br>

例子三:序列的内置函数

<#--序列类型内置函数样例-->
<#assign mySequence = ["Java 课代表","张三","李四","王五"]>
<#--将所有元素以指定分隔符分割,输出字符串-->
${mySequence?join(",")}<br>
<#--取序列中的第一个元素-->
${mySequence?first}<br>
<#--将序列排序后使用逗号分割输出为字符串-->
${mySequence?sort?join(",")}<br>

通过以上三个例子的简单演示,相信你已经能掌握内置函数的使用技巧了,就是在变量后面用 ?加变量数据类型所支持的函数。FTL 的内置函数极其丰富,官网按数据类型详细罗列了各自支持的内置函数及其用法,可自行查看官网的内置函数参考

为了方便大家快速查阅相关内置函数(built-ins)和指令(directives),课代表从官网翻译,并使用 xmind 做了个思维导图,每个函数(指令)都可以点进去查看功能描述和样例,可以极大提高模板开发效率:

freemarker-xmind.png

原始 xmind 文件放在 课代表的github上,读者可以按需自取。

课代表划重点!这个思维导图是全文精华,一定要下载下来看看!

6.命名空间(Namespaces)

所谓命名空间,就是在同一个模板里,所有使用 assign,macro,function 指令所创建的变量集合,它的主要作用就是唯一标识一个变量。

有两种方式可以创建命名空间:

1、同一个模板中的变量在同一个命名空间中。

以如下的index.ftlh为例,这里面创建的变量都在一个命名空间下,同名变量的值会相符覆盖

<#assign myName = "Java 课代表">
<#assign myName = "课代表">
<#--实际输出的是“课代表”-->
${myName}

2、不同模板中的变量可以通过 import 指令来区分不同的命名空间变量

模板A中想使用模板B中的变量,可以使用 import 指令,给引入的模板定义一个新的命名空间,通过 as 后面指定的 key 访问该新命名空间。

比如模板 lib/example.ftlh中定义了copyright

<#macro copyright date>
  <p>Copyright (C) ${date} Someone. All rights reserved.</p>
</#macro>

<#assign mail = "user@example.com">

在另一个模板index.ftlh中使用copyright

<#import "lib/example.ftlh" as e>
<@e.copyright date="1999-2002"/>
${e.mail}

命名空间的生命周期(The life-cycle of namespaces)

命名空间由 import 指令中的 path 确定(绝对路径),如果相同的 path 引入了多次,只有第一次调用 import 的时候才会触发相应命名空间的创建。后面对于相同模板路径的 import,指代的都是同一个命名空间,举例:

<#import "/lib/example.ftl" as e>
<#import "/lib/example.ftl" as e2>
<#import "/lib/example.ftl" as e3>
${e.mail}, ${e2.mail}, ${e3.mail}
<#assign mail="other@example.com" in e>
${e.mail}, ${e2.mail}, ${e3.mail}

/lib/example.ftlimport 后赋给 e,e2,e3三个命名空间,修改e中的 mail, 对e2,e3同样生效

输出:

user@example.com, user@example.com, user@example.com
other@example.com, other@example.com, other@example.com

import 和 include 的区别

<#import "lib/example.ftlh" as e> 会创建一个全新的命名空间,并把lib/example.ftlh中定义的变量封装到新命名空间中,提供访问,如:<@e.copyright date="1999-2002"/>

<#include "lib/example.ftlh"> 只是单纯把example.ftlh的内容插入到当前模板,并不会对命名空间产生影响

Freemarker官方建议:

所有使用 include 的地方都应该被 import 替代

使用 import 好处如下:

  • import 引入的模板只会被执行一次,重复引用多次并不会重复执行模板。而对于 include 而言,每次 include 都会执行一次模板内容;
  • import 可以创建该模板的命名空间,引用变量时可以清晰表达出变量来源,减少命名冲突概率;
  • 如果定义了很多通用方法,可以将auto-import配置为懒加载,用到哪个加载哪个。而auto-include无法实现懒加载,必须全量加载;
  • import 指令不会有任何输出,而 include 可能会根据模板内容输出相应字符。

7.最佳实践

1.空值处理

变量空值的处理

对于不存在的变量和值为 null 的变量,freemarker 统一认为是不存在的值,对其调用将会报错。为了避免这种情况,可以设置默认值,示例:<h1>Welcome ${user!"visitor"}!</h1>,当user不存在时,将显示visitor字符串。

另一种方式是在变量后面使用 ??表达式,如:user??如果user存在,则返回 true,否则返回 false,示例:<#if user??><h1>Welcome ${user}!</h1></#if>,当user不存在时,就不展示欢迎标语了。

list中的空值处理

遍历序列的时候,假设序列中有空值,freemarker并不会直接报错或显示空值,而是像更上一级作用域去搜索同名变量值,这种行为可能会导致错误的输出,举例:

<#assign x = 20>
<#list xs as x>
  ${x!'Missing'}
</#list>

本意是当遇到序列 xs 中的空元素是显示“missing” 字符串,但由于 freemarker 向上查找的特性, 这里的空值将会显示为 20。要关闭这个特性,可以在服务端配置:configuration.setFallbackOnNullLoopVariable(false);

2.使用 import 代替 include

前文在介绍到 include 的时候提到过,官方建议应该将所有用到 include 的地方都用 import 实现

我们平时用到 include 指令,主要就是用来把一段内容插入到当前模板,那如何用 import 实现 include 的功能呢?

很简单,把需要插入的内容封装成 自定义指令就好了。

比如我们从common.ftlh 里定义一个自定义指令 myFooter

<#macro myFooter>
    <hr>
    <p>这里是 footer</p>
</#macro>

在需要使用的地方,引入 common.ftlh 并调用 myFooter 指令

<#import "lib/common.ftlh" as common>
<#--将include使用import代替-->
<#--<#include "footer.ftlh">-->
<@common.myFooter/>

3.隔行变色

数据展示的时候经常遇到使用表格展示数据的情况,为了增加辨识度,一般会让奇数行和偶数行颜色不同以区分,这就是隔行变色

下面以遍历序列为例:

<#assign mySequence = ["Java 课代表","张三","李四","王五"]>
<#list mySequence as name>
    <span style="color:  ${name?item_cycle("red","blue")}">   ${name}<br/> </span>
</#list>
    

这里的 item_cycle 是循环变量的内置函数,至于他的详细用法,再次推荐你去看一下课代表整理的思维导图。

8.总结

本文介绍了 Freemarker 的基本概念和基础语法,意在让刚接触的萌新能对 Freemarker 有个全局性认识,了解Freemarker的数据模型、内置函数、指令。只要能区分这几个概念,实际开发中现用现查即可,不要一开始就迷失在海量的API中。

总体来说,Freemarker 是一个比较简单,容易上手的模板引擎,只要掌握了本文所提及的基本概念,直接上手开发是完全没问题的。

在本文写作过程中,课代表意识到纯文字表达的局限性,又不能全文罗列和翻译API,于是整理了一个思维导图,将Freemarker 的各类指令,内置函数及其官网示例全都翻译整理了进去。在平时开发过程中极大提升了开发效率,需要的同学请到 课代表的 github自取。


👇关注 Java课代表,获取最新 Java 干货👇
image

查看原文

赞 5 收藏 4 评论 0

Java课代表 赞了文章 · 2020-11-27

Jekyll+GitHub Pages部署自己的静态Blog

混了这么久,一直想拥有自己的博客,通过jekyllGitHub Pages捣腾出了自己的博客(https://www.ichochy.com)

一、安装jekyll

  1. 首先有安装Ruby的开发环境
  2. 运行gem install jekyll bundler安装jekyll和bundler
  3. 运行jekyll new myBlog创建默认的blog

    文件目录:
    -rw-r--r--   1 mleo  staff    35  2 13 15:02 .gitignore
    -rw-r--r--   1 mleo  staff   398  2 13 15:02 404.html
    -rw-r--r--   1 mleo  staff  1039  2 13 15:02 Gemfile
    -rw-r--r--   1 mleo  staff  1686  2 13 15:03 Gemfile.lock
    -rw-r--r--   1 mleo  staff  1652  2 13 15:02 _config.yml
    drwxr-xr-x   3 mleo  staff    96  2 13 15:02 _posts
    -rw-r--r--   1 mleo  staff   539  2 13 15:02 about.md
    -rw-r--r--   1 mleo  staff   175  2 13 15:02 index.md   
  4. 运行cd myBlog进入blog目录,运行bundler exec jelly serve启动

    MacBook-Pro:myBlog mleo$ bundler exec jekyll serve
    Configuration file: /Users/mleo/Develop/Coding/myBlog/_config.yml
            Source: /Users/mleo/Develop/Coding/myBlog
       Destination: /Users/mleo/Develop/Coding/myBlog/_site
     Incremental build: disabled. Enable with --incremental
      Generating... 
       Jekyll Feed: Generating feed for posts
                    done in 0.862 seconds.
     Auto-regeneration: enabled for '/Users/mleo/Develop/Coding/myBlog'
    Server address: http://127.0.0.1:4000/
      Server running... press ctrl-c to stop.
  5. 通过http://127.0.0.1:400就可以访问blog

    如下图:

    WX20190213-152850

二、了解jekyll

  1. jekyll目录结构:

    文件/目录描述
    _config.yml常量配置信息,网站的基础信息
    _drafts未发布的草稿帖子
    _includes模块化页面,使用: include default.html
    _layouts布局模板页面,使用: layout: default
    _posts发布的blog,固定格式: YEAR-MONTH-DAY-title.MARKUP
    _data文件数据(.yml.yaml.json.csv.tsv格式)
    _sass定义站点使用的样式
    _siteJekyll build 后生成的站点静态文件
    .jekyll-metadataJekyll build 日志信息
    index.htmlindex.md其他HTML,Markdown文件将由Jekyll转换,生成首页
    其他文件/文件夹例如 cssimagesfavicon.ico文件等
  2. 通过Gemfile文件配置 jekyll 主题

    Jekyll 3.2开始,jekyll new使用Gemfile文件来定义网站的主题,使默认目录结构更简单。默认情况下_layouts_includes_sass存储在Ruby中。

    minima 是默认主题,运行 bundle show minima 显示主题文件位置

    MacBook-Pro:myBlog mleo$ bundle show minima
    /Library/Ruby/Gems/2.3.0/gems/minima-2.5.0
  3. 自定义站点信息

    通过自定义_config.yml文件,改变 blog 网站信息,

    常量说明
    title标题
    email作者邮箱
    description网站信息
    baseurl网站路径
    url网站地址,如:https://www.ichochy.com
    twitter_username媒体账号,如:iChochy
    github_username媒体账号,如:iChochy

    注:修改_config.yml需要重启服务

三、书写Blog

  • 进入_post目录,开始你的创作吧,注意文件的格式必须为YEAR-MONTH-DAY-title.MARKUP,如:2019-02-13-blog.md
  • 开始写作吧,直接使用md语法来书写你的文章

    ---                                                                                                                                          
    layout: post                       --指定模板
    title:  "blog"                     --标题
    date:   2019-02-13 15:02:11 +0800  --时间
    tags: blog                   --分类
                                           
    ---   
    内容
                                                                                                                            
    如下图:

    WX20190215-171119

四、创建GitHub Pages项目

  • 新建一个项目,项目名必须为<username>.github.io,如:我的用户名为iChochy,项目名为iChochy.github.io

    如下图:

    WX20190215-172254

五、将Blog接交到GitHub

  • 将本地写好的的blog pull到github上,在项目设置中打开GitHub Pages

    如下图:

    WX20190218-102109

  • 选择master branch并保存,就完成了部署

六、运行Blog

直接访问项目名(<username>.github.io)就可以看你blog了,如:iChochy.github.io

七、自定义域名

  • 自定义域名需要有自己的域名,没有可以注册购买个心意的域名:阿里云
  • 进入域名配置中心,配置域名解析

    如下图:

    WX20190218-095303

  • 进入github项目设置,设置自己的域名并保存,就完成了自定义域名设置

    如下图:

    WX20190218-095906

八、开启HTTPS

  • 进入github项目设置,开启Enforce HTTPS就完成了

    不过,如果是自定义域名,会需要等待几分钟,github需要申请证书并部署
  • 完成开启后,如下图:

    WX20190218-104830


联系方式:

邮箱:iChochy@qq.com
网站:https://www.ichochy.com
源文:https://www.ichochy.com/posts/20190213/
查看原文

赞 1 收藏 0 评论 0

Java课代表 赞了问题 · 2020-11-17

MySQL:聚簇索引与二级索引

二级索引末尾会保存主键的值,这个好理解,保存主键等待需要时回表
但如果主键是联合索引,那么二级索引的末尾存的是什么呢?
`

CREATE TABLE T (

A INT(11), 
B INT(11), 
C INT(11), 
PRIMARY KEY (A, B), 
KEY C (C), 
KEY CA (C, A)

);

`
名为 C 的二级索引末尾,是将联合索引 (A, B) 中 A, B 两个字段的值都保存在末尾的吗?
名为 CA 的二级索引末尾,也是将联合索引 (A, B) 中 A, B 两个字段的值都保存在末尾的吗?

这个问题上网查都不知道该搜什么关键字,只能来请教各位大佬了

关注 2 回答 1

Java课代表 关注了问题 · 2020-11-17

MySQL:聚簇索引与二级索引

二级索引末尾会保存主键的值,这个好理解,保存主键等待需要时回表
但如果主键是联合索引,那么二级索引的末尾存的是什么呢?
`

CREATE TABLE T (

A INT(11), 
B INT(11), 
C INT(11), 
PRIMARY KEY (A, B), 
KEY C (C), 
KEY CA (C, A)

);

`
名为 C 的二级索引末尾,是将联合索引 (A, B) 中 A, B 两个字段的值都保存在末尾的吗?
名为 CA 的二级索引末尾,也是将联合索引 (A, B) 中 A, B 两个字段的值都保存在末尾的吗?

这个问题上网查都不知道该搜什么关键字,只能来请教各位大佬了

关注 2 回答 1

Java课代表 回答了问题 · 2020-11-17

MySQL:聚簇索引与二级索引

先说答案:
1、名为 C 的二级索引末尾,是将联合索引 (A, B) 中 A, B 两个字段的值都保存在末尾的吗?
是的。名为 C 的二级索,由于有联合主键的出在,实际上是(C,A,B)
2、名为 CA 的二级索引末尾,也是将联合索引 (A, B) 中 A, B 两个字段的值都保存在末尾的吗?
是保存在末尾,但是有一点需要注意,他保存的其实是(C,A,B),要特别注意不是(C,A,A,B)
相关文档可以参考官方链接:15.6.2.1 Clustered and Secondary Indexes
相关部分摘录如下:

In InnoDB, each record in a secondary index contains the primary key columns for the row, as well as the columns specified for the secondary index

所以你可以看出来,针对你问题中的描述:

KEY C (C), 
KEY CA (C, A)

这俩索引其实都是(C,A,B),保留一个就可以了

我在学索引的时候,也有过同样的疑问。
所以对你这个问题感同身受,立马跑来回答。也不知道题主何时能看到。
最后感谢题主问出了我以前也有过的问题,我决定本周整理一篇文章梳理下索引,下周一来这个问题下发链接

关注 2 回答 1

Java课代表 关注了用户 · 2020-11-16

幻有夢現 @sdzbzjh

_
| |__ __ _
| '_ | | | |/ _` |
| |_) | |_| | (_| |
|_.__/ \__,_|\__, |

         |___/ 暂时没有个人简介,

关注 2

认证与成就

  • 获得 98 次点赞
  • 获得 5 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 5 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2020-07-31
个人主页被 4.2k 人浏览