mysqL和sql server 多表批量更新

使用inner join 进行表更新sql 与mysql 的区别:

mysql:
UPDATE 表A w  INNER JOIN 表B d ON W.wID=D.wID  SET W.字段=新数据

 

sql server:
UPDATE W
SET W.字段=新数据
FROM 表a W
INNER JOIN 表B d ON W.wID=D.wid

发表在 mysql | mysqL和sql server 多表批量更新已关闭评论

在java中写出完美的单例模式

1. 前言

 

 

 

单例(Singleton)应该是开发者们最熟悉的设计模式了,并且好像也是最容易实现的——基本上每个开发者都能够随手写出——但是,真的是这样吗?

 

 

 

作为一个Java开发者,也许你觉得自己对单例模式的了解已经足够多了。我并不想危言耸听说一定还有你不知道的——毕竟我自己的了解也的确有限,但究竟你自己了解的程度到底怎样呢?往下看,我们一起来聊聊看~

 

 

 

 

 

2. 什么是单例?

 

 

 

单例对象的类必须保证只有一个实例存在——这是维基百科上对单例的定义,这也可以作为对意图实现单例模式的代码进行检验的标准。

 

 

 

对单例的实现可以分为两大类——懒汉式和饿汉式,他们的区别在于:

 

 

 

懒汉式:指全局的单例实例在第一次被使用时构建。

 

饿汉式:指全局的单例实例在类装载时构建。

 

 

 

从它们的区别也能看出来,日常我们使用的较多的应该是懒汉式的单例,毕竟按需加载才能做到资源的最大化利用嘛~

 

 

 

3. 懒汉式单例

 

 

 

先来看一下懒汉式单例的实现方式。

 

 

 

3.1 简单版本

 

 

 

看最简单的写法Version 1:

 

 

// Version 1

public class Single1 {

private static Single1 instance;

public static Single1 getInstance() {

if (instance == null) {

instance = new Single1();

}

return instance;

}

}

 

或者再进一步,把构造器改为私有的,这样能够防止被外部的类调用。

 

 

// Version 1.1

public class Single1 {

private static Single1 instance;

private Single1() {}

public static Single1 getInstance() {

if (instance == null) {

instance = new Single1();

}

return instance;

}

}

 

我仿佛记得当初学校的教科书就是这么教的?—— 每次获取instance之前先进行判断,如果instance为空就new一个出来,否则就直接返回已存在的instance。

 

 

 

这种写法在大多数的时候也是没问题的。问题在于,当多线程工作的时候,如果有多个线程同时运行到if (instance == null),都判断为null,那么两个线程就各自会创建一个实例——这样一来,就不是单例了。

 

 

 

3.2 synchronized版本

 

 

 

那既然可能会因为多线程导致问题,那么加上一个同步锁吧!

 

 

 

修改后的代码如下,相对于Version1.1,只是在方法签名上多加了一个synchronized:

 

 

// Version 2

public class Single2 {

private static Single2 instance;

private Single2() {}

public static synchronized Single2 getInstance() {

if (instance == null) {

instance = new Single2();

}

return instance;

}

}

 

OK,加上synchronized关键字之后,getInstance方法就会锁上了。如果有两个线程(T1、T2)同时执行到这个方法时,会有其中一个线程T1获得同步锁,得以继续执行,而另一个线程T2则需要等待,当第T1执行完毕getInstance之后(完成了null判断、对象创建、获得返回值之后),T2线程才会执行执行。——所以这端代码也就避免了Version1中,可能出现因为多线程导致多个实例的情况。

 

 

 

但是,这种写法也有一个问题:给gitInstance方法加锁,虽然会避免了可能会出现的多个实例问题,但是会强制除T1之外的所有线程等待,实际上会对程序的执行效率造成负面影响。

 

 

 

3.3 双重检查(Double-Check)版本

 

 

 

Version2代码相对于Version1d代码的效率问题,其实是为了解决1%几率的问题,而使用了一个100%出现的防护盾。那有一个优化的思路,就是把100%出现的防护盾,也改为1%的几率出现,使之只出现在可能会导致多个实例出现的地方。

 

 

 

——有没有这样的方法呢?当然是有的,改进后的代码Vsersion3如下:

 

 

// Version 3

public class Single3 {

private static Single3 instance;

private Single3() {}

public static Single3 getInstance() {

if (instance == null) {

synchronized (Single3.class) {

if (instance == null) {

instance = new Single3();

}

}

}

return instance;

}

}

 

这个版本的代码看起来有点复杂,注意其中有两次if (instance == null)的判断,这个叫做『双重检查 Double-Check』。

 

 

 

第一个if (instance == null),其实是为了解决Version2中的效率问题,只有instance为null的时候,才进入synchronized的代码段——大大减少了几率。

 

 

 

第二个if (instance == null),则是跟Version2一样,是为了防止可能出现多个实例的情况。

 

 

 

—— 这段代码看起来已经完美无瑕了。

 

……

 

……

 

……

 

—— 当然,只是『看起来』,还是有小概率出现问题的。

 

 

 

这弄清楚为什么这里可能出现问题,首先,我们需要弄清楚几个概念:原子操作、指令重排。

 

 

 

知识点:什么是原子操作?

 

 

 

简单来说,原子操作(atomic)就是不可分割的操作,在计算机中,就是指不会因为线程调度被打断的操作。

 

 

 

比如,简单的赋值是一个原子操作:

 

m = 6; // 这是个原子操作

假如m原先的值为0,那么对于这个操作,要么执行成功m变成了6,要么是没执行m还是0,而不会出现诸如m=3这种中间态——即使是在并发的线程中。

 

 

 

而,声明并赋值就不是一个原子操作:

 

int n = 6; // 这不是一个原子操作

对于这个语句,至少有两个操作:

 

 

 

①声明一个变量n

 

②给n赋值为6

 

 

 

——这样就会有一个中间状态:变量n已经被声明了但是还没有被赋值的状态。

 

——这样,在多线程中,由于线程执行顺序的不确定性,如果两个线程都使用m,就可能会导致不稳定的结果出现。

 

 

 

知识点:什么是指令重排?

 

 

 

简单来说,就是计算机为了提高执行效率,会做的一些优化,在不影响最终结果的情况下,可能会对一些语句的执行顺序进行调整。

 

比如,这一段代码:

 

 

int a ; // 语句1

 

a = 8 ; // 语句2

 

int b = 9 ; // 语句3

 

int c = a + b ; // 语句4

 

正常来说,对于顺序结构,执行的顺序是自上到下,也即1234。

 

 

 

但是,由于指令重排的原因,因为不影响最终的结果,所以,实际执行的顺序可能会变成3124或者1324。

 

 

 

由于语句3和4没有原子性的问题,语句3和语句4也可能会拆分成原子操作,再重排。

 

 

 

——也就是说,对于非原子性的操作,在不影响最终结果的情况下,其拆分成的原子操作可能会被重新排列执行顺序。

 

 

 

OK,了解了原子操作和指令重排的概念之后,我们再继续看Version3代码的问题。

 

 

 

下面这段话直接从陈皓的文章(深入浅出单实例SINGLETON设计模式)中复制而来:

 

 

 

主要在于singleton = new Singleton()这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情。

 

 

 

1. 给 singleton 分配内存

 

 

 

2. 调用 Singleton 的构造函数来初始化成员变量,形成实例

 

 

 

3. 将singleton对象指向分配的内存空间(执行完这步 singleton才是非 null 了)

 

但是在 JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。

 

 

 

再稍微解释一下,就是说,由于有一个『instance已经不为null但是仍没有完成初始化』的中间状态,而这个时候,如果有其他线程刚好运行到第一层if (instance == null)这里,这里读取到的instance已经不为null了,所以就直接把这个中间状态的instance拿去用了,就会产生问题。

 

 

 

这里的关键在于——线程T1对instance的写操作没有完成,线程T2就执行了读操作。

 

 

 

3.4 终极版本:volatile

 

 

 

对于Version3中可能出现的问题(当然这种概率已经非常小了,但毕竟还是有的嘛~),解决方案是:只需要给instance的声明加上volatile关键字即可,Version4版本:

 

 

// Version 4

 

public class Single4 {

 

private static volatile Single4 instance;

 

private Single4() {}

 

public static Single4 getInstance() {

 

if (instance == null) {

 

synchronized (Single4.class) {

 

if (instance == null) {

 

instance = new Single4();

 

}

 

}

 

}

 

return instance;

 

}

 

}

 

volatile关键字的一个作用是禁止指令重排,把instance声明为volatile之后,对它的写操作就会有一个内存屏障(什么是内存屏障?),这样,在它的赋值完成之前,就不用会调用读操作。

 

 

 

注意:volatile阻止的不singleton = new Singleton()这句话内部[1-2-3]的指令重排,而是保证了在一个写操作([1-2-3])完成之前,不会调用读操作(if (instance == null))。

 

 

 

——也就彻底防止了Version3中的问题发生。

 

——好了,现在彻底没什么问题了吧?

 

……

 

……

 

……

 

 

 

好了,别紧张,的确没问题了。大名鼎鼎的EventBus中,其入口方法EventBus.getDefault()就是用这种方法来实现的。

 

……

 

……

 

……

 

不过,非要挑点刺的话还是能挑出来的,就是这个写法有些复杂了,不够优雅、简洁。

 

 

 

4. 饿汉式单例

 

 

 

下面再聊了解一下饿汉式的单例。

 

 

 

如上所说,饿汉式单例是指:指全局的单例实例在类装载时构建的实现方式。

 

 

 

由于类装载的过程是由类加载器(ClassLoader)来执行的,这个过程也是由JVM来保证同步的,所以这种方式先天就有一个优势——能够免疫许多由多线程引起的问题。

 

 

 

4.1 饿汉式单例的实现方式

 

 

 

饿汉式单例的实现如下:

 

 

//饿汉式实现

 

public class SingleB {

 

private static final SingleB INSTANCE = new SingleB();

 

private SingleB() {}

 

public static SingleB getInstance() {

 

return INSTANCE;

 

}

 

}

 

对于一个饿汉式单例的写法来说,它基本上是完美的了。

 

 

 

所以它的缺点也就只是饿汉式单例本身的缺点所在了——由于INSTANCE的初始化是在类加载时进行的,而类的加载是由ClassLoader来做的,所以开发者本来对于它初始化的时机就很难去准确把握:

 

 

 

可能由于初始化的太早,造成资源的浪费

 

 

 

如果初始化本身依赖于一些其他数据,那么也就很难保证其他数据会在它初始化之前准备好。

 

 

 

当然,如果所需的单例占用的资源很少,并且也不依赖于其他数据,那么这种实现方式也是很好的。

 

 

 

知识点:什么时候是类装载时?

 

 

 

前面提到了单例在类装载时被实例化,那究竟什么时候才是『类装载时』呢?

 

 

 

不严格的说,大致有这么几个条件会触发一个类被加载:

 

 

 

1. new一个对象时

 

2. 使用反射创建它的实例时

 

3. 子类被加载时,如果父类还没被加载,就先加载父类

 

4. jvm启动时执行的主类会首先被加载

 

 

 

5. 一些其他的实现方式

 

 

 

5.1 Effective Java 1 —— 静态内部类

 

 

 

《Effective Java》一书的第一版中推荐了一个中写法:

 

 

// Effective Java 第一版推荐写法

 

public class Singleton {

 

private static class SingletonHolder {

 

private static final Singleton INSTANCE = new Singleton();

 

}

 

private Singleton (){}

 

public static final Singleton getInstance() {

 

return SingletonHolder.INSTANCE;

 

}

 

}

 

这种写法非常巧妙:

 

 

 

对于内部类SingletonHolder,它是一个饿汉式的单例实现,在SingletonHolder初始化的时候会由ClassLoader来保证同步,使INSTANCE是一个真·单例。

 

 

 

同时,由于SingletonHolder是一个内部类,只在外部类的Singleton的getInstance()中被使用,所以它被加载的时机也就是在getInstance()方法第一次被调用的时候。

 

 

 

——它利用了ClassLoader来保证了同步,同时又能让开发者控制类加载的时机。从内部看是一个饿汉式的单例,但是从外部看来,又的确是懒汉式的实现。

 

 

 

简直是神乎其技。

 

 

 

5.2 Effective Java 2 —— 枚举

 

 

 

你以为到这就算完了?不,并没有,因为厉害的大神又发现了其他的方法。

 

 

 

《Effective Java》的作者在这本书的第二版又推荐了另外一种方法,来直接看代码:

 

 

// Effective Java 第二版推荐写法

 

public enum SingleInstance {

 

INSTANCE;

 

public void fun1() {

 

// do something

 

}

 

}

 

 

 

// 使用

 

SingleInstance.INSTANCE.fun1();

 

看到了么?这是一个枚举类型……连class都不用了,极简。

 

 

 

由于创建枚举实例的过程是线程安全的,所以这种写法也没有同步的问题。

 

 

 

作者对这个方法的评价:

 

 

 

这种写法在功能上与共有域方法相近,但是它更简洁,无偿地提供了序列化机制,绝对防止对此实例化,即使是在面对复杂的序列化或者反射攻击的时候。虽然这中方法还没有广泛采用,但是单元素的枚举类型已经成为实现Singleton的最佳方法。

 

 

 

枚举单例这种方法问世一些,许多分析文章都称它是实现单例的最完美方法——写法超级简单,而且又能解决大部分的问题。

 

 

 

不过我个人认为这种方法虽然很优秀,但是它仍然不是完美的——比如,在需要继承的场景,它就不适用了。

 

 

 

6. 总结

 

 

 

OK,看到这里,你还会觉得单例模式是最简单的设计模式了么?再回头看一下你之前代码中的单例实现,觉得是无懈可击的么?

 

 

 

可能我们在实际的开发中,对单例的实现并没有那么严格的要求。比如,我如果能保证所有的getInstance都是在一个线程的话,那其实第一种最简单的教科书方式就够用了。再比如,有时候,我的单例变成了多例也可能对程序没什么太大影响……

 

 

 

但是,如果我们能了解更多其中的细节,那么如果哪天程序出了些问题,我们起码能多一个排查问题的点。早点解决问题,就能早点回家吃饭……

 

 

 

—— 还有,完美的方案是不存在,任何方式都会有一个『度』的问题。比如,你的觉得代码已经无懈可击了,但是因为你用的是JAVA语言,可能ClassLoader有些BUG啊……你的代码谁运行在JVM上的,可能JVM本身有BUG啊……你的代码运行在手机上,可能手机系统有问题啊……你生活在这个宇宙里,可能宇宙本身有些BUG啊……

 

 

 

所以,尽力做到能做到的最好就行了。

 

 

 

—— 感谢你花费了不少时间看到这里,但愿你没有觉

来源:http://www.cnblogs.com/dongyu666/p/6971783.html

发表在 java | 在java中写出完美的单例模式已关闭评论

敏捷开发中个一些概念及要点

名词一:backlog

 

一、什么是迭代backlog

 

1、迭代Backlog是团队在一轮迭代中需要完成的 任务清单,是迭代计划会议确定的内容;

 

2、迭代Backlog是团队在召开迭代计划会议的时 候从产品Backlog挑选出高优先级的需求清单;

 

3、每项任务信息包含当前剩余工作量和负责人

 

 

 

二、迭代Backlog关键要点

 

1、任务清单是由完整团队成员 自己定义和分解的,而不是上级指派;

 

2、与需求相关的所有工作都可以作 为一个任务,每个任务要落实到具体的责任人;

 

3、任务的颗粒度要足够小, 工作量大于2天的任务要进一步分解;

 

4、用小时作为任务剩余工作量 的估计单位,并且每日估计和刷新

 

 

 

名词二:完成标准(DoD )

 

1、基于”随时可向用户发布”的目标 制定衡量团队工作是否已完成的标准

 

 

 

 

 

名词三:迭代计划会议

 

一、什么是迭代计划会议

 

1、每轮迭代启动前,团队共同讨论本轮迭代详细开发计划的过程, 输入时产品backlog,输出是团队迭代Backlog

 

二、迭代计划会议内容

 

1、澄清需求、对“完成标准”达成一致

 

2、工作量估计、根据团队能力确定本轮迭代交付内容

 

3、细化、分配迭代任务和初始工作计划

 

 

 

三、迭代会议好处

 

1、通过充分讨论,使团队成员对任务和完成标准理解一致

 

2、团队共同参与,促进团队成员更认真对待自己的承诺

 

 

 

四、迭代会议关键要点

 

1、充分参与:Scrum Master确保PO和Team 充分参与讨论,达成理解一致

 

2、互相承诺:Team承诺完成迭代 Backlog中的需求并达到‘’完成标准“, PO承诺在短迭代周期不增加需求(2-4周)

 

3、确定内部任务:Team和PO协商把一些 内部任务放入迭代中(例如重构、持续集成、 集成环境搭建),由PO考虑并与其它外部需求一期排序

 

 

 

名词四、每日站立会议

 

一、什么是每日站立会议

 

1、由Scrum Master组织,Team成员全体站立参与

 

2、聚焦在下面四个主题

 

2.1、我昨天为本项目做了什么?

 

2.2、我今天计划为本项目做了什么

 

2.3、我需要什么帮助以更高效的工作

 

2.4、SM关系运到哪些难的问题或阻碍

 

二、每日站立会议的关键要点

 

1、准时开始:按计划会议制定的时间地点开会 形成团队成员带 自然习惯

 

2、搞笑会议:会议限时15分钟, 每个人都保持站立,依次发言, 不讨论与会议四个主题无关的 事情(如技术解决方案)

 

3、问题跟踪:SM应该记录下问题并跟踪解决

 

 

 

名词五:迭代回顾会议

 

一、目的

 

1、分享好的经验和发现改进点, 促进团队不断进步

 

二、围绕三个问题

 

1、本次迭代有哪些做得好

 

2、本次迭代我们在哪些方面还能做得更好

 

3、我们在下个迭代准备在哪些方面改进

 

三、迭代回顾会议的关键要点

 

1、会议气氛:Team全员参加,气氛宽松自由, 畅所欲言,头脑风暴发现问题,共同分析原因

 

2、关注重点:Team共同讨论优先级, 将精力放在最需要的地方(关注几个改进就够了,如TOP3)

 

3、会议结论要跟踪闭环:可以放入迭代backlog中

 

 

名词六:持续集成

一、概念

 

1、持续集成(CI)是一项软件开发实践, 其中团队的成员经常集成他们的工作, 通常每日每人至少集成一次,每次集成通过自动化构建完成

二、好处

1、大幅度缩短反馈周期,实时反映产品真实质量状态

2、缺陷在引入当天就被发现并解决,降低缺陷修改成本

 

3、将集成工作分散在平时, 通过每天生成可部署的软件, 避免产品最终集成时爆发大量问题

发表在 管理 | 敏捷开发中个一些概念及要点已关闭评论

敏捷开发的价值观与十二条原则

敏捷不是某一种方法论、过程或框架,更不是字面意义上的敏捷,而是一组价值观与原则。

 

敏捷开发的核心理念:

 

敏捷开发的核心理念:敏捷开发的核心理念就是以最简单有效的方式快速地达成目标,并在这个过程中及时地响应外界的变化,做出迅速的调整。

敏捷开发的第一条价值观就是“ 以人为本”,强调“ 个体(人)” 及“ 个体” 间的沟通与协作在软件开发过程中的重要性。这个顺序不是偶然而为之的,敏捷开发将重视个体潜能的激发和团队的高效协作作为其所推崇的第一价值观。

敏捷开发的第二条价值观就是“ 目标导向”。同其他众多管理理论和模型一样,敏捷开发认同目标导向是成功的关键,因为没有目标也就无所谓成功。敏捷开发的价值观中清楚地阐明,软件开发的目标是“ 可工作的软件”,而不是面面俱到的文档。而遗憾的是,很多软件项目已经在纷繁的文档之中迷失了自己的目标。

敏捷开发的第三条价值观就是“ 客户为先”。虽然敏捷开发强调的第一价值观是“ 以人为本”,但敏捷宣言的缔造者们并没有忘记客户,相反他们真正的理解客户的需求、懂得如何与客户合作。敏捷价值观里强调的“ 客户为先”即不是简单地把客户当作“ 上帝”、刻板的推崇“ 客户至上”,客户要求什么、我们就做什么;也不是把客户当作“ 谈判桌上的对手” 甚至“ 敌人”,去斗智斗勇。敏捷价值观把客户当成了合作者和伙伴,把自己的使命定位为“ “ 帮助客户取得竞争优势”。

敏捷开发的第四条价值观就是“ 拥抱变化”。人们常说“ 世界上唯一不变的就是变化”,大多数人也相信事实确实如此。而以往很多的软件项目却忽视了这一点,或者更准确地说是他们不愿意“ 正视”。他们总是试图用详尽的计划去预先穷举这些变化,然后又试图通过严格遵循计划来控制变化的发生,而结果往往是被不断涌现的变化击垮。敏捷开发价值观中承认变化是软件开发的一部分、并相信正是客户在不断变化其需求的过程中明晰了其真正的需要。因而敏捷开发欢迎变化、拥抱变化,并可坦然应对变化,正是这些变化为客户和项目带来了价值。

最后,还应记住敏捷宣言中的最后一句话:“ 尽管右项有其价值,我们更重视左项的价值”—敏捷宣言并未否定或贬损“ 右项” 的价值,在敏捷开发的价值观中承认“ 流程和工具”、“ 详尽的文档”、“ 合同谈判” 以及“ 遵循计划” 的重要性,只是两相比较,“ 更重视左项的价值”。

敏捷开发的十二条原则:

 

1)我们最重要的目标,是通过持续不断地及早交付有价值的软件使客户满意。

2)欣然面对需求变化,即使在开发后期也一样。为了客户的竞争优势,敏捷过程掌控变化。

3)经常地交付可工作的软件,相隔几星期或一两个月,倾向于采取较短的周期。

4)业务人员和开发人员必须相互合作,项目中的每一天都不例外。

5)激发个体的斗志,以他们为核心搭建项目。提供所需的环境和支援,辅以信任,从而达成目标。

6)不论团队内外,传递信息效果最好和效率最高的方式是面对面的交谈。

7)可工作的软件是进度的首要度量标准。

8)敏捷过程倡导可持续开发。责任人、开发人员和用户要能够共同维持其步调稳定延续。

9)坚持不懈地追求技术卓越和良好设计,敏捷能力由此增强。

10)以简洁为本,它是极力减少不必要工作量的艺术。

11)最好的架构、需求和设计出自组织团队。

12)团队定期地反思如何能提高成效,并依此调整自身的举止表现。

– 敏捷开发原则是对敏捷价值观的解释和实践,它将敏捷的价值观落实到具体的可操作的原则之上,遵循这十二条原则,是敏捷软件开发项目得以成功的基石。

– 这十二条原则囊括了软件项目管理的所有基本流程,而且这些流程足够具体,它告诉我们项目管理的第一步就是要明确目标,而软件项目的终极目标就是“ 不断地及早交付有价值的软件使客户满意”;它提示我们软件工程的起始点是需求,而需求的固有特征就是不断变化,敏捷开发过程要响应变化;它强调“ 可工作的软件是进度的首要度量标准”,因而需要以尽可能短的周期“ 经常地交付可工作的软件”;它重视相关干系人的协调(“ 业务人员和开发人员必须相互合作”、“ 责任人、开发人员和用户要能够共同维持其步调稳定延续”),重视激发个人潜能(“ 激发个体的斗志”),要求团队使用最高效的沟通方式(“ 面对面的交谈”);它推崇技术变革所具备的强大能量(“ 坚持不懈地追求技术卓越和良好设计”);它强调精益生产(“ 简洁为本”),要求项目采用自组织团队管理模式,并指出“ 定期总结反思” 是校准团队行为、最终达成目标的有效途径。

发表在 管理 | 敏捷开发的价值观与十二条原则已关闭评论

mysql可重复读select和update

mysql可重复读事物开启后,如果多次查询同一数据,而中间对这一数据update操作,那么update之后的同一查询可能是不可重复读,update可以打破同一查询条件的可重复读。

update时读取数据是最新版本的数据,而select是到当前事物版本为止的数据。当更新成功之后,当前版本即为最新版本,再次select,读取的是最新的数据

发表在 mysql | mysql可重复读select和update已关闭评论

Vue指令大全

1. v-text
v-text主要用来更新textContent,可以等同于JS的text属性。

<span v-text="msg"></span>

这两者等价:

<span>{{msg}}</span>

2. v-html
双大括号的方式会将数据解释为纯文本,而非HTML。为了输出真正的HTML,可以用v-html指令。它等同于JS的innerHtml属性。

<div v-html="rawHtml"></div>

这个div的内容将会替换成属性值rawHtml,直接作为HTML进行渲染。


3. v-pre
v-pre主要用来跳过这个元素和它的子元素编译过程。可以用来显示原始的Mustache标签。跳过大量没有指令的节点加快编译。

<div id="app">
    <span v-pre>{{message}}</span>  //这条语句不进行编译
    <span>{{message}}</span>
</div>

最终仅显示第二个span的内容


4. v-cloak
这个指令是用来保持在元素上直到关联实例结束时进行编译。

<div id="app" v-cloak>
    <div>
        {{message}}
    </div>
</div>
<script type="text/javascript">
    new Vue({
      el:'#app',
      data:{
        message:'hello world'
      }
    })
</script>

在页面加载时会闪烁,先显示:

<div>
    {{message}}
</div>

然后才会编译为:

<div>
    hello world!
</div>

5. v-once
v-once关联的实例,只会渲染一次。之后的重新渲染,实例极其所有的子节点将被视为静态内容跳过,这可以用于优化更新性能。

<span v-once>This will never change:{{msg}}</span>  //单个元素
<div v-once>//有子元素
    <h1>comment</h1>
    <p>{{msg}}</p>
</div>
<my-component v-once:comment="msg"></my-component>  //组件
<ul>
    <li v-for="i in list">{{i}}</li>
</ul>

上面的例子中,msg,list即使产生改变,也不会重新渲染。


6. v-if
v-if可以实现条件渲染,Vue会根据表达式的值的真假条件来渲染元素。

<a v-if="ok">yes</a>

如果属性值ok为true,则显示。否则,不会渲染这个元素。


7. v-else
v-else是搭配v-if使用的,它必须紧跟在v-if或者v-else-if后面,否则不起作用。

<a v-if="ok">yes</a>
<a v-else>No</a>

8. v-else-if
v-else-if充当v-if的else-if块,可以链式的使用多次。可以更加方便的实现switch语句。

<div v-if="type==='A'">
    A
</div>
<div v-if="type==='B'">
    B
</div>
<div v-if="type==='C'">
    C
</div>
<div v-else>
    Not A,B,C
</div>

9. v-show

<h1 v-show="ok">hello world</h1>

也是用于根据条件展示元素。和v-if不同的是,如果v-if的值是false,则这个元素被销毁,不在dom中。但是v-show的元素会始终被渲染并保存在dom中,它只是简单的切换css的dispaly属性。

注意:v-if有更高的切换开销
v-show有更高的初始渲染开销。
因此,如果要非常频繁的切换,则使用v-show较好;如果在运行时条件不太可能改变,则v-if较好


10. v-for
用v-for指令根据遍历数组来进行渲染
有下面两种遍历形式

<div v-for="(item,index) in items"></div>   //使用in,index是一个可选参数,表示当前项的索引
<div v-for="item of items"></div>   //使用of

下面是一个例子,并且在v-for中,拥有对父作用域属性的完全访问权限。

<ul id="app">
    <li v-for="item in items">
        {{parent}}-{{item.text}}
    </li>
</ul>
<script type="text/javascript">
    var example = new Vue({
      el:'#app',
      data:{
        parent:'父作用域'
        items:[
          {text:'文本1'},
          {text:'文本2'}
        ]
      }
    })
</script>

会被渲染为:

<ul id="app">
    <li>父作用域-文本1</li>
    <li>父作用域-文本2</li>
</ul>

注意:当v-for和v-if同处于一个节点时,v-for的优先级比v-if更高。这意味着v-if将运行在每个v-for循环中


11. v-bind
v-bind用来动态的绑定一个或者多个特性。没有参数时,可以绑定到一个包含键值对的对象。常用于动态绑定class和style。以及href等。
简写为一个冒号【

<1>对象语法

//进行类切换的例子
<div id="app">
    <!--当data里面定义的isActive等于true时,is-active这个类才会被添加起作用-->
    <!--当data里面定义的hasError等于true时,text-danger这个类才会被添加起作用-->
    <div :class="{'is-active':isActive, 'text-danger':hasError}"></div>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            isActive: true,  
            hasError: false
        }
    })
</script>

渲染结果:

<!--因为hasError: false,所以text-danger不被渲染-->
<div class = "is-active"></div>

<2>数组语法

<div id="app">
    <!--数组语法:errorClass在data对应的类一定会添加-->
    <!--is-active是对象语法,根据activeClass对应的取值决定是否添加-->
    <p :class="[{'is-active':activeClass},errorClass]">12345</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            activeClass: false,
            errorClass: 'text-danger'
        }
    })
</script>

渲染结果:

<!--因为activeClass: false,所以is-active不被渲染-->
<p class = "text-danger"></p>

<3>直接绑定数据对象

<div id="app">
    <!--在vue实例的data中定义了classObject对象,这个对象里面是所有类名及其真值-->
    <!--当里面的类的值是true时会被渲染-->
    <div :class="classObject">12345</div>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            classObject:{
                'is-active': false,
                'text-danger':true
            }           
        }
    })
</script>

渲染结果:

<!--因为'is-active': false,所以is-active不被渲染-->
<div class = "text-danger"></div>

12. v-model
这个指令用于在表单上创建双向数据绑定
v-model会忽略所有表单元素的value、checked、selected特性的初始值。因为它选择Vue实例数据做为具体的值。

<div id="app">
    <input v-model="somebody">
    <p>hello {{somebody}}</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            somebody:'小明'
        }
    })
</script>

这个例子中直接在浏览器input中输入别的名字,下面的p的内容会直接跟着变。这就是双向数据绑定。

v-model修饰符
<1> .lazy
默认情况下,v-model同步输入框的值和数据。可以通过这个修饰符,转变为在change事件再同步。

<input v-model.lazy="msg">

<2> .number
自动将用户的输入值转化为数值类型

<input v-model.number="msg">

<3> .trim
自动过滤用户输入的首尾空格

<input v-model.trim="msg">

13. v-on
v-on主要用来监听dom事件,以便执行一些代码块。表达式可以是一个方法名。
简写为:【 @

<div id="app">
    <button @click="consoleLog"></button>
</div>
<script>
    var app = new Vue({
        el: '#app',
        methods:{
            consoleLog:function (event) {
                console.log(1)
            }
        }
    })
</script>

事件修饰符

  • .stop 阻止事件继续传播
  • .prevent 事件不再重载页面
  • .capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理
  • .self 只当在 event.target 是当前元素自身时触发处理函数
  • .once 事件将只会触发一次
  • .passive 告诉浏览器你不想阻止事件的默认行为
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
<!-- 而不会等待 `onScroll` 完成  -->
<!-- 这其中包含 `event.preventDefault()` 的情况 -->
<div v-on:scroll.passive="onScroll">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用v-on:click.prevent.self阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

 

发表在 前端 | Vue指令大全已关闭评论

maven项目引入sqljdbc4 找不到包的完美 解决方案

详情查看:

https://mvnrepository.com/artifact/com.microsoft.sqlserver/sqljdbc4

pom.xml引入仓库地址:

<repositories>
    <repository>
        <id>clojars</id>
        <url>http://clojars.org/repo/</url>
    </repository>
</repositories>

 

发表在 java | maven项目引入sqljdbc4 找不到包的完美 解决方案已关闭评论

IntelliJ IDEA—IDEA2018激活 IDEA 2018.2激活教程 最新

激活方式:破解补丁(此方式有效期到2100年)

1、 下载破解补丁文件 JetbrainsCrack-2.9-release-enc.jar,路径为:百度云链接:https://pan.baidu.com/s/1rfOdn3suqyP2RUtIsZqbkQ 密码:etr5(失效)
2018.8.1更新最新破解补丁JetbrainsCrack-2.10-release-enc.jar,百度云下载地址:https://pan.baidu.com/s/1qgXrr8yHBhAI9gcqRsxrbA 密码:9nrg (失效)
2018.8.15更新最新破解补丁JetbrainsCrack-3.1-release-enc.jar百度云下载地址:https://pan.baidu.com/s/1hcoSMVfdQD3UzvCaGUCK3w 密码:x56a

2、将补丁放在安装包的/bin路径下,如图中放置在最后的jar文件,并且 分别 对本文件夹(bin)下的idea.exe.vmoptions和idea64.exe.vmoptions这两个文件进行修改,打开文件在末尾添加如下配置指令:

windows版:-javaagent:D:/indea/bin/JetbrainsCrack-3.1-release-enc.jar

Mac版:-javaagent:../bin/JetbrainsCrack-3.1-release-enc.jar

说明:D:/indea/bin/ 是你IDEA的安装位置

3、保存编辑后的文件后,拷贝如下注册码

K71U8DBPNE-eyJsaWNlbnNlSWQiOiJLNzFVOERCUE5FIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IkZvciBlZHVjYXRpb25hbCB1c2Ugb25seSIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiSUkiLCJwYWlkVXBUbyI6IjIwMTktMDUtMDQifSx7ImNvZGUiOiJSUzAiLCJwYWlkVXBUbyI6IjIwMTktMDUtMDQifSx7ImNvZGUiOiJXUyIsInBhaWRVcFRvIjoiMjAxOS0wNS0wNCJ9LHsiY29kZSI6IlJEIiwicGFpZFVwVG8iOiIyMDE5LTA1LTA0In0seyJjb2RlIjoiUkMiLCJwYWlkVXBUbyI6IjIwMTktMDUtMDQifSx7ImNvZGUiOiJEQyIsInBhaWRVcFRvIjoiMjAxOS0wNS0wNCJ9LHsiY29kZSI6IkRCIiwicGFpZFVwVG8iOiIyMDE5LTA1LTA0In0seyJjb2RlIjoiUk0iLCJwYWlkVXBUbyI6IjIwMTktMDUtMDQifSx7ImNvZGUiOiJETSIsInBhaWRVcFRvIjoiMjAxOS0wNS0wNCJ9LHsiY29kZSI6IkFDIiwicGFpZFVwVG8iOiIyMDE5LTA1LTA0In0seyJjb2RlIjoiRFBOIiwicGFpZFVwVG8iOiIyMDE5LTA1LTA0In0seyJjb2RlIjoiR08iLCJwYWlkVXBUbyI6IjIwMTktMDUtMDQifSx7ImNvZGUiOiJQUyIsInBhaWRVcFRvIjoiMjAxOS0wNS0wNCJ9LHsiY29kZSI6IkNMIiwicGFpZFVwVG8iOiIyMDE5LTA1LTA0In0seyJjb2RlIjoiUEMiLCJwYWlkVXBUbyI6IjIwMTktMDUtMDQifSx7ImNvZGUiOiJSU1UiLCJwYWlkVXBUbyI6IjIwMTktMDUtMDQifV0sImhhc2giOiI4OTA4Mjg5LzAiLCJncmFjZVBlcmlvZERheXMiOjAsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0

———————

4、打开IDEA,进入激活窗口此时需要选择 激活码(Activation code) 的激活方式,并输入刚刚拷贝激活码进行激活
5、激活完成
———————
原文:https://blog.csdn.net/halen001/article/details/81137092

发表在 java, 开发工具 | IntelliJ IDEA—IDEA2018激活 IDEA 2018.2激活教程 最新已关闭评论

VirtualBox实现内外网络互访问的配置

一、使虚拟电脑centos能够上网 
原理:
NAT(网络地址转换模式)
  使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。也就是说,使用NAT模式可以实现在虚拟系统里访问互联网。NAT模式下的虚拟系统的TCP/IP配置信息是由VMnet8(NAT)虚拟网络的DHCP服务器提供的,无法进行手工修改,因此虚拟系统也就无法和本局域网中的其他真实主机进行通讯。采用NAT模式最大的优势是虚拟系统接入互联网非常简单,你不需要进行任何其他的配置,只需要宿主机器能访问互联网即可。
  如果你想利用VMWare安装一个新的虚拟系统,在虚拟系统中不用进行任何手工配置就能直接访问互联网,建议你采用NAT模式。
步骤:
在VirtualBox中设置网络连接,启用NAT连接模式。
centos可以ping到Windows,但是Windows不能ping到centos
这个也好理解,因为NAT的网络连接模式就是虚拟机通过宿主机的网络来访问互联网,那么虚拟机当然知道宿主机的网络地址。但是反过来,Windows就不清楚到达10.0.2.15地址要如何经过路由了。
在这里要注意一下,centos的IP地址10.0.2.5是通过DHCP自动分配的。
二、使虚拟电脑centos能够与宿主机互联
这一部分的目标就是实现Windows能够ping通centos。
原理:
         bridged(桥接模式)
  在这种模式下,VirtualBox虚拟出来的操作系统就像是局域网中的一台独立的主机,它可以访问网内任何一台机器。在桥接模式下,你需要手工为虚拟系统配置IP地址、子网掩码,而且还要和宿主机器处于同一网段,这样虚拟系统才能和宿主机器进行通信。同时,由于这个虚拟系统是局域网中的一个独立的主机系统,那么就可以手工配置它的TCP/IP配置信息,以实现通过局域网的网关或路由器访问互联网。
使用桥接模式的虚拟系统和宿主机器的关系,就像连接在同一个Hub上的两台电脑。想让它们相互通讯,你就需要为虚拟系统配置IP地址和子网掩码,否则就无法通信。
如果你想利用VirtualBox在局域网内新建一个虚拟服务器,为局域网用户提供网络服务,就应该选择桥接模式。
步骤:
在VirtualBox中设置网络连接,开启Bridge Adapter连接模式
重启centos后ping宿主机,成功ping通
三、补充:第三种连接方式
在这里必须提一点,就是如果172.16.35.237这个IP地址已经被其他计算机使用怎么办,为了解决这种IP地址冲突的情况,我们来进一步了解host-only连接模式。
原理:
host-only(主机模式)
在某些特殊的网络调试环境中,要求将真实环境和虚拟环境隔离开,这时你就可采用host-only模式。在host-only模式中,所有的虚拟系统是可以相互通信的,但虚拟系统和真实的网络是被隔离开的。
提示:在host-only模式下,虚拟系统和宿主机器系统是可以相互通信的,相当于这两台机器通过双绞线互连。
在host-only模式下,虚拟系统的TCP/IP配置信息(如IP地址、网关地址、DNS服务器等),都是由VMnet1(host-only)虚拟网络的DHCP服务器来动态分配的。
如果你想利用VirtualBox创建一个与网内其他机器相隔离的虚拟系统,进行某些特殊的网络调试工作,可以选择host-only模式。
步骤:
在VirtualBox中设置网络连接,启用host-only连接模式。
重启centos后ping宿主机,成功ping通
四、常用命令
ip addr  查看centos主机网卡和ip
发表在 linux | VirtualBox实现内外网络互访问的配置已关闭评论

virtualBox虚拟机linux centos 挂载光盘

1、虚拟机加载虚拟光驱

登录后,依次选择 VituralBox 的设备-》分配光驱-》选择需要加载的 *.iso

 

2、创建挂载点

mkdir /mnt/cdrom

 

3、 挂载

mount /dev/cdrom /mnt/cdrom

接下来就可以使用光盘的内容了

 

3、 卸载光盘

umount /mnt/cdrom

 

 

发表在 linux | virtualBox虚拟机linux centos 挂载光盘已关闭评论