为什么Spring官方推荐通过构造器注入

我们在使用Spring的时候,最方便的就是它的IOC(控制反转),也就是所有的Bean都交由

Spring进行管理,那么我们在看网上的文章或者自己在写代码的时候经常会像这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Service
public class TestService {

@Autowired
TestDao TestDao;

public void getInfo(){
}
}

@Service
public class TestService {

private final TestDao TestDao;

@Autowired
public TestService(TestDao TestDao){
this.TestDao = TestDao;
}

public void getInfo(){
}

}

但是貌似许多人都会使用第一种方式,因为这样简单方便,如果是采用第二种的话,每一次新增加一个bean,都需要在构造器的入参上面加一个参数,就会显得有点麻烦。

阅读更多

2019年07月第一周总结

这一周主要学习如下:

Vue

在使用ElementUI的时候有一个el-select标签,我们有一个需求就是需要在下拉列表的时候还需要过滤出特定的选项,但是ElementUI官方默认的过滤却只能支持 label 的筛选,所以这个时候就需要重新filter-method方法来过滤出所需要的选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<template>
<div>
<el-form v-model="selectData">
<el-select v-model="selectData.value" placeholder="请选择" filterable :filter-method="search" prop="value">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
<span style="float: left">{{ item.label }}</span>
<span style="float: right; font-size: 15px">{{ item.value }}</span>
</el-option>
</el-select>
</el-form>
</div>
</template>
<script>
export default {
data () {
return {
options: [{
value: '选项1',
label: '黄金糕'
}, {
value: '选项2',
label: '双皮奶'
}, {
value: '选项3',
label: '蚵仔煎'
}, {
value: '选项4',
label: '龙须面'
}, {
value: '选项5',
label: '北京烤鸭'
}],
selectData: {
value: ''
}
};
},
methods: {
search (val) {
let copyObj2 = JSON.parse(JSON.stringify(this.options));
if (val != null && val !== '') {
this.options = copyObj2.filter((item) => {
if (item.value.indexOf(val) > -1) {
debugger;
return true;
} else {
return false;
}
});
} else {
this.options = copyObj2;
}
}
}
};
</script>
<style>

</style>

但是后来又说要把选择的值给另一个字段…于是我就在search方法下面加了一行this.otherField = val。。后来前端把那一行给去除了。。。然后修改为如下代码。

阅读更多

Es6.X升级到Es7.x的变化

ElasticSearch6.升级至ElasticSearch7.x的一些变化

由于最近需要将Es6.x升级至Es7,所以正好记录下在升级过程中遇到的一些问题,以便以后翻阅。

区别

Es7.x系列中取消了Type

Es6系列之前,创建一个索引是需要index,type这两个缺一不可的,例如如下请求:

阅读更多

vue里面冒号和非冒号区别

vue里面冒号和非冒号的却别

今天在使用Vue的时候,突然发现了一个问题,就是在后端传过来的值因为是一个boolean类型的,但是前端又需要进行展示,由于我们使用的是ElementUI的话,于是参照官网上就是这样写的:

1
2
3
4
<el-select v-model="option_boolean">
<el-option label="1" value="true"></el-option>
<el-option label="2" value="false"></el-option>
</el-select>

但是此时页面上展示并非是 1 和 2 ,而是 true 和 false。如下:

阅读更多

数据库调优(一)

开篇

在上一篇文章中,我们有一个表,里面的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> select * from org_copy;
+--------+-----------------+---------------+----------+
| org_id | org_name | org_parent_id | org_copy |
+--------+-----------------+---------------+----------+
| 1 | 一级部门 | 0 | 1 |
| 2 | 一一级部门 | 0 | 2 |
| 3 | 1.1级部门 | 1 | 3 |
| 4 | 1.2级部门 | 1 | 4 |
| 5 | 1.1.1部门 | 3 | 5 |
| 6 | 1.1.2部门 | 3 | 6 |
| 7 | 1.1.1.1部门 | 5 | 7 |
| 8 | 1.3部门 | 1 | 8 |
| 9 | 1.2.1部门 | 4 | 9 |
+--------+-----------------+---------------+----------+
9 rows in set (0.00 sec)

这应该是一个很基本的一个mysql表,同时我们在上一篇文章中,也执行了如下SQL。

1
2
3
4
5
6
7
8
mysql> explain SELECT * FROM org_copy WHERE org_name>'一级部门' and  org_parent_id=1;
+----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | org_copy | NULL | range | index_name | index_name | 768 | NULL | 1 | 11.11 | Using index condition |
+----+-------------+----------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

阅读更多

数据库最左原则以及理解

本次的实验是基于Mysql8版本。首先在数据库中有一个表,其结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> show create table org;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| org | CREATE TABLE `org` (
`org_id` int(5) NOT NULL,
`org_name` varchar(255) DEFAULT NULL,
`org_parent_id` int(5) DEFAULT NULL,
PRIMARY KEY (`org_id`),
KEY `index_name` (`org_name`,`org_parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

可以看到在这个表中,有一个主键org_id以及一个联合索引index_name。其他的并无特别之处。

最左原则

在Mysql里面,有一个最左原则,官网的介绍如下:

阅读更多

ElementUI使用rules遇到的一些问题

这些天一直在踩Vue的坑…今天遇到的一个问题是在一个父组件中,将某些数据通过props传递给子组件,同时在子组件里面也有相应的一些rules规则,但是在实际的开发中,却发现子组件的rules并未生效…反而一直提示对应的 message,后来才发现是跟 ElementUI 的prop有关。

首先看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<template>
<div>
<p>该Demo是为了测试Vue中rule和prop的不同</p>
<el-form :model="vehicles">
<el-form-item label="公共汽车车轮个数" prop="bus.wheel" :rules="{required: true,message: '请输入公共汽车车轮个数'}">
<el-input v-model="vehicles.bus.wheel" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="公共汽车司机驾照" prop="bus.driver.license" :rules="{validator: licenseCheck ,trigger:'blur'}">
<el-input v-model="vehicles.bus.driver.license" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="公共汽车车轮个数" prop="bus.driver.years">
<el-input v-model="vehicles.bus.driver.years" placeholder="请输入"></el-input>
</el-form-item>
<car :car="vehicles.car"></car>
</el-form>
</div>
</template>
<script>
import Car from './Car';

export default {
components: {
Car
},
data () {
return {
vehicles: {
bus: {
wheel: null,
driver: {
license: null,
years: null
}
},
car: {
wheel: null,
driver: {
license: null,
years: null
}
},
train: {
wheel: null,
driver: {
license: null,
years: null
}
}
},
person: {
child: {
year: null
}
}
};
},
methods: {
licenseCheck (rule, value, callback) {
let m = this.car;
console.log(m);
debugger;
if (value != null) {
if (value != 'A') {
callback(new Error('必须A照'));
} else {
callback();
}
}
},
init () {
console.log(this.car);
}
}
};
</script>
<style>

</style>

此时在这个组件中,一切都是正常的,但是一个完整的项目里面,是不可能将所有的元素都堆积在一个页面中,那样的话以后的维护就会非常的麻烦。所以此时就需要一个子组件,然后将父组件中一些数据传递至子组件。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<template>
<div>
<p>小汽车子组件</p>
<el-form-item label="小汽车车轮个数" prop="wheel" :rules="{required: true,message: '请输入公共汽车车轮个数'}">
<el-input v-model="car.wheel" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="小汽车司机驾照" prop="driver.license" :rules="{validator: licenseCheck ,trigger:'blur'}">
<el-input v-model="car.driver.license" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="小汽车车轮个数" prop="driver.years">
<el-input v-model="car.driver.years" placeholder="请输入"></el-input>
</el-form-item>
</div>
</template>
<script>
export default {
props: {
car: {
type: Object,
default: function () {
return {};
}
}
},
methods: {
licenseCheck (rule, value, callback) {
let m = this.car;
console.log(m);
debugger;
if (value != null) {
if (value <= 'D') {
callback(new Error('必须C照以上'));
} else {
callback();
}
}
},
init () {
console.log(this.car);
}
},
mounted () {
this.init();
}
};
</script>
<style>

</style>

阅读更多

在Vue中使用filters来进行字典值的转换

在Vue里面,经常会遇到一些字典值的转换,而这些字典值由于和后端进行了约定的,一般不会轻易的改变,所以在前后端开发的项目中,这种字典值最好的做法是前端独立的保存一份,自己在前端自行进行处理。

我们的做法是使用Vuexstore配合filters来进行前端的字典值转化,首先是在store里面将字典值进行固定,然后通过filters在页面中进行一个转换。

使用Store

Vue里面使用store首先需要安装vuex,安装完毕之后就可以直接在main.js里面直接引用了,但是为了统一管理还是决定新建一个store文件夹,然后将store相关的文件全部统一存放,新建完毕之后项目结构如下:

1
2
3
4
---App.vue
---main.js
---store
-----index.js
阅读更多

Vue中nextTick的使用

这段时间一直在负责一个前后端项目,前端是Vue+ElemeUI,由于自己之前只是会简单的使用 Vue 的一些初级命令,自然只能慢慢的踩坑,然后再出坑….。例如数组无法触发Vue的视图更新

刚开始在使用 Vue 的时候,一直都是在 created 方法里面获取后端数据进行渲染,这样用起来倒也没什么问题,只不过今天突然看到了 Vue 的nextTick 方法,感觉比之前在created里面请求后端更加高级。所以顺便研究了一波。

使用场景

nextTick常用于数据更新后,但是dom元素还未完成刷新,如何理解呢? 在 Vue 里面,更新 DOM 元素是异步的,也就是说当我们修改了数据之后,DOM元素并不会立即被刷新。参考深入响应式原理

如下Demo

阅读更多

JDK1.8下ConcurrentHashMap的一些理解(一)

在JDK1.8里面,ConcurrentHashMap在put方法里面已经将分段锁移除了,转而是CAS锁和synchronized

ConcurrentHashMap是Java里面同时兼顾性能和线程安全的一个键值对集合,同属于键值对的集合还有HashTable以及HashMap
HashTable是一个线程安全的类,因为它的所有public方法都被synchronized修饰,这样就导致了一个问题,就是效率太低。

虽然HashMapJDK1.8的并发场景下触发扩容时不会出现成环了,但是会出现数据丢失的情况。
所以如果需要在多线程的情况下(多读少写))使用Map集合的话,ConcurrentHashMap是一个不错的选择。

ConcurrentHashMap在JDK1.8的时候将put()方法中的分段锁Segment移除,转而采用一种CAS锁和synchronized来实现插入方法的线程安全。
如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
//省略相关代码
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
synchronized (f) {
//省略相关代码
}
if (binCount != 0) {
if (binCount >= TREEIFY_THRESHOLD)
treeifyBin(tab, i);
if (oldVal != null)
return oldVal;
break;
}
}
}
addCount(1L, binCount);
return null;
}
阅读更多