继开 | 博客

热爱生活,努力学习,实现自己的价值


  • 短诗的序

  • 迷途自渡

  • 寒星三两

  • 林深见鹿

  • 记昨日书

  • 顾探往昔

Java使用mybatis 批量插入

发表于 2021-09-04
字数统计: 824 字 | 阅读时长 ≈ 4 min

mybatis的批量插入

我们的测试主体类是springboot环境中的一个控制器类,重要的代码如下,在我们的测试中Constants.MAX_BATCH_NUMBER = 10000。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@GetMapping("insert")
public void insertBatchData() {
// 构建一个list,大小为1百万条数据
long beginCreateList = System.currentTimeMillis();
List<Map<String, Object>> lists = new ArrayList<>();
for (int i = 0; i < 100000; i ++) {
Map<String, Object> map = new HashMap<>();
map.put("userId", i + "");
map.put("username", "huhx" + i);
map.put("password", "124" + i);
map.put("sex", 1);
map.put("address", System.currentTimeMillis());
lists.add(map);
}
long endCreateList = System.currentTimeMillis();
logger.debug("创建一个大小为10万的列表,耗时:" + (endCreateList - beginCreateList)); // 4103

// 插入数据
dbSessionTemplateSupport.simpleSqlInsertBatch("user.simpleInsertUserData", lists);
long endInsertData = System.currentTimeMillis();
logger.debug("插入10万数据,耗时:" + (endInsertData - endCreateList)); // 49649
}

一、我们每10000条数据提交一次事务

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
public class DbSessionTemplateSupport extends SqlSessionTemplate {

public DbSessionTemplateSupport(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}

// 支持批量的插入
public void baseInsertBatch(String sqlStatement, List<Map<String, Object>> list) {
SqlSession session = getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
if (list == null || list.size() < 1) {
return;
}
int listSize = list.size();
try {
// 如果提交的列表条数小于提交阀值
if (listSize <= Constants.MAX_BATCH_NUMBER) {
for (int i = 0; i < list.size(); i++) {
session.insert(sqlStatement, list.get(i));
}
session.commit();
} else {
for (int i = 0; i < list.size(); ) {
session.insert(sqlStatement, list.get(i));
i++;
if (i % Constants.MAX_BATCH_NUMBER == 0 || i == listSize) {
session.commit();
session.clearCache();
}
}
}
} catch (Exception e) {
session.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}

这种方式处理插入,仍旧比较慢(其实是很慢很慢,可能是我的代码问题,没有统计时间,太慢了)。但是这种方式可以支持oracle,下面的这种方式非常快,但是oracle不支持。

二、采用mysql支持的拼接式插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* mysql的批量插入方式,oracle不支持。
*
* @param sqlStatement
* @param list
*/
public void simpleSqlInsertBatch(String sqlStatement, List<Map<String, Object>> list) {
if (list == null || list.size() < 1) {
return;
}
// 如果提交的列表条数小于提交阀值
List<Map<String, Object>>[] splitLists = CommUtil.splitLists(list, Constants.MAX_BATCH_NUMBER);
for (List<Map<String, Object>> tempList : splitLists) {
insert(sqlStatement, tempList);
}
}

我们对原始的列表进行切割,然后依次的插入。每次的插入都是MAX_BATCH_NUMBER条数据。下面是切割的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 对一个列表按照splitNum进行分割。
*
* @param lists
* @param splitNum
* @param <T>
* @return
*/
public static <T> List<T>[] splitLists(List<T> lists, int splitNum) {
int listSize;
if (lists == null || (listSize = lists.size()) < 1) {
return new ArrayList[0];
}
int length = listSize % splitNum == 0 ? listSize / splitNum : listSize / splitNum + 1;
// 这里面如果用ArrayList,会在50行报错。ArrayList list = new List();这样会报错。
List<T>[] results = new List[length];
int fromIndex, toIndex;
for (int i = 0; i < length; i++) {
fromIndex = i * splitNum;
toIndex = (fromIndex + splitNum) > listSize ? listSize : (fromIndex + splitNum);
results[i] = lists.subList(fromIndex, toIndex);
}
return results;
}

插入的sql语句在mybatis中是使用for…each的方式,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- mysql的批量插入方式 -->
<insert id="simpleInsertUserData" parameterType="java.util.List">
INSERT INTO puser
(userId, username, password, address, sex)
VALUES
<foreach collection ="list" item="item" index= "index" separator =",">
(
#{item.userId},
#{item.username},
#{item.password},
#{item.address},
#{item.sex}
)
</foreach >
</insert>

10万条数据的分割时间加上插入到mysql数据库,这种方式耗时:15658毫秒。需要注意的是如果常数设置为10万条,也就是第10万插入一次。这种方式会报错的

解决需要XMANAGER软件来处理X11转发需求(不安装XMANAGER)

发表于 2021-09-03
字数统计: 94 字 | 阅读时长 ≈ 1 min

问题

xshell登录虚拟机之后,如果要用到带界面的工具就需要用xmanager来转发。

此问题会造成操作卡顿等问题。

解决办法

设置xshell的属性

X11转移的路径为:链接 > SSH > 隧道

将“转发X11连接到(X)”的勾选取消掉

然后重新打开会话,不再弹窗提示消息

Oracle,mysql,sqlserver三种数据库查询表获取表数据的前100条数据与排序时获取指定的条数.

发表于 2021-09-02
字数统计: 386 字 | 阅读时长 ≈ 2 min

一、oracle

获取表的前100条数据.
(从1行开始取100行数据,第一行到第100行数据)

1
select * from t_stu_copy  where rownum<=100;

补充:先降序排序再获取第101条到第200条之间的所有记录

1
2
3
select * from t_stu_copy order by stuid desc where rownum between 100 and 200 ;---错误

select * from t_stu_copy where rownum between 100 and 200 order by stuid desc ;---错误
1
2
3
SELECT * FROM(SELECT ROWNUM AS rowno,t.* FROM t_stu_copy t WHERE ROWNUM <= 200 ORDER BY t.stuid ) a WHERE a.rowno > 100;---正确

select * from t_stu_copy where stuid between 101 and 200;;---正确

二、mysql

获取表的前100条数据.
(从1行开始取100行数据,第一行到第100行数据)

1
select * from t_stu_copy limit 0,100;

补充:先降序排序再获取第101条到第200条之间的所有记录
(从101行开始取100行数据,第101行到第200行数据)

1
2
3
select * from t_stu_copy order by stuid  limit 100,100;

select * from t_stu_copy where stuid between 101 and 200;

三、sqlserver

获取表的前100条数据.

1
select top 100 * from t_stu_copy ;

补充:先降序排序再获取第101条到第200条之间的所有记录
(三种方法,不过方法a与b得到的结果是将第101条到第200条倒过来显示罢了)
a.

1
select top 100 * from (select top 200 * from t_stu order by stuid) a order by stuid desc;

b.

1
2
3
select top m * into 临时表(或表变量) from tablename order by columnname  set rowcount n select * from 表变量 order by columnname desc.

select top 200 * into xxx from t_stu order by stuid set ROWCOUNT 100 select * from xxx order by stuid desc;

xxx表示临时表变量.

c.

1
select * from t_stu where stuid between 101 and 200.

MarkDown添加图片的三种方式

发表于 2021-09-02
字数统计: 465 字 | 阅读时长 ≈ 2 min

插图最基础的格式就是:

1
![Alt text](图片链接 "optional title")

Alt text:图片的Alt标签,用来描述图片的关键词,可以不写。最初的本意是当图片因为某种原因不能被显示时而出现的替代文字,后来又被用于SEO,可以方便搜索引擎根据Alt text里面的关键词搜索到图片。 图片链接:可以是图片的本地地址或者是网址。”optional title”:鼠标悬置于图片上会出现的标题文字,可以不写。

插入本地图片

只需要在基础语法的括号中填入图片的位置路径即可,支持绝对路径和相对路径。
例如:

1
![avatar](/home/picture/1.png)

不灵活不好分享,本地图片的路径更改或丢失都会造成markdown文件调不出图。

插入网络图片

只需要在基础语法的括号中填入图片的网络链接即可,现在已经有很多免费/收费图床和方便传图的小工具可选。
例如:

1
![avatar](http://baidu.com/pic/doge.png)

将图片存在网络服务器上,非常依赖网络。

把图片存入markdown文件

用base64转码工具把图片转成一段字符串,然后把字符串填到基础格式中链接的那个位置。
基础用法:

1
![avatar](data:image/png;base64,iVBORw0......)

这个时候会发现插入的这一长串字符串会把整个文章分割开,非常影响编写文章时的体验。如果能够把大段的base64字符串放在文章末尾,然后在文章中通过一个id来调用,文章就不会被分割的这么乱了。

高级用法
比如:

1
2
![avatar][base64str]
[base64str]:data:image/png;base64,iVBORw0......

base64编辑的时候文本太多会卡

QueryWrapper及LambdaQueryWrapper的使用

发表于 2021-09-01
字数统计: 300 字 | 阅读时长 ≈ 1 min

一、引用

idea新建一个spring boot 项目,然后在pom.xml文件中引入mybatis plus 的依赖:

1
2
3
4
5
6
<!--mybatis plus extension,包含了mybatis plus core-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>

二、使用

LambdaQueryWrapper 的使用

使用的关键的代码

1
2
3
4
QueryWrapper<PbListBlack> sectionQueryWrapper = new QueryWrapper<>();
sectionQueryWrapper.eq("OPTYPE", 1);
sectionQueryWrapper.eq("BLTYPE", 1);
List<PbListBlack> pbListBlacks = iPbListBlackMapper.selectList(sectionQueryWrapper);

上面这段代码的意思就是,首先新建一个sectionQueryWrapper对象,类型为PbListBlack对象,也就是你需要查询的实体数据,

1
2
sectionQueryWrapper.eq(“OPTYPE”, 1);
sectionQueryWrapper.eq(“BLTYPE”, 1);

这两句的意思是PbListBlack对象对应的数据库表中的OPTYPE,BLTYPE字段值要为1

QueryWrapper 的使用

使用的关键的代码与LambdaQueryWrapper基本一致,只是狗叫方法不同

1
2
3
QueryWrapper<PbListBlack> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("OPTYPE", 1);
List<PbListBlack> pbListBlacks = iPbListBlackMapper.selectList(queryWrapper);

上面这段代码的意思就是,首先新建一个QueryWrapper对象,类型为PbListBlack对象,也就是你需要查询的实体数据,

1
2
queryWrapper.eq("OPTYPE", 1);
queryWrapper.eq("BLTYPE", 1);

这两句的意思是PbListBlack对象对应的数据库表中的OPTYPE,BLTYPE字段值要为1

二 常用的方法

1
![QueryWrapper](../myresoursce/img/noteImg/QueryWrapper.png)

系统搭建中Idea出现点击run不运行情况解决办法

发表于 2021-08-30
字数统计: 63 字 | 阅读时长 ≈ 1 min

这是因为该项目涉及到了groovy这个插件,可能是IDEA版本和这个项目涉及到的groovy这个版本不同导致的!!!
解决办法:如图 打开IDEA —->file—->settings—->Plugins
然后搜索groovy,点击取消即可

Window中出现右键点击之后卡死情况解决办法

发表于 2021-08-29
字数统计: 40 字 | 阅读时长 ≈ 1 min

右键开始,
选择命令提示符,以管理员身份运行
在“命令提示符”窗口中,输入命令

1
SFC/Scannow

并按回车键。

Java实现QueryWrapper分页查询

发表于 2021-08-27
字数统计: 153 字 | 阅读时长 ≈ 1 min

准备

最近在用 mybatisplus,遇到分页的需求,需要引入mybatisplus的分页插件(官网上有)

实现

mybatisplus分页插件:

1
2
3
4
5
6
public class MyBatisConfiguration{
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}

执行代码:

1
2
3
4
5
6
7
8
public List<类名> getList(类名 condition,int start,int size){
//注释的这种写法,筛选是只要condition中栏位有值,sql的where条件中都会自带<等于>判断语句
//LambdaQueryWrapper<类名> queryWrapper = new QueryWrapper<类名>(condition).lambda()
LambdaQueryWrapper<类名> queryWrapper = new QueryWrapper<类名>().lambda();
//<类名>()这种不带的,筛选条件需全部自己写
...
return this.page(new Page<>(start,size),queryWrapper).getRecords();
}
1…212223…38

继开

一辈子很短,努力的做好两件事就好:第一件事是热爱生活,好好的去爱身边的人;第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱。

303 日志
171 标签
RSS
gitee E-Mail
0%
鲁ICP备18007712号
© 2025 继开 | 站点字数统计: 262.2k
博客使用 Hexo 搭建
|
主题 — NexT.Mist v5.1.4
人访问 次查看