SpringBoot+MyBatis+Phoenix整合实践

1.项目工程结构

2.pom依赖配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.patozon</groupId>
    <artifactId>data-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>data-service</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring.mybatis.version>2.1.3</spring.mybatis.version>
        <mybatis.generator.version>1.3.7</mybatis.generator.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${spring.mybatis.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>5.0.0-HBase-2.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.8.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>${mybatis.generator.version}</version>
                <configuration>
                    <!--mybatis的代码生成器的配置文件-->
                    <configurationFile>src/main/resources/mybatis-generator-config.xml</configurationFile>
                    <!--允许覆盖生成的文件-->
                    <!--值得注意的是,MyBatis Generator 只会覆盖旧的 po、dao、而 *mapper.xml 不会覆盖,而是追加,这样做的目的是防止用户自己写的 sql 语句一不小心都被 MyBatis Generator 给覆盖了-->
                    <overwrite>true</overwrite>
                    <!--将当前pom的依赖项添加到生成器的类路径中-->
                    <includeCompileDependencies>true</includeCompileDependencies>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3.数据源配置(多数据源)

application.yml配置文件

server:
  port: 8090

spring:
  application:
    name: data-service
#  profiles:
#    active: dev #默认为开发环境
  datasource:
    mysql:
      name: mysql
      driver-class-name: com.mysql.cj.jdbc.Driver
      # Springboot2.0 在配置数据库连接的时候需要使用jdbc-url,如果只使用url的话会报
      jdbc-url: jdbc:mysql://192.168.5.231:3306/db_single_product
      username: hive
      password: hive@123
    phoenix:
      name: phoenix
      driver-class-name: org.apache.phoenix.jdbc.PhoenixDriver
      #zookeeper地址
      jdbc-url: jdbc:phoenix:ptxtest-bd1,ptxtest-bd2,ptxtest-bd3:2181
      # username: hive
      # password: hive@123
      # spring-boot 2.X 默认采用高性能的 Hikari 作为连接池
      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:
  mapper-locations: classpath:mapper/*/*.xml
  type-aliases-package: com.patozon.dataservice.vo.basedata
  configuration:
    # 是否打印sql语句 调试的时候可以开启
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

MySQL数据源配置

package com.patozon.dataservice.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

/**
 * @Author: mars_cai
 * @Date: 2020/11/12 15:37
 */
@Configuration
@MapperScan(basePackages = "com.patozon.dataservice.dao.mysql", sqlSessionFactoryRef = "mysqlSqlSessionFactory")
public class MySQLDataSourceConfig {

    @Bean(name = "mysqlDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    public DataSource getMySQLDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean("mysqlSqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("mysqlDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        // 设置mybatis的xml所在位置
        bean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/mysql/*.xml"));
        return bean.getObject();
    }

    @Bean("mysqlSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("mysqlSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

Phoenix数据源配置

package com.patozon.dataservice.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

/**
 * @Author: mars_cai
 * @Date: 2020/11/12 15:37
 */
@Configuration
@MapperScan(basePackages = "com.patozon.dataservice.dao.phoenix", sqlSessionFactoryRef = "phoenixSqlSessionFactory")
public class PhoenixDataSourceConfig {

    @Bean(name = "phoenixDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.phoenix")
    public DataSource getPhoenixDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean("phoenixSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("phoenixDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        // 设置mybatis的xml所在位置
        bean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/phoenix/*.xml"));
        return bean.getObject();
    }

    @Bean("phoenixSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("phoenixSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

4.测试用例

4.1 建样例表

CREATE SCHEMA TEST;
CREATE TABLE IF NOT EXISTS TEST."MEMBER"(

"m_id" VARCHAR PRIMARY KEY ,

"address"."contry" VARCHAR ,

"address"."province" VARCHAR ,

"address"."city" VARCHAR ,

"info"."age" VARCHAR ,

"info"."birthday" VARCHAR ,

"info"."company" VARCHAR

) column_encoded_bytes = 0;

 4.2 实体对象

package com.patozon.dataservice.vo;

/**
 * @Author: mars_cai
 * @Date: 2020/11/12 16:12
 */
public class MemberVO {

    private String mId;
    private String contry;
    private String province;
    private String city;
    private String age;
    private String birthday;
    private String company;

    public MemberVO(String mId, String contry, String province, String city, String age, String birthday, String company) {
        this.mId = mId;
        this.contry = contry;
        this.province = province;
        this.city = city;
        this.age = age;
        this.birthday = birthday;
        this.company = company;
    }

    public String getmId() {
        return mId;
    }

    public void setmId(String mId) {
        this.mId = mId;
    }

    public String getContry() {
        return contry;
    }

    public void setContry(String contry) {
        this.contry = contry;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }
}

4.3 数据访问对象dao

扫描二维码关注公众号,回复: 15968249 查看本文章
package com.patozon.dataservice.dao.phoenix;

import com.patozon.dataservice.vo.MemberVO;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @Author: mars_cai
 * @Date: 2020/11/12 16:11
 */
@Mapper
public interface MemberDao {

    /**
     * 查询所有member
     *
     * @return List<MemberVO>
     */
    @Select("SELECT * FROM TEST.MEMBER")
    List<MemberVO> queryAll();

    /**
     * 插入member数据
     *
     * @param memberVO
     */
    @Insert("UPSERT INTO TEST.MEMBER VALUES(#{mId},#{contry},#{province},#{city},#{age},#{birthday},#{company})")
    void save(MemberVO memberVO);

}

4.4 测试用例

package com.patozon.dataservice;

import com.patozon.dataservice.dao.phoenix.MemberDao;
import com.patozon.dataservice.vo.MemberVO;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
class DataServiceApplicationTests {

    @Autowired
    private MemberDao memberDao;

    @Test
    void contextLoads() {
    }

    @Test
    public void queryAll() {
        List<MemberVO> memberVOS = memberDao.queryAll();

        if (memberVOS != null) {
            for (MemberVO memberVO : memberVOS) {
                System.out.println(memberVO.getmId());
            }

        }
    }

    @Test
    public void save(){
        MemberVO memberVO = new MemberVO("1", "中国", "广东省", "深圳市", "30", "10月1日", "深圳市xxx有限公司");
        memberDao.save(memberVO);
    }

}

4.5 测试结果

DBeaver连接Phoenix查看结果

5.问题

5.1 guava版本兼容问题

选择版本对应的版本

        <dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>5.0.0-HBase-2.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.8.4</version>
        </dependency>

5.2 phoenix.schema.isNamespaceMappingEnabled enable

在CM平台HBase已经配置了,但是没有生效

Cannot initiate connection as SYSTEM:CATALOG is found but client does not have phoenix.schema.isNamespaceMappingEnabled enabled,Cannot initiate connection as SYSTEM:CATALOG is found but client does not have phoenix.schema.isNamespaceMappingEnabled enable

下载Hbase客户端hbase-site.xml配置文件到本地,复制到本地phoenix-core-5.0.0-HBase-2.0.jar中

猜你喜欢

转载自blog.csdn.net/weixin_38023225/article/details/109673236