From 901c9d7ef5ad4845aa2684311193df7d1c6482d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BD=97=E7=A5=A5?= <1366971433@qq.com>
Date: Fri, 5 Apr 2019 09:42:43 +0800
Subject: [PATCH] =?UTF-8?q?Spring+Mybtais+Phoenix=E6=95=B4=E5=90=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 2 +-
notes/Spring+Mybtais+Phoenix整合.md | 385 +++++++++++++++++++++++
pictures/spring-boot-mybatis-phoenix.png | Bin 0 -> 12775 bytes
pictures/spring-mybatis-phoenix.png | Bin 0 -> 15053 bytes
4 files changed, 386 insertions(+), 1 deletion(-)
create mode 100644 notes/Spring+Mybtais+Phoenix整合.md
create mode 100644 pictures/spring-boot-mybatis-phoenix.png
create mode 100644 pictures/spring-mybatis-phoenix.png
diff --git a/README.md b/README.md
index 9b9e34b..9dcae7e 100644
--- a/README.md
+++ b/README.md
@@ -78,13 +78,13 @@
## 十、HBase
1. [HBase基本环境搭建(Standalone /pseudo-distributed mode)](https://github.com/heibaiying/BigData-Notes/blob/master/notes/installation/Hbase%E5%9F%BA%E6%9C%AC%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md)
-
2. [HBase系统架构及数据结构](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E5%8F%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.md)
3. [HBase常用Shell命令](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%20Shell.md)
4. HBase Java API
5. HBase 协处理器
6. HBase 备份与恢复
7. [HBase的SQL中间层——Phoenix](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%E7%9A%84SQL%E5%B1%82%E2%80%94%E2%80%94Phoenix.md)
+8. [Spring/Spring Boot 整合 Mybatis + Phoenix]()
## 十一、Kafka
## 十二、Zookeeper
## 十三、Scala
diff --git a/notes/Spring+Mybtais+Phoenix整合.md b/notes/Spring+Mybtais+Phoenix整合.md
new file mode 100644
index 0000000..aa27ba2
--- /dev/null
+++ b/notes/Spring+Mybtais+Phoenix整合.md
@@ -0,0 +1,385 @@
+# Spring/Spring Boot 整合 Mybatis + Phoenix
+
+
+## 一、前言
+
+使用Spring+Mybatis操作Phoenix和操作其他的关系型数据库(如Mysql,Oracle)在配置上是基本相同的,下面会分别给出Spring/Spring Boot 整合步骤,完整代码见本仓库:
+
++ [Spring + Mybatis + Phoenix](https://github.com/heibaiying/BigData-Notes/tree/master/code/Phoenix/spring-mybatis-phoenix)
++ [SpringBoot + Mybatis + Phoenix](https://github.com/heibaiying/BigData-Notes/tree/master/code/Phoenix/spring-boot-mybatis-phoenix)
+
+## 二、Spring + Mybatis + Phoenix
+
+### 2.1 项目结构
+
+
+
+### 2.2 主要依赖
+
+除了Spring相关依赖外,还需要导入`phoenix-core`和对应的Mybatis依赖包
+
+```xml
+
+
+ org.mybatis
+ mybatis-spring
+ 1.3.2
+
+
+ org.mybatis
+ mybatis
+ 3.4.6
+
+
+
+ org.apache.phoenix
+ phoenix-core
+ 4.14.0-cdh5.14.2
+
+```
+
+### 2.3 数据库配置文件
+
+在数据库配置文件 `jdbc.properties` 中配置数据库驱动和zookeeper地址
+
+```properties
+# 数据库驱动
+phoenix.driverClassName=org.apache.phoenix.jdbc.PhoenixDriver
+# zookeeper地址
+phoenix.url=jdbc:phoenix:192.168.0.105:2181
+```
+
+### 2.4 配置数据源和会话工厂
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 2.5 Mybtais参数配置
+
+新建mybtais配置文件,按照需求配置额外参数, 更多settings配置项可以参考[官方文档](http://www.mybatis.org/mybatis-3/zh/configuration.html)
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### 2.6 查询接口
+
+```java
+public interface PopulationDao {
+
+ List queryAll();
+
+ void save(USPopulation USPopulation);
+
+ USPopulation queryByStateAndCity(@Param("state") String state, @Param("city") String city);
+
+ void deleteByStateAndCity(@Param("state") String state, @Param("city") String city);
+}
+```
+
+```xml
+
+
+
+
+
+
+
+
+ UPSERT INTO us_population VALUES( #{state}, #{city}, #{population} )
+
+
+
+
+
+ DELETE FROM us_population WHERE state=#{state} AND city = #{city}
+
+
+
+```
+
+### 2.7 单元测试
+
+```java
+@RunWith(SpringRunner.class)
+@ContextConfiguration({"classpath:springApplication.xml"})
+public class PopulationDaoTest {
+
+ @Autowired
+ private PopulationDao populationDao;
+
+ @Test
+ public void queryAll() {
+ List USPopulationList = populationDao.queryAll();
+ if (USPopulationList != null) {
+ for (USPopulation USPopulation : USPopulationList) {
+ System.out.println(USPopulation.getCity() + " " + USPopulation.getPopulation());
+ }
+ }
+ }
+
+ @Test
+ public void save() {
+ populationDao.save(new USPopulation("TX", "Dallas", 66666));
+ USPopulation usPopulation = populationDao.queryByStateAndCity("TX", "Dallas");
+ System.out.println(usPopulation);
+ }
+
+ @Test
+ public void update() {
+ populationDao.save(new USPopulation("TX", "Dallas", 99999));
+ USPopulation usPopulation = populationDao.queryByStateAndCity("TX", "Dallas");
+ System.out.println(usPopulation);
+ }
+
+
+ @Test
+ public void delete() {
+ populationDao.deleteByStateAndCity("TX", "Dallas");
+ USPopulation usPopulation = populationDao.queryByStateAndCity("TX", "Dallas");
+ System.out.println(usPopulation);
+ }
+}
+```
+
+## 三、SpringBoot + Mybatis + Phoenix
+
+### 3.1 项目结构
+
+
+
+### 3.2 主要依赖
+
+```xml
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 1.3.2
+
+
+
+ org.apache.phoenix
+ phoenix-core
+ 4.14.0-cdh5.14.2
+
+
+```
+
+spring boot 与 mybatis 版本的对应关系:
+
+| MyBatis-Spring-Boot-Starter 版本 | MyBatis-Spring 版本 | Spring Boot 版本 |
+| -------------------------------- | ------------------- | ---------------- |
+| **1.3.x (1.3.1)** | 1.3 or higher | 1.5 or higher |
+| **1.2.x (1.2.1)** | 1.3 or higher | 1.4 or higher |
+| **1.1.x (1.1.1)** | 1.3 or higher | 1.3 or higher |
+| **1.0.x (1.0.2)** | 1.2 or higher | 1.3 or higher |
+
+### 3.3 配置数据源
+
+在application.yml 中配置数据源,spring boot 2.x 版本默认采用Hikari作为数据库连接池,Hikari是目前java平台性能最好的连接池,性能好于druid。
+
+```yaml
+spring:
+ datasource:
+ #zookeeper地址
+ url: jdbc:phoenix:192.168.0.105:2181
+ driver-class-name: org.apache.phoenix.jdbc.PhoenixDriver
+
+ # 如果不想配置对数据库连接池做特殊配置的话,以下关于连接池的配置就不是必须的
+ # spring-boot 2.X 默认采用高性能的 Hikari 作为连接池 更多配置可以参考 https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby
+ type: com.zaxxer.hikari.HikariDataSource
+ hikari:
+ # 池中维护的最小空闲连接数
+ minimum-idle: 10
+ # 池中最大连接数,包括闲置和使用中的连接
+ maximum-pool-size: 20
+ # 此属性控制从池返回的连接的默认自动提交行为。默认为true
+ auto-commit: true
+ # 允许最长空闲时间
+ idle-timeout: 30000
+ # 此属性表示连接池的用户定义名称,主要显示在日志记录和JMX管理控制台中,以标识池和池配置。 默认值:自动生成
+ pool-name: custom-hikari
+ #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
+ max-lifetime: 1800000
+ # 数据库连接超时时间,默认30秒,即30000
+ connection-timeout: 30000
+ # 连接测试sql 这个地方需要根据数据库方言差异而配置 例如 oracle 就应该写成 select 1 from dual
+ connection-test-query: SELECT 1
+
+# mybatis 相关配置
+mybatis:
+ configuration:
+ # 是否打印sql语句 调试的时候可以开启
+ log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+```
+
+### 3.4 新建查询接口
+
+上面Spring+Mybatis我们使用了XML的方式来写SQL,为了体现Mybatis支持多种方式,这里使用注解的方式来写SQL。
+
+```java
+@Mapper
+public interface PopulationDao {
+
+ @Select("SELECT * from us_population")
+ List queryAll();
+
+ @Insert("UPSERT INTO us_population VALUES( #{state}, #{city}, #{population} )")
+ void save(USPopulation USPopulation);
+
+ @Select("SELECT * FROM us_population WHERE state=#{state} AND city = #{city}")
+ USPopulation queryByStateAndCity(String state, String city);
+
+
+ @Delete("DELETE FROM us_population WHERE state=#{state} AND city = #{city}")
+ void deleteByStateAndCity(String state, String city);
+}
+```
+
+### 3.5 单元测试
+
+```java
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class PopulationTest {
+
+ @Autowired
+ private PopulationDao populationDao;
+
+ @Test
+ public void queryAll() {
+ List USPopulationList = populationDao.queryAll();
+ if (USPopulationList != null) {
+ for (USPopulation USPopulation : USPopulationList) {
+ System.out.println(USPopulation.getCity() + " " + USPopulation.getPopulation());
+ }
+ }
+ }
+
+ @Test
+ public void save() {
+ populationDao.save(new USPopulation("TX", "Dallas", 66666));
+ USPopulation usPopulation = populationDao.queryByStateAndCity("TX", "Dallas");
+ System.out.println(usPopulation);
+ }
+
+ @Test
+ public void update() {
+ populationDao.save(new USPopulation("TX", "Dallas", 99999));
+ USPopulation usPopulation = populationDao.queryByStateAndCity("TX", "Dallas");
+ System.out.println(usPopulation);
+ }
+
+
+ @Test
+ public void delete() {
+ populationDao.deleteByStateAndCity("TX", "Dallas");
+ USPopulation usPopulation = populationDao.queryByStateAndCity("TX", "Dallas");
+ System.out.println(usPopulation);
+ }
+
+}
+
+```
+
+
+
+## 附:建表语句
+
+上面单元测试涉及到的测试表的建表语句如下:
+
+```sql
+CREATE TABLE IF NOT EXISTS us_population (
+ state CHAR(2) NOT NULL,
+ city VARCHAR NOT NULL,
+ population BIGINT
+ CONSTRAINT my_pk PRIMARY KEY (state, city));
+
+-- 测试数据
+UPSERT INTO us_population VALUES('NY','New York',8143197);
+UPSERT INTO us_population VALUES('CA','Los Angeles',3844829);
+UPSERT INTO us_population VALUES('IL','Chicago',2842518);
+UPSERT INTO us_population VALUES('TX','Houston',2016582);
+UPSERT INTO us_population VALUES('PA','Philadelphia',1463281);
+UPSERT INTO us_population VALUES('AZ','Phoenix',1461575);
+UPSERT INTO us_population VALUES('TX','San Antonio',1256509);
+UPSERT INTO us_population VALUES('CA','San Diego',1255540);
+UPSERT INTO us_population VALUES('CA','San Jose',912332);
+```
+
diff --git a/pictures/spring-boot-mybatis-phoenix.png b/pictures/spring-boot-mybatis-phoenix.png
new file mode 100644
index 0000000000000000000000000000000000000000..174451bb9d48a7da44413a91dcfa3138d6b054b4
GIT binary patch
literal 12775
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
S`w@TA0K8Oq4X%_k3;jPSe{ebg
literal 0
HcmV?d00001
diff --git a/pictures/spring-mybatis-phoenix.png b/pictures/spring-mybatis-phoenix.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e19d01aa35343eea210ce728a13ec77230c21a7
GIT binary patch
literal 15053
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