1
2
3
4
5
6
7
8
9
10
SELECT
TABLE_NAME AS `Table`,
(DATA_LENGTH + INDEX_LENGTH) AS `Size (B)`
FROM
information_schema.TABLES
WHERE
TABLE_SCHEMA = "database_name"
ORDER BY
(DATA_LENGTH + INDEX_LENGTH)
DESC;

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

import org.apache.ibatis.mapping.*;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class TestService {
@Autowired
SqlSessionFactory sqlSessionFactory;

public List<Map<String, Object>> query(String sqlString,String id, Map<String,Object> param){
Configuration configuration=sqlSessionFactory.getConfiguration();
if(!configuration.hasStatement(id)){
LanguageDriver xmlLanguageDriver=new XMLLanguageDriver();
SqlSource sqlSource=xmlLanguageDriver.createSqlSource(configuration, sqlString, Map.class);
BoundSql boundSql=sqlSource.getBoundSql(param);
MappedStatement ms = new MappedStatement.Builder(configuration, id, sqlSource, SqlCommandType.SELECT)
.resultMaps(new ArrayList<ResultMap>() {
{
add(new ResultMap.Builder(configuration, "defaultResultMap", Map.class, new ArrayList<>(0)).build());
}
}).build();
configuration.addMappedStatement(ms);
}
SqlSession sqlSession= sqlSessionFactory.openSession();
List<Map<String, Object>> results=sqlSession.selectList(id,param);
sqlSession.close();
return results;
}

@PostConstruct
public void test(){
Map<String,Object> map = new HashMap<>();
map.put("id","11961ca784b94d4e90e86584224796d6");
String sql = "<script>select id,title from t_table WHERE 1=1\n"
+ " <if test=\"id!=null and id!=''\">\n"
+ " AND id= #{id}\n"
+ " </if></script>";
List<Map<String, Object>> list = query(sql,"test",map);
for(Map<String,Object> m : list){
System.out.println("item:" + m.get("title"));
}
}
}

原文链接:https://www.jianshu.com/p/cfd4a7a4f5ac

使用命令 npm publish 发布一个包时,或有如下报错:

npm ERR! publish Failed PUT 403 npm ERR! code E403 npm ERR! no_perms Private mode enable, only admin can publish this module:… 解决过程如下:

检查仓库是否被设成了淘宝镜像库

1
2
npm config get registry
https://registry.npm.taobao.org/

如是,则设回原仓库

1
npm config set registry=http://registry.npmjs.org

登录账号(如未登录)

1
2
3
4
5
npm login
Username: username
Password: *******
Email: (this IS public)
foo@bar.com Logged in as username on [http://registry.npmjs.org/.](http://registry.npmjs.org/)

再次发布

1
npm publish

如发布成功,则再次将仓库地址设为淘宝镜像地址

1
npm config set registry=https://registry.npm.taobao.org/

原文来自:https://zhangzw.com/posts/20191205.html

在实际项目中我们经常会用到 List 转 Map 操作,在过去我们可能使用的是 for 循环遍历的方式。举个例子:

先定义类:

1
2
3
4
5
6
7
// 简单对象 
@Accessors(chain = true) // 链式方法
@lombok.Data
class User {
private String id;
private String name;
}

然后有这样一个 List:

1
2
3
4
5
List<User> userList = Lists.newArrayList(
new User().setId("A").setName("张三"),
new User().setId("B").setName("李四"),
new User().setId("C").setName("王五")
);

我们希望转成 Map 的格式为:

A-> 张三 B-> 李四 C-> 王五 过去的做法(循环):

1
2
3
4
Map<String, String> map = new HashMap<>();
for (User user : userList) {
map.put(user.getId(), user.getName());
}

使用 Java8 特性 Java8 中新增了 Stream 特性,使得我们在处理集合操作时更方便了。

以上述例子为例,我们可以一句话搞定:

1
userList.stream().collect(Collectors.toMap(User::getId, User::getName));

当然,如果希望得到 Map 的 value 为对象本身时,可以这样写:

1
userList.stream().collect(Collectors.toMap(User::getId, t -> t));

或:

1
userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

关于 Collectors.toMap 方法 Collectors.toMap 有三个重载方法:

1
2
3
4
5
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction);
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier);

参数含义分别是:

keyMapper:Key 的映射函数

valueMapper:Value 的映射函数

mergeFunction:当 Key 冲突时,调用的合并方法

mapSupplier:Map 构造器,在需要返回特定的 Map 时使用

还是用上面的例子,如果 List 中 userId 有相同的,使用上面的写法会抛异常:

1
2
3
4
5
6
List<User> userList = Lists.newArrayList(
new User().setId("A").setName("张三"),
new User().setId("A").setName("李四"), // Key 相同
new User().setId("C").setName("王五")
);
userList.stream().collect(Collectors.toMap(User::getId, User::getName));

// 异常: java.lang.IllegalStateException: Duplicate key 张三 at java.util.stream.Collectors.lambda$throwingMerger$114(Collectors.java:133) at java.util.HashMap.merge(HashMap.java:1245) at java.util.stream.Collectors.lambda$toMap$172(Collectors.java:1320) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at Test.toMap(Test.java:17) … 这时就需要调用第二个重载方法,传入合并函数,如:

1
userList.stream().collect(Collectors.toMap(User::getId, User::getName, (n1, n2) -> n1 + n2));

// 输出结果: A-> 张三李四 C-> 王五 第四个参数(mapSupplier)用于自定义返回 Map 类型,比如我们希望返回的 Map 是根据 Key 排序的,可以使用如下写法:

1
2
3
4
5
6
7
8
List<User> userList = Lists.newArrayList(
new User().setId("B").setName("张三"),
new User().setId("A").setName("李四"),
new User().setId("C").setName("王五")
);
userList.stream().collect(
Collectors.toMap(User::getId, User::getName, (n1, n2) -> n1, TreeMap::new)
);

// 输出结果: A-> 李四 B-> 张三 C-> 王五

近期一个项目需要用到简单的定时任务,需要支持配置文件里修改 执行周期。记录如下 maven依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

关键代码

1
2
3
4
5
6
7
8
@Bean
public SchedulingConfigurer schedulingConfigurer(){
return new SchedulingConfigurer() {
@Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.addCronTask(runnable,schedule);
}
};
}

完整代码

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
package com.example;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

@Value("${demo.schedule}")
String schedule;

public static void main(String[] args){
SpringApplication.run(DemoApplication.class, args);
}

@Bean
public SchedulingConfigurer schedulingConfigurer(){
return new SchedulingConfigurer() {
@Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.addCronTask(runnable,schedule);
}
};
}

Runnable runnable = new Runnable() {
int i;
@Override public void run() {
System.out.println("runing " + ++i);
}
};

}

在application.properties里加一行

1
demo.schedule=*/3 * * * * ?

这个表示 每3秒执行一次。

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
Student s1 = new Student("aa", 10,1);
Student s2 = new Student("bb", 20,2);
Student s3 = new Student("cc", 10,3);
List<Student> list = Arrays.asList(s1, s2, s3);

//装成list
List<Integer> ageList = list.stream().map(Student::getAge).collect(Collectors.toList()); // [10, 20, 10]

//转成set
Set<Integer> ageSet = list.stream().map(Student::getAge).collect(Collectors.toSet()); // [20, 10]

//转成map,注:key不能相同,否则报错
Map<String, Integer> studentMap = list.stream().collect(Collectors.toMap(Student::getName, Student::getAge)); // {cc=10, bb=20, aa=10}

//字符串分隔符连接
String joinName = list.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc)

//聚合操作
//1.学生总数
Long count = list.stream().collect(Collectors.counting()); // 3
//2.最大年龄 (最小的minBy同理)
Integer maxAge = list.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get(); // 20
//3.所有人的年龄
Integer sumAge = list.stream().collect(Collectors.summingInt(Student::getAge)); // 40
//4.平均年龄
Double averageAge = list.stream().collect(Collectors.averagingDouble(Student::getAge)); // 13.333333333333334
// 带上以上所有方法
DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(Student::getAge));
System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());

//分组
Map<Integer, List<Student>> ageMap = list.stream().collect(Collectors.groupingBy(Student::getAge));
//多重分组,先根据类型分再根据年龄分
Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getType, Collectors.groupingBy(Student::getAge)));

//分区
//分成两部分,一部分大于10岁,一部分小于等于10岁
Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));

//规约
Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get(); //40