HBase 系列(十一)—— Spring/Spring Boot + Mybatis + Phoenix 整合
阿新 • • 發佈:2019-08-27
一、前言
使用 Spring+Mybatis 操作 Phoenix 和操作其他的關係型資料庫(如 Mysql,Oracle)在配置上是基本相同的,下面會分別給出 Spring/Spring Boot 整合步驟,完整程式碼見本倉庫:
- Spring + Mybatis + Phoenix
- SpringBoot + Mybatis + Phoenix
二、Spring + Mybatis + Phoenix
2.1 專案結構
2.2 主要依賴
除了 Spring 相關依賴外,還需要匯入 phoenix-core
和對應的 Mybatis 依賴包
<!--mybatis 依賴包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!--phoenix core--> <dependency> <groupId>org.apache.phoenix</groupId> <artifactId>phoenix-core</artifactId> <version>4.14.0-cdh5.14.2</version> </dependency>
2.3 資料庫配置檔案
在資料庫配置檔案 jdbc.properties
中配置資料庫驅動和 zookeeper 地址
# 資料庫驅動
phoenix.driverClassName=org.apache.phoenix.jdbc.PhoenixDriver
# zookeeper地址
phoenix.url=jdbc:phoenix:192.168.0.105:2181
2.4 配置資料來源和會話工廠
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 開啟註解包掃描--> <context:component-scan base-package="com.heibaiying.*"/> <!--指定配置檔案的位置--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--配置資料來源--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!--Phoenix 配置--> <property name="driverClassName" value="${phoenix.driverClassName}"/> <property name="url" value="${phoenix.url}"/> </bean> <!--配置 mybatis 會話工廠 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--指定 mapper 檔案所在的位置--> <property name="mapperLocations" value="classpath*:/mappers/**/*.xml"/> <property name="configLocation" value="classpath:mybatisConfig.xml"/> </bean> <!--掃描註冊介面 --> <!--作用:從介面的基礎包開始遞迴搜尋,並將它們註冊為 MapperFactoryBean(只有至少一種方法的接口才會被註冊;, 具體類將被忽略)--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--指定會話工廠 --> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!-- 指定 mybatis 介面所在的包 --> <property name="basePackage" value="com.heibaiying.dao"/> </bean> </beans>
2.5 Mybtais引數配置
新建 mybtais 配置檔案,按照需求配置額外引數, 更多 settings 配置項可以參考官方文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- mybatis 配置檔案 --> <configuration> <settings> <!-- 開啟駝峰命名 --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 列印查詢 sql --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> </configuration>
2.6 查詢介面
public interface PopulationDao {
List<USPopulation> 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);
}
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.heibaiying.dao.PopulationDao">
<select id="queryAll" resultType="com.heibaiying.bean.USPopulation">
SELECT * FROM us_population
</select>
<insert id="save">
UPSERT INTO us_population VALUES( #{state}, #{city}, #{population} )
</insert>
<select id="queryByStateAndCity" resultType="com.heibaiying.bean.USPopulation">
SELECT * FROM us_population WHERE state=#{state} AND city = #{city}
</select>
<delete id="deleteByStateAndCity">
DELETE FROM us_population WHERE state=#{state} AND city = #{city}
</delete>
</mapper>
2.7 單元測試
@RunWith(SpringRunner.class)
@ContextConfiguration({"classpath:springApplication.xml"})
public class PopulationDaoTest {
@Autowired
private PopulationDao populationDao;
@Test
public void queryAll() {
List<USPopulation> 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 主要依賴
<!--spring 1.5 x 以上版本對應 mybatis 1.3.x (1.3.1)
關於更多 spring-boot 與 mybatis 的版本對應可以參見 <a href="http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/">-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--phoenix core-->
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.14.0-cdh5.14.2</version>
</dependency>
<dependency>
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。
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。
@Mapper
public interface PopulationDao {
@Select("SELECT * from us_population")
List<USPopulation> 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 單元測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class PopulationTest {
@Autowired
private PopulationDao populationDao;
@Test
public void queryAll() {
List<USPopulation> 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);
}
}
附:建表語句
上面單元測試涉及到的測試表的建表語句如下:
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);
更多大資料系列文章可以參見 GitHub 開源專案: 大資料入門指南