转载请注明出处WangYuheng’s Blog

简单说一下业务场景,前台用户通过input输入内容,在离开焦点时,将内容在div中显示。
这时遇到一个问题,如果用户输入了html标签,则在div显示中,标签被解析。
由于是纯前端操作,不涉及后端,因此需要通过js对输入内容进行转义。

这里提供一个非常简单有效的转义方案,利用了innerHTMLinnerText
注:火狐不支持innerText,需要使用 textContent 属性,而IE早期版本不支持此属性,为了同时兼容IE及火狐,需要进行判断操作.

因为innerText(textContent)会获取纯文本内容,忽略html节点标签,而innerHTML会显示标签内容,
所以我们先将需转义的内容赋值给innerText(textContent),再获取它的innerHTML属性,这时获取到的就是转义后文本内容。
代码如下:

function HTMLEncode(html) {
    var temp = document.createElement("div");
    (temp.textContent != null) ? (temp.textContent = html) : (temp.innerText = html);
    var output = temp.innerHTML;
    temp = null;
    return output;
}

var tagText = "<p><b>123&456</b></p>";
console.log(HTMLEncode(tagText));//&lt;p&gt;&lt;b&gt;123&amp;456&lt;/b&gt;&lt;/p&gt; 

通过测试结果,可以看到html标签及&符都被转义后保存。
同理,反转义的方法为先将转义文本赋值给innerHTML,然后通过innerText(textContent)获取转义前的文本内容

function HTMLDecode(text) { 
    var temp = document.createElement("div"); 
    temp.innerHTML = text; 
    var output = temp.innerText || temp.textContent; 
    temp = null; 
    return output; 
} 
var tagText = "<p><b>123&456</b></p>";
var encodeText = HTMLEncode(tagText);
console.log(encodeText);//&lt;p&gt;&lt;b&gt;123&amp;456&lt;/b&gt;&lt;/p&gt;
console.log(HTMLDecode(encodeText)); //<p><b>123&456</b></p> 

Best regards
Wang Yuheng

转载请注明出处WangYuheng’s Blog

由于网络连接不稳定,在连接局域网内的mysql开发服务器时,连续多次断开,结果无法连接到mysql服务器,报错内容如下:

Host 'host_name' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'

这是mysql自带的一种保护机制,如果客户端连续连接失败次数max_connect_errors,超过默认值,则会拒绝客户端继续连接。
可以通过

SHOW VARIABLES LIKE 'max_connect_errors'

查看允许连接失败的次数,默认为100次。由于网络不稳,可能会让JDBC等连接很快超过此默认值,可以通过修改此默认值来避免出现连接失败的情形,如

SET GLOBAL max_connect_errors=10000;

如果本机已被拒绝连接,可以通过另一台可连接到mysql服务器的主机执行以下命令

 mysqladmin flush-hosts -h localhost -uroot -p *****

此命令会清空所有的hosts缓存信息,执行后即可链接

Best regards
Wang Yuheng

转载请注明出处WangYuheng’s Blog

mysql 查询缓存

在sql调优的过程中,发现原本很慢的一条sql(将近1分钟) 在第二次运行时, 瞬间就完成了(0.04sec)。
这是因为mysql自带的缓存机制,将查询结果进行缓存,如果table数据未发生变化,再次使用同一条sql进行查询时,直接从上次的查询结果缓存中读取数据,而不是重新分析、执行sql。
如果table数据发生变化,所有与之相关的缓存都会被释放刷新,这样就不会出现数据脏读问题。

The query cache stores the text of a SELECT statement together with the corresponding result that was sent to the client. If an identical statement is received later, the server retrieves the results from the query cache rather than parsing and executing the statement again. The query cache is shared among sessions, so a result set generated by one client can be sent in response to the same query issued by another client.


是否使用查询缓存

为了避免缓存,可以在sql查询语句的字段前增加 SQL_NO_CACHE 关键字
如:

select * from t_user;

select SQL_NO_CACHE * from t_user;

反之,你也可以使用 SQL_CACHE 关键字,强制mysql从缓存中读取数据

select SQL_CACHE * from t_user;

mysql还提供了一种释放全部缓存的方法

reset query cache;  

设置查询缓存

查看是否有查询缓存。

SHOW VARIABLES LIKE 'have_query_cache';

注意,只要数据库拥有查询缓存功能,这个VALUE就是YES,无论查询缓存是否启用。

则查询缓存为启用状态。mysql默认为启用状态

mysql查询缓存可以通过两个变量来控制,query_cache_typequery_cache_size


query_cache_type

SHOW VARIABLES LIKE 'query_cache_type';

query_cache_type包含三种状态

  • 0 or OFF 此时不会从缓存中读取查询数据
  • 1 or ON 表示除非声明了SELECT SQL_NO_CACHE,否则都会从缓存中读取数据
  • 2 or DEMAND 表示所有语句都会从缓存中读取,相当于所有查询语句都使用了SELECT SQL_CACHE

通过如下命令可以设置查询缓存状态(需要管理员权限),执行后,需要重启mysql服务才能生效。

SET GLOBAL query_cache_type = 1;  

但是此命令会影响所有的使用此mysql服务的client。可以通过如下命令,关闭此客户端的查询缓存状态,但是同样需要重启server后才能生效。

SET SESSION query_cache_type = OFF;

SHOW VARIABLES LIKE 'query_cache_type';

query_cache_size

SHOW VARIABLES LIKE 'query_cache_size';

query_cache_size表示缓存大小,默认为1M。如果设置为0,则相当于query_cache_size=OFF

同样可通过 SET GLOBAL 进行设置

SET GLOBAL query_cache_size=40000;

需要注意的是,设置的query_cache_size,并不全是用于存储数据,还有约40KB的空间来维护查询缓存的结构。


Best regards
Wang Yuheng

转载请注明出处WangYuheng’s Blog

java.lang#split方法简介

java.lang提供的split方法,可以根据指定分隔符,将String字符串,切割并返回String[]字符串数组。

public String[] split(String regex)
public String[] split(String regex, int limit)

regex为指定分隔符,支持正在表达式
limit为切割后的数组长度,默认为0,不会超过实际长度
例:

public static void main(String[] args) {
    String str = "a,b,c,d,e";
    String[] arr1 = str.split(","); // ["a","b","c","d","e"] length=5
    String[] arr2 = str.split(",", 3); //["a", "b", "c,d,e"] length=3
    String[] arr3 = str.split(",", 10); //["a","b","c","d","e"] length=5
    String[] arr4 = str.split("nan"); //["a,b,c,d,e"] length=1
    String[] arr5 = "".split("nan"); //[""] length=1
}

特殊用法

因为split支持正则参数,可能会需要根据多个分隔符进行分隔,如 id=? and gender=? or age>?,希望根据andor两个分隔符进行分隔,则可通过正则实现。

public static void main(String[] args) {
    String str = "id=? and gender=? or age>?";
    String[] arr1 = str.split("and | or"); // ["id=? ","gender=?"," age>?"] length=3
}

注意上述中的空格符, 如果只根据关键字分隔,不能输入空格。“and|or”,可实现分隔效果。


易现exception

NullPointerException

字符串为””时, 返回结果为String[]{“”},但是字符串为null,会抛出空指针异常java.lang.NullPointerException

ArrayIndexOutOfBoundsException

标题中出现的java.lang.ArrayIndexOutOfBoundsException, 是一个容易出现的bug,因为支持正则参数,如果传入参数为转义符,则会出现非预期的结果数据。
如:

public static void main(String[] args) {
    String str = "a.b.c.d.e";
    String[] arr1 = str.split("."); // length=0 如果读取数组 则会出现数组越界异常ArrayIndexOutOfBoundsException
    String[] arr2 = str.split("\\."); // ["a","b","c","d","e"] length=5
}

同理, 根据“|”分隔,需要使用“\|”

java.util.regex.PatternSyntaxException

同样是由于正则表达式参数,“+” “*”需要使用“\+” “\*”进行转义,否则,会报错java.util.regex.PatternSyntaxException

public static void main(String[] args) {
    String str = "a+b+c+d+e";
    String[] arr1 = str.split("\\+"); // ["a","b","c","d","e"] length=5
    String[] arr2 = str.split("+"); // java.util.regex.PatternSyntaxException: Dangling meta character '+' near index 0
}

Best regards
Wang Yuheng

转载请注明出处WangYuheng’s Blog

Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。

初识markdown

       第一次接触markdown,用在blog的编辑器上,发现并没有传统的富文本支持,自己的代码格式又是一片混乱,然后发现了一句“支持markdown语法”。经过查找之后发现,markdown确实可以提供非常良好的写作体验。
markdown给我的第一感觉是类似于HTML语言,同样都是通过简单的标记实现样式显示,但是markdown要简单的多,并且通过普通的文本编辑器就可书写,也可以非常方便的进行移植。

markdown优点

  • 纯文本实现,兼容各种文本编辑器,移植行好
  • 标签简单,可读性好
  • 插件众多,扩展性强
  • 可导出为HTML、PDF等多种格式

我最看重的一点是,对于blog而言,markdown能让我更专注于文字内容本身,而不用关心布局。这有助于让我摆脱网站布局和繁重的word。


学习markdown

markdown语言简单,容易记忆,只需了解一些常用的标记方式,就可实现文字的编辑工作。
(注:markdown的标准语言为:标签和文字内容之间要保留一个空格。)

常用标记

标题

将一句话作为文章的标题,只需在文字前加上#即可。

# 一级标题
## 二级标题
### 三级标题

以此类推,markdown和HTML一样,也提供了6种不同大小的标题方式。

列表

列表分为有序列表和无序列表两种:

无序列表只需在文字前加上-*,可混合使用,推荐使用-

- 列表1
* 列表2
- 列表3
  • 列表1
  • 列表2
  • 列表3

有序列表直接在文字前加上“1.” “2.”,可以全部输入数字“1.” ,markdown会自动实现排序

1. 列表1
1. 列表2
1. 列表3
  1. 列表1
  2. 列表2
  3. 列表3

格式

提供了非常方便的粗体和斜体格式规则 一个* 包含的文字为斜体, 两个*包含则为粗体

*斜体格式*

斜体格式

**粗体格式**

粗体格式

引用

引用外部一段文字的语法非常简单,只需在文字前加上大于号>
>这是一段引用的文字

这是一段引用的文字

链接

[链接](http://wangyuheng.github.io)

链接

图片

图片和链接的使用方式类似,差别在于图片需要前面加一个!
![](http://wangyuheng.github.io/images/searchicon.png)

表格

| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |
Tables Are Cool
col 3 is right-aligned $1600
col 2 is centered $12
zebra stripes are neat $1

分割线

分割线的语法很简单,只需要三个*就可以,相当于HTML中的
,文本会另起一行
***


markdown相关软件


结语

通过上面的简单介绍,已经可以在提供了markdown的环境下,简单的使用这一写作神奇了。至于更高级的功能、软件,以及熟练程度,都需要在实际的使用过程中慢慢积累。
最后,祝您写作愉快!


Best regards
Wang Yuheng