概述
在企业级应用开发中,高性能数据库与灵活的后端框架组合是构建稳定、高效系统的关键。SAP HANA Cloud 作为一款基于内存计算的现代化数据库,支持实时事务处理(OLTP)与在线分析处理(OLAP),广泛应用于 SAP BTP(Business Technology Platform)生态系统中。
与此同时,Spring Boot 以其“约定优于配置”的理念,极大提升了微服务开发效率;而 MyBatis-Plus 在处理复杂 SQL 查询和高度定制化数据操作方面表现优异,是许多企业项目的首选 ORM 框架。
本文将带你从零开始,使用 Spring Boot + MyBatis-Plus 完整搭建一个连接并操作 SAP HANA Cloud 数据库的后端项目,涵盖环境准备、项目创建、依赖配置、代码实现到接口测试的全流程,适用于企业集成、数据服务开发等实际场景。
1:开发环境与账号配置
所需工具与环境:
- JDK 11 或以上
- Maven 3.6+
- IntelliJ IDEA
- SAP HANA Cloud 实例(已创建并运行)参考:如何启用SAP BTP HANA Cloud数据库服务
- Postman 或其他 API 测试工具(用于接口调用验证)
⚠️ 提示:确保你已获取 SAP HANA Cloud 的连接信息,包括主机地址、端口、用户名、密码以及 TLS/SSL 配置参数。
2:创建 Spring Boot 项目
使用 Spring Initializr 创建项目:
- Project: Maven
- Language: Java
- Spring Boot Version: 3.5.5
- Group: cn.nevox
- Artifact: hana-demo
- Dependencies:
- Spring Web
- Spring Configuration Processor
- Lombok
点击 Generate 下载项目压缩包,解压后导入到你的 IDE(如 IntelliJ IDEA)中。
3:添加核心依赖
打开 pom.xml
文件,添加以下关键依赖以支持 MyBatis 和 SAP HANA 驱动。
<?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>3.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.nevox</groupId>
<artifactId>hana-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hana-demo</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.12</version>
</dependency>
<!-- SAP HANA JDBC Driver -->
<dependency>
<groupId>com.sap.cloud.db.jdbc</groupId>
<artifactId>ngdbc</artifactId>
<version>2.24.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
4:配置 SAP HANA Cloud 数据库连接
在 src/main/resources/application.yml
中添加如下配置:
server:
port: 8080
spring:
datasource:
hikari:
jdbc-url: jdbc:sap://****************.hana.trial-us10.hanacloud.ondemand.com:443/?currentschema=DBADMIN
driver-class-name: com.sap.db.jdbc.Driver
username: DBADMIN
password: ******
maximum-pool-size: 10
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
logging:
level:
com.zaxxer.hikari: DEBUG
org.springframework.jdbc: DEBUG
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
type-aliases-package: cn.nevox.hana_demo.entity
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
5:创建实体类(Entity)
假设我们有一个员工表 EMPLOYEE
,包含字段:EMP_ID
, FIRST_NAME
, LAST_NAME
, EMAIL
, DEPARTMENT
, HIRE_DATE
。
6:编写 Mapper 接口与 XML 映射文件
7:编写 Service 层逻辑
接口定义
实现类
8:编写 Controller 提供 REST API
提供分页查询接口 /api/employee/list
,支持按姓名、部门、入职日期过滤。
package cn.nevox.hana_demo.controller;
import cn.nevox.hana_demo.entity.Employee;
import cn.nevox.hana_demo.service.IEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDate;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@RestController
@RequestMapping("/api/employee")
public class EmployeeController {
@Autowired
private IEmployeeService employeeService;
@GetMapping("/list")
public java.util.Map<String, Object> getList(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "department", required = false) String department,
@RequestParam(value = "joinDate", required = false) String joinDate,
@RequestParam(value = "page", required = false, defaultValue = "1") long page,
@RequestParam(value = "size", required = false, defaultValue = "10") long size) {
// 构造条件(用于count)
LambdaQueryWrapper<Employee> countWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(name)) {
countWrapper.and(q -> q.like(Employee::getFirstName, name)
.or().like(Employee::getLastName, name));
}
if (StringUtils.isNotBlank(department)) {
countWrapper.eq(Employee::getDepartment, department);
}
if (StringUtils.isNotBlank(joinDate)) {
try {
LocalDate date = LocalDate.parse(joinDate);
countWrapper.eq(Employee::getHireDate, date);
} catch (Exception ignored) {
}
}
long total = employeeService.count(countWrapper);
// 再构造一次条件用于分页查询
LambdaQueryWrapper<Employee> listWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(name)) {
listWrapper.and(q -> q.like(Employee::getFirstName, name)
.or().like(Employee::getLastName, name));
}
if (StringUtils.isNotBlank(department)) {
listWrapper.eq(Employee::getDepartment, department);
}
if (StringUtils.isNotBlank(joinDate)) {
try {
LocalDate date = LocalDate.parse(joinDate);
listWrapper.eq(Employee::getHireDate, date);
} catch (Exception ignored) {
}
}
listWrapper.orderByAsc(Employee::getEmpId);
long offset = Math.max(0, (page - 1)) * size;
// HANA 支持 LIMIT ... OFFSET ...
listWrapper.last("limit " + size + " offset " + offset);
java.util.List<Employee> records = employeeService.list(listWrapper);
java.util.Map<String, Object> result = new java.util.HashMap<>();
result.put("total", total);
result.put("current", page);
result.put("size", size);
result.put("records", records);
return result;
}
}
9:配置数据源——添加 DataSourceConfig
package cn.nevox.hana_demo.config;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
private static final Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
// 确保至少设置这些基本属性
config.setDriverClassName("com.sap.db.jdbc.Driver");
return config;
}
@Bean
@Primary
public DataSource dataSource() {
try {
HikariConfig config = hikariConfig();
// 确保URL、用户名和密码已设置
if (config.getJdbcUrl() == null || config.getJdbcUrl().isEmpty()) {
throw new IllegalStateException("JDBC URL must be configured for HikariCP");
}
if (config.getUsername() == null || config.getUsername().isEmpty()) {
throw new IllegalStateException("Username must be configured for HikariCP");
}
if (config.getPassword() == null) {
throw new IllegalStateException("Password must be configured for HikariCP");
}
// HANA特定的配置
config.setConnectionTestQuery("SELECT 1 FROM DUMMY");
config.setPoolName("HANA-HikariCP");
logger.info("Configuring HANA DataSource with URL: {}", config.getJdbcUrl());
logger.info("HikariCP pool configuration - MaxPoolSize: {}, MinIdle: {}",
config.getMaximumPoolSize(), config.getMinimumIdle());
HikariDataSource dataSource = new HikariDataSource(config);
// 测试连接
try (java.sql.Connection connection = dataSource.getConnection()) {
logger.info("HANA connection test successful");
}
return dataSource;
} catch (Exception e) {
logger.error("Failed to initialize HANA DataSource", e);
throw new IllegalStateException("Could not initialize HANA DataSource", e);
}
}
}
10:启动项目并测试
运行主类 HanaDemoApplication
,观察控制台日志是否正常启动:
若无异常,说明应用已成功启动并与 HANA Cloud 建立连接。
11:使用 Postman 测试接口
打开 Postman,发送 GET 请求:
说明后端已成功连接 SAP HANA Cloud 并查询出数据。
总结
本文详细演示了如何使用 Spring Boot + MyBatis-Plus 构建一个连接 SAP HANA Cloud 的企业级后端服务。
通过该方案,开发者可以在企业项目中高效集成 SAP HANA Cloud,充分发挥其内存计算、实时分析、高并发处理等优势,同时借助 Spring 生态实现快速开发、灵活扩展与良好维护性。