一、前言 使用 Spring+Mybatis 操作 Phoenix 和操作其他的關係型資料庫(如 Mysql,Oracle)在配置上是基本相同的,下麵會分別給出 Spring/Spring Boot 整合步驟,完整代碼見本倉庫: + "Spring + Mybatis + Phoenix" + "S ...
一、前言
使用 Spring+Mybatis 操作 Phoenix 和操作其他的關係型資料庫(如 Mysql,Oracle)在配置上是基本相同的,下麵會分別給出 Spring/Spring Boot 整合步驟,完整代碼見本倉庫:
二、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 開源項目: 大數據入門指南