apache ignite系列(九):使用ddl和dml脚本初始化ignite并使用mybatis查询缓存
博客又断了一段时间,本篇将记录一下基于ignite对jdbc支持的特性在实际使用过程中的使用。
使用ddl和dml脚本初始化ignite
由于spring-boot中支持通过spring.datasource.schema属性指定初始化DDL脚本,spring.datasource.data指定初始化DML脚本。而ignite支持jdbc协议,测试了一下,发现一样可以通过该配置初始化ignite。
spring.datasource.url=jdbc:ignite:thin://127.0.0.1/
spring.datasource.driver-class-name=org.apache.ignite.IgniteJdbcThinDriver
spring.datasource.schema=classpath:db/schema.sql
spring.datasource.data=classpath:db/data.sql
说明ignite数据源同样可以作为一个DataSource实例。
DDL的规范
创建表
CREATE TABLE [IF NOT EXISTS] tableName (tableColumn [, tableColumn]...
[, PRIMARY KEY (columnName [,columnName]...)])
[WITH "paramName=paramValue [,paramName=paramValue]..."]
WITH语法中支持的选项以及含义如下(可参见xml配置中CacheConfiguration的相关配置):
| 参数 | 含义 |
|---|---|
| TEMPLATE | 缓存模式:PARTITIONED或者REPLICATED |
| BACKUPS | 备份数量 |
| ATOMICITY | 原子模式:ATOMIC或者TRANSACTIONAL |
| CACHEGROUP | 缓存组名 |
| AFFINITYKEY | 并置键列名 |
| CACHE_NAME | 缓存名(如果不设置的话默认会加SQL_前缀) |
| KEY_TYPE | 键类型 |
| VALUE_TYPE | 值类型 |
| DATA_REGION | 内存区名 |
创建索引
CREATE [SPATIAL] INDEX [[IF NOT EXISTS] indexName] ON tableName
(columnName [ASC|DESC] [,...]) [(index_option [...])]
示例:
schema.sql
--student学生信息表
CREATE TABLE IF NOT EXISTS PUBLIC.STUDENT (
STUDID INTEGER,
NAME VARCHAR,
EMAIL VARCHAR,
dob Date,
PRIMARY KEY (STUDID))
WITH "template=replicated,atomicity=ATOMIC,cache_name=student";
CREATE INDEX IF NOT EXISTS STUDENT_NE_INDEX ON PUBLIC.STUDENT (NAME, EMAIL);
-- grade成绩表
CREATE TABLE IF NOT EXISTS PUBLIC.GRADE (
STUDID INTEGER,
grade DOUBLE,
PRIMARY KEY (STUDID))
WITH "template=replicated,atomicity=ATOMIC,cache_name=grade";
DML规范
ignite中dml与标准sql中的基本一致示例如下:
INSERT INTO student (studid, name, email, dob) VALUES (1, 'student_1', 'student_1gmail.com', '2017-09-28');
完整dml初始化脚本:
-- student
INSERT INTO student (studid, name, email, dob) VALUES (1, 'student_1', 'student_1gmail.com', '2017-09-28');
INSERT INTO student (studid, name, email, dob) VALUES (2, 'student_2', 'student_2gmail.com', '2017-09-28');
...
--grade
INSERT INTO grade (studid, grade) VALUES (1, 3);
INSERT INTO grade (studid, grade) VALUES (2, 64);
...
注:如果使用了KEY_TYPE选项配置自定义KEY类型,那么要么在自定义类型中得有对应的构造方法,要么使用java内置类型的时候,insert语句必须带上_key字段的值。
例如:
ddl语句中with选项为
WITH "template=replicated,atomicity=ATOMIC,cache_name=student,key_type=java.lang.Long";
那么dml语句就得像下面这么写
INSERT INTO student (_key, studid, name, email, dob) VALUES (1, '1', 'student_1', 'student_1gmail.com', '2017-09-28');
初始化完成后可通过监控程序看到如下监控情况 :


可以发现缓存和数据均已初始化成功。
使用Mybatis查询ignite缓存
由于ignite可以作为DataSource的实例,所以猜想应该也可以通过Mybatis去查询ignite,这样可以替代原来需要SqlFieldsQuery查询并对结果进行逐行解析的方式。经验证后发现ignite能完美支持myabtis,所以在查询ignite的方式上有了一个更便捷的方式。
与普通使用mybatis的方式一样,定义IgniteMapper.xml和IgniteMapper.java
IgniteMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.cord.ignite.data.mapper.IgniteMapper">
<resultMap type="org.cord.ignite.data.domain.Student" id="StudentResult">
<result property="studId" column="studid"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<result property="dob" column="dob"/>
</resultMap>
<select id="findStudentsById" parameterType="java.lang.String" resultMap="StudentResult">
SELECT * FROM student WHERE studid = #{studentId}
</select>
<select id="findGradeByName" parameterType="java.lang.String" resultType="java.lang.Double">
SELECT g.grade FROM student s,grade g WHERE s.STUDID=g.STUDID and s.name= #{name}
</select>
</mapper>
IgniteMapper.java
public interface IgniteMapper {
/**
* 根据studentId查询学生信息
* @param studentId
* @return Student
*/
Student findStudentsById(String studentId);
/**
* 根据学生姓名查询学生分数
* @param name
* @return 学生分数
*/
Double findGradeByName(String name);
}
查询:
...
@Autowired
private IgniteMapper igniteMapper;
...
Student student = igniteMapper.findStudentsById(studentId);
...
double grade = igniteMapper.findGradeByName(name);
注:由于ignite中可以自定义sql函数,测试过,在mybatis中ignite的自定义sql函数同样支持。
性能
由于ignite中jdbc的方式属于轻客户端,所以性能要比api的方式差,而在通过mybatis查询的方式其性能表现通过测试得出的结果如下:
在相同的sql相同数据的情况下,100并发查询:
mybatis查询
/findStudentsById 耗时 [13]ms.
/findStudentsById 耗时 [9]ms.
/findStudentsById 耗时 [3]ms.
/findStudentsById 耗时 [10]ms.
/findStudentsById 耗时 [11]ms.
/findStudentsById 耗时 [11]ms.
/findStudentsById 耗时 [13]ms.
/findStudentsById 耗时 [8]ms.
/findStudentsById 耗时 [8]ms.
/findStudentsById 耗时 [14]ms.
/findStudentsById 耗时 [17]ms.
/findStudentsById 耗时 [11]ms.
/findStudentsById 耗时 [8]ms.
/findStudentsById 耗时 [13]ms.
/findStudentsById 耗时 [11]ms.
/findStudentsById 耗时 [10]ms.
/findStudentsById 耗时 [9]ms.
/findStudentsById 耗时 [10]ms.
/findStudentsById 耗时 [12]ms.
/findStudentsById 耗时 [9]ms.
/findStudentsById 耗时 [3]ms.
/findStudentsById 耗时 [3]ms.
...
/findStudentsById 耗时 [1]ms.
/findStudentsById 耗时 [2]ms.
/findStudentsById 耗时 [2]ms.
/findStudentsById 耗时 [2]ms.
/findStudentsById 耗时 [2]ms.
/findStudentsById 耗时 [2]ms.
/findStudentsById 耗时 [2]ms.
/findStudentsById 耗时 [2]ms.
/findStudentsById 耗时 [1]ms.
/findStudentsById 耗时 [1]ms.
/findStudentsById 耗时 [1]ms.
/findStudentsById 耗时 [0]ms.
吞吐量为537/sec, 性能有波动情况,稳定后在2ms左右。
api查询
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [1]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [1]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
/cpFindStudentsById 耗时 [0]ms.
吞吐量为1256/sec,性能比较稳定,稳定后在1ms以内。
完整代码请参考:https://github.com/cording/ignite-example
结论
对于不是要求极限性能的场景,mybatis查询方式完全能满足,这使得对于很多现有基于myabtis的项目代码,能相对平滑的使用ignite作为加速层,而又不用做过多改动。
还有,写博客确实有点费时间....................
apache ignite系列(九):使用ddl和dml脚本初始化ignite并使用mybatis查询缓存的更多相关文章
- mysql系列九、mysql语句执行过程及运行原理(分组查询和关联查询原理)
一.背景介绍 了解一个sql语句的执行过程,了解一部分都做了什么,更有利于对sql进行优化,因为你知道它的每一个连接.where.分组.子查询是怎么运行的,都干了什么,才会知道怎么写是不合理的. 大致 ...
- apache ignite系列(八):问题汇总
1,java.lang.ClassNotFoundException Unknown pair 1.Please try to turn on isStoreKeepBinary in cache s ...
- apache ignite系列(四):持久化
ignite持久化与固化内存 1.持久化的机制 ignite持久化的关键点如下: ignite持久化可防止内存溢出导致数据丢失的情况: 持久化可以定制化配置,按需持久化; 持久化能解决在大量缓存数据情 ...
- apache ignite系列(三):数据处理(数据加载,数据并置,数据查询)
使用ignite的一个常见思路就是将现有的关系型数据库中的数据导入到ignite中,然后直接使用ignite中的数据,相当于将ignite作为一个缓存服务,当然ignite的功能远不止于此,下面以 ...
- apache ignite系列(二):配置
ignite有两种配置方式,一种是基于XML文件的配置,一种是基于JAVA代码的配置: 这里将ignite常用的配置集中罗列出来了,一般建议使用xml配置. 1,基于XML的配置 <beans ...
- apache ignite系列(一): 简介
apache-ignite简介(一) 1,简介 ignite是分布式内存网格的一种实现,其基于java平台,具有可持久化,分布式事务,分布式计算等特点,此外还支持丰富的键值存储以及SQL语法(基于 ...
- apache ignite系列(五):分布式计算
ignite分布式计算 在ignite中,有传统的MapReduce模型的分布式计算,也有基于分布式存储的并置计算,当数据分散到不同的节点上时,根据提供的并置键,计算会传播到数据所在的节点进行计算,再 ...
- 23-hadoop-hive的DDL和DML操作
跟mysql类似, hive也有 DDL, 和 DML操作 数据类型: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ ...
- 分布式系列九: kafka
分布式系列九: kafka概念 官网上的介绍是kafka是apache的一种分布式流处理平台. 最初由Linkedin开发, 使用Scala编写. 具有高性能,高吞吐量的特定. 包含三个关键能力: 发 ...
随机推荐
- 大白话5分钟带你走进人工智能-第32节集成学习之最通俗理解XGBoost原理和过程
目录 1.回顾: 1.1 有监督学习中的相关概念 1.2 回归树概念 1.3 树的优点 2.怎么训练模型: 2.1 案例引入 2.2 XGBoost目标函数求解 3.XGBoost中正则项的显式表达 ...
- 使用rpm安装指定版本的docker(1.12.6)
一.原因 如果系统是Centos7.3,直接使用yum install docker安装的docker版本是1.13.1,导致在创建容器的会报错,错误如下: 所以为了防止安装高版本的docker引发的 ...
- 从原理层面掌握@ModelAttribute的使用(核心原理篇)【一起学Spring MVC】
每篇一句 我们应该做一个:胸中有蓝图,脚底有计划的人 前言 Spring MVC提供的基于注释的编程模型,极大的简化了web应用的开发,我们都是受益者.比如我们在@RestController标注的C ...
- 弃用 wget, 拥抱多线程下载 axel
0x00 事件 对于在 Linux 的下载工具而言,比较常用的就是 wget 或者 curl,吾也一直用 wget 的方式进行网络上的资源下载.偶然发现了 axel 这个支持多线程的下载工具,试用了几 ...
- 【java提高】(18)---静态内部类和非静态内部类
java提高](18)-静态内部类和非静态内部类 定义 放在一个类的内部的类我们就叫内部类. 自己从开发到现在其实用到内部类主要在两个地方会考虑用内部类: 1.使用静态内部类的单例模式 2.将Json ...
- 清缓存的姿势不对,真的会出生产bug哦
最近解决了一个生产bug,bug的原因很简单,就是清理缓存的方式不对.本来没啥好说的,但是考虑到我们有时候确实会在一些小问题上栽跟头,最终决定把这个小故事拿出来跟大家分享下. 风起有一天在撸代码,突然 ...
- SpringBoot电商项目实战 — Redis实现分布式锁
最近有小伙伴发消息说,在Springboot系列文第二篇,zookeeper是不是漏掉了?关于这个问题,其实我在写第二篇的时候已经考虑过,但基于本次系列文章是实战练习,在项目里你能看到Zookeepe ...
- C语言的输入
%*2d%d 去掉前面两位 新旧函数 scanf和scanf_s 去掉安全检查 整型 scanf(“%d”,&x); scanf_s(“%d”,&x); 字符型 char ch; sc ...
- 用java自制简易线程池(不依赖concurrent包)
很久之前人们为了继续享用并行化带来的好处而不想使用进程,于是创造出了比进程更轻量级的线程.以linux为例,创建一个进程需要申请新的自己的内存空间,从父进程拷贝一些数据,所以开销是比较大的,线程(或称 ...
- Flutter学习笔记(23)--多个子元素的布局Widget(Rwo、Column、Stack、IndexedStack、Table、Wrap)
如需转载,请注明出处:Flutter学习笔记(23)--多个子元素的布局Widget(Rwo.Column.Stack.IndexedStack.Table.Wrap) 上一篇梳理了拥有单个子元素布局 ...