Java连接电科金仓数据库(KingbaseES)实战指南

**摘要:**本文分享了KingbaseES V8.6数据库与SpringBoot 2.7.x框架的集成实战经验。内容包括:1. 环境准备(Ubuntu系统安装配置、驱动获取方式);2. JDBC基础操作(连接、查询、事务处理);3. SpringBoot项目完整配置(pom依赖、数据源配置);4. MyBatis-Plus集成(实体类、Mapper、Service层实现);5. RESTful接口开发示例。文章提供了详细的代码示例,涵盖从数据库安装到应用开发的完整流程,帮助开发者快速实现国产数据库适配。

目录

前言

一、环境准备与驱动获取

[1.1 数据库安装与配置](#1.1 数据库安装与配置)

[1.2 JDBC驱动获取与配置](#1.2 JDBC驱动获取与配置)

[1.3 创建测试数据库](#1.3 创建测试数据库)

二、基础JDBC连接与操作

[2.1 最基础的JDBC连接示例](#2.1 最基础的JDBC连接示例)

[2.2 查询测试](#2.2 查询测试)

[2.3 新增测试](#2.3 新增测试)

[2.4 删除测试](#2.4 删除测试)

[2.5 大数据分配处理](#2.5 大数据分配处理)

[三、Spring Boot集成方案](#三、Spring Boot集成方案)

[3.1 完整项目配置](#3.1 完整项目配置)

[3.2 application.yml配置](#3.2 application.yml配置)

[3.3 实体类与Mapper](#3.3 实体类与Mapper)

[3.4 服务层与控制层](#3.4 服务层与控制层)

四、总结


前言

最近公司项目需要适配国产数据库,经过调研选择了电科金仓的KingbaseES。前前后后折腾了两周,踩了无数坑,从驱动配置到性能调优,每个环节都有故事。本文基于KingbaseES V8.6版本,JDK 1.8环境,Spring Boot 2.7.x框架,分享完整的实战经验。希望能帮助兄弟们少走弯路。

一、环境准备与驱动获取

1.1 数据库安装与配置

首先需要在服务器上安装KingbaseES数据库。这里以Ubuntu环境为例:

bash 复制代码
# 创建用户
useradd kingbase
passwd kingbase

# 创建安装目录
mkdir -p /opt/kingbase/ES/V8
chown -R kingbase:kingbase /opt/kingbase

# 解压安装包(假设安装包已经下载到/opt/software)
cd /opt/software
tar -xvf KingbaseES_V008R006C007B0024_Lin64_single_install.tar.gz

# 开始安装
./setup.sh -i console

安装过程中需要注意:

  • 选择"完全安装",包含所有组件

  • 数据目录建议放在独立磁盘,如/kingbase/data

  • 端口默认54321,如果冲突需要修改

  • 字符集选择UTF8,避免中文乱码

我往期作品有2篇文章分别详细介绍windows10和ubunu系统下安装步骤,大家有需要可以去参考参考:

零改造迁移实录:2000+存储过程从SQL Server滑入KingbaseES V9R4C12的72小时

在Ubuntu服务器上安装KingbaseES V009R002C012(Orable兼容版)数据库过程详细记录

1.2 JDBC驱动获取与配置

Kingbase的JDBC驱动获取比较麻烦,有几种方式:

方式1:官网下载https://www.kingbase.com.cn/download.html 访问电科金仓官网(需注册账号):

bash 复制代码
wget https://www.kingbase.com.cn/download/jdbc/kingbase8-8.6.0.jar

方式2:安装目录获取 安装完成后,驱动位于:

bash 复制代码
/opt/kingbase/ES/V8/Interface/jdbc/kingbase8-8.6.0.jar

方式3:Maven仓库(推荐) 如果公司搭建了私有仓库,可以上传后使用:

java 复制代码
<dependency>
    <groupId>cn.com.kingbase</groupId>
    <artifactId>kingbase8</artifactId>
    <version>8.6.0</version>
</dependency>

1.3 创建测试数据库

个人建议创建一个单独数据库,不然跟之前表有可能跟系统库冲突,如下图:

sql 复制代码
-- 连接数据库
ksql -U system -d testdb -p 54321

-- 创建测试数据库
CREATE DATABASE devdb 
    WITH 
    OWNER = system
    ENCODING = 'UTF8'
    LC_COLLATE = 'zh_CN.UTF-8'
    LC_CTYPE = 'zh_CN.UTF-8';

-- 切换到新数据库
\c devdb

创建测试表king_user,如下图:

sql 复制代码
-- 创建测试表
CREATE TABLE IF NOT EXISTS king_user (
    user_id BIGSERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(100) NOT NULL,
    real_name VARCHAR(50),
    email VARCHAR(100),
    phone VARCHAR(20),
    status SMALLINT DEFAULT 1,
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

创建对应的索引,方便快速查询,如下所示:

sql 复制代码
-- 创建索引
CREATE INDEX idx_sys_user_username ON king_user(username);
CREATE INDEX idx_sys_user_status ON king_user(status);
CREATE INDEX idx_sys_user_create_time ON king_user(create_time);

-- 插入测试数据
INSERT INTO king_user (username, password, real_name, email, phone) VALUES
('admin', 'e10adc3949ba59abbe56e057f20f883e', '管理员', 'admin@kingbase.com', '13800138000'),
('zhangsan', 'e10adc3949ba59abbe56e057f20f883e', '张三', 'zhangsan@test.com', '13900139000'),
('lisi', 'e10adc3949ba59abbe56e057f20f883e', '李四', 'lisi@test.com', '13700137000');

创建订单表和插入测试数据:

sql 复制代码
-- 创建订单表
CREATE TABLE IF NOT EXISTS biz_order (
    order_id BIGSERIAL PRIMARY KEY,
    order_no VARCHAR(32) NOT NULL UNIQUE,
    user_id BIGINT NOT NULL,
    product_name VARCHAR(200) NOT NULL,
    quantity INTEGER NOT NULL DEFAULT 1,
    unit_price DECIMAL(10,2) NOT NULL,
    total_amount DECIMAL(10,2) NOT NULL,
    order_status SMALLINT DEFAULT 1,
    payment_status SMALLINT DEFAULT 0,
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_order_user FOREIGN KEY (user_id) REFERENCES king_user(user_id)
);

-- 创建订单表索引
CREATE INDEX idx_biz_order_user_id ON biz_order(user_id);
CREATE INDEX idx_biz_order_order_no ON biz_order(order_no);
CREATE INDEX idx_biz_order_create_time ON biz_order(create_time);

-- 插入测试订单数据
INSERT INTO biz_order (order_no, user_id, product_name, quantity, unit_price, total_amount) VALUES
('ORDER202312010001', 2, 'Java编程思想(第4版)', 2, 89.00, 178.00),
('ORDER202312010002', 2, 'Spring实战(第5版)', 1, 99.00, 99.00),
('ORDER202312010003', 3, 'MySQL必知必会', 3, 59.00, 177.00);

二、基础JDBC连接与操作

2.1 最基础的JDBC连接示例

创建一个简单的Java项目,先验证能否正常连接:

java 复制代码
package com.example.kingbase;

import java.sql.*;
import java.util.Properties;

/**
 * KingbaseES基础连接测试
 */
public class BasicConnectionTest {
    
    // 数据库连接信息
    private static final String DB_URL = "jdbc:kingbase8://localhost:54321/devdb";
    private static final String DB_USER = "system";
    private static final String DB_PASSWORD = "123456";
    private static final String DRIVER_CLASS = "com.kingbase8.Driver";
    
    public static void main(String[] args) {
        // 测试连接
        testBasicConnection();
        
        // 测试查询
        testQuery();
        
        // 测试插入
        testInsert();
        
        // 测试事务
        testTransaction();
    }
    
    /**
     * 基础连接测试
     */
    public static void testBasicConnection() {
        Connection conn = null;
        try {
            // 1. 加载驱动
            Class.forName(DRIVER_CLASS);
            System.out.println("驱动加载成功!");
            
            // 2. 获取连接
            conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            System.out.println("数据库连接成功!");
            
            // 3. 获取数据库元数据
            DatabaseMetaData metaData = conn.getMetaData();
            System.out.println("数据库产品名称: " + metaData.getDatabaseProductName());
            System.out.println("数据库版本: " + metaData.getDatabaseProductVersion());
            System.out.println("驱动版本: " + metaData.getDriverVersion());
            System.out.println("用户名: " + metaData.getUserName());
            
        } catch (ClassNotFoundException e) {
            System.err.println("驱动类找不到: " + e.getMessage());
        } catch (SQLException e) {
            System.err.println("数据库连接失败: " + e.getMessage());
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                    System.out.println("数据库连接已关闭!");
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    
 

2.2 查询测试

sql 复制代码
/**
     * 查询测试
     */
    public static void testQuery() {
        String sql = "SELECT user_id, username, real_name, email, create_time FROM sys_user WHERE status = ? ORDER BY create_time DESC";
        
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setInt(1, 1);
            
            try (ResultSet rs = pstmt.executeQuery()) {
                System.out.println("\n=== 用户列表 ===");
                System.out.printf("%-10s %-20s %-20s %-30s %-20s%n", 
                    "用户ID", "用户名", "真实姓名", "邮箱", "创建时间");
                System.out.println("--------------------------------------------------------------------------------");
                
                while (rs.next()) {
                    System.out.printf("%-10d %-20s %-20s %-30s %-20s%n",
                        rs.getLong("user_id"),
                        rs.getString("username"),
                        rs.getString("real_name"),
                        rs.getString("email"),
                        rs.getTimestamp("create_time"));
                }
            }
            
        } catch (SQLException e) {
            System.err.println("查询失败: " + e.getMessage());
        }
    }

2.3 新增测试

java 复制代码
 /**
     * 插入测试
     */
    public static void testInsert() {
        String sql = "INSERT INTO sys_user (username, password, real_name, email, phone) VALUES (?, ?, ?, ?, ?)";
        
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            
            // 设置参数
            pstmt.setString(1, "wangwu");
            pstmt.setString(2, "e10adc3949ba59abbe56e057f20f883e");
            pstmt.setString(3, "王五");
            pstmt.setString(4, "wangwu@test.com");
            pstmt.setString(5, "13600136000");
            
            // 执行插入
            int affectedRows = pstmt.executeUpdate();
            System.out.println("\n插入成功,影响行数: " + affectedRows);
            
            // 获取自动生成的主键
            try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {
                if (generatedKeys.next()) {
                    long userId = generatedKeys.getLong(1);
                    System.out.println("新插入的用户ID: " + userId);
                }
            }
            
        } catch (SQLException e) {
            System.err.println("插入失败: " + e.getMessage());
        }
    }

2.4 删除测试

java 复制代码
 /**
     * 事务测试
     */
    public static void testTransaction() {
        String insertUserSql = "INSERT INTO sys_user (username, password, real_name) VALUES (?, ?, ?)";
        String insertOrderSql = "INSERT INTO biz_order (order_no, user_id, product_name, quantity, unit_price, total_amount) VALUES (?, ?, ?, ?, ?, ?)";
        
        Connection conn = null;
        try
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

/**
 * 批量删除
 */
public static void batchDelete() {
    String sql = "DELETE FROM sys_user WHERE username = ?";
    
    try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
         PreparedStatement pstmt = conn.prepareStatement(sql)) {
        
        conn.setAutoCommit(false);
        
        // 删除测试数据
        String[] usernames = {"test_user_1", "test_user_2", "test_user_3"};
        for (String username : usernames) {
            pstmt.setString(1, username);
            pstmt.addBatch();
        }
        
        int[] results = pstmt.executeBatch();
        conn.commit();
        
        System.out.println("批量删除完成,删除条数: " + results.length);
        
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

2.5 大数据分配处理

java 复制代码
/**
 * 大数据量分批处理
 */
public static void largeDataProcessing() {
    String selectSql = "SELECT user_id, username FROM sys_user WHERE user_id > ? ORDER BY user_id ASC LIMIT ?";
    String updateSql = "UPDATE sys_user SET email = ? WHERE user_id = ?";
    
    try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
         PreparedStatement selectStmt = conn.prepareStatement(selectSql);
         PreparedStatement updateStmt = conn.prepareStatement(updateSql)) {
        
        conn.setAutoCommit(false);
        
        long lastUserId = 0;
        int batchSize = 1000;
        boolean hasMoreData = true;
        
        while (hasMoreData) {
            // 查询一批数据
            selectStmt.setLong(1, lastUserId);
            selectStmt.setInt(2, batchSize);
            
            List<User> userList = new ArrayList<>();
            try (ResultSet rs = selectStmt.executeQuery()) {
                while (rs.next()) {
                    User user = new User();
                    user.userId = rs.getLong("user_id");
                    user.username = rs.getString("username");
                    userList.add(user);
                }
            }
            
            if (userList.isEmpty()) {
                hasMoreData = false;
                continue;
            }
            
            // 更新这批数据
            for (User user : userList) {
                String newEmail = user.username + "@newdomain.com";
                updateStmt.setString(1, newEmail);
                updateStmt.setLong(2, user.userId);
                updateStmt.addBatch();
                
                lastUserId = user.userId;
            }
            
            updateStmt.executeBatch();
            conn.commit();
            updateStmt.clearBatch();
            
            System.out.println("已处理至用户ID: " + lastUserId);
        }
        
        System.out.println("大数据量分批处理完成!");
        
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

三、Spring Boot集成方案

3.1 完整项目配置

创建一个Spring Boot项目,完整的配置如下:

pom.xml完整配置:

XML 复制代码
<?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 
         http://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.7.18</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>kingbase-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>kingbase-demo</name>
    <description>人大金仓数据库集成示例</description>

    <properties>
        <java.version>11</java.version>
        <kingbase.version>8.6.0</kingbase.version>
        <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
        <druid.version>1.2.20</druid.version>
    </properties>

    <dependencies>
        <!-- Spring Boot Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

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

        <!-- 人大金仓JDBC驱动 -->
        <dependency>
            <groupId>cn.com.kingbase</groupId>
            <artifactId>kingbase8</artifactId>
            <version>${kingbase.version}</version>
        </dependency>

        <!-- 数据库连接池 - Druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>

        <!-- MyBatis Plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

        <!-- 测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 工具类 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.22</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3.2 application.yml配置

java 复制代码
server:
  port: 8080
  servlet:
    context-path: /api

spring:
  application:
    name: kingbase-demo

  # 数据源配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.kingbase8.Driver
    url: jdbc:kingbase8://localhost:54321/devdb?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    username: system
    password: 123456
    
    # Druid连接池配置
    druid:
      initial-size: 10
      min-idle: 10
      max-active: 100
      max-wait: 60000
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 1
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      filters: stat,wall,slf4j
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      use-global-data-source-stat: true

# MyBatis Plus配置
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    call-setters-on-nulls: true
    jdbc-type-for-null: 'null'
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      id-type: ASSIGN_ID
      logic-delete-field: deleted
      logic-delete-value: 1
      logic-not-delete-value: 0
  mapper-locations: classpath*:mapper/**/*Mapper.xml

# 日志配置
logging:
  level:
    com.example.kingbase.mapper: debug
    org.springframework.jdbc: debug

3.3 实体类与Mapper

这个实体类就是我们上面刚刚创建的表

java 复制代码
package com.example.kingbase.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 用户实体
 */
@Data
@TableName("king_user")
public class SysUser implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 用户ID
     */
    @TableId(value = "user_id", type = IdType.ASSIGN_ID)
    private Long userId;
    
    /**
     * 用户名
     */
    @TableField("username")
    private String username;
    
    /**
     * 密码
     */
    @TableField("password")
    private String password;
    
    /**
     * 真实姓名
     */
    @TableField("real_name")
    private String realName;
    
    /**
     * 邮箱
     */
    @TableField("email")
    private String email;
    
    /**
     * 手机号
     */
    @TableField("phone")
    private String phone;
    
    /**
     * 状态 0-禁用 1-启用
     */
    @TableField("status")
    private Integer status;
    
    /**
     * 创建时间
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    
    /**
     * 逻辑删除标识
     */
    @TableField("deleted")
    @TableLogic
    private Integer deleted;
}

Mapper接口:

java 复制代码
package com.example.kingbase.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.kingbase.entity.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 用户Mapper
 */
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
    
    /**
     * 根据用户名模糊查询
     */
    List<SysUser> selectByUsernameLike(@Param("username") String username);
    
    /**
     * 批量插入用户
     */
    int batchInsert(@Param("userList") List<SysUser> userList);
    
    /**
     * 根据状态统计用户数量
     */
    int countByStatus(@Param("status") Integer status);
}

mapper xml:

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.kingbase.mapper.SysUserMapper">

    <select id="selectByUsernameLike" resultType="com.example.kingbase.entity.SysUser">
        SELECT user_id, username, password, real_name, email, phone, status, create_time, update_time, deleted
        FROM sys_user
        WHERE username LIKE CONCAT('%', #{username}, '%')
          AND deleted = 0
        ORDER BY create_time DESC
    </select>

    <insert id="batchInsert" parameterType="java.util.List">
        INSERT INTO sys_user (username, password, real_name, email, phone, status, create_time, update_time, deleted)
        VALUES
        <foreach collection="userList" item="user" separator=",">
            (#{user.username}, #{user.password}, #{user.realName}, #{user.email}, #{user.phone}, 
             #{user.status}, #{user.createTime}, #{user.updateTime}, 0)
        </foreach>
    </insert>

    <select id="countByStatus" resultType="java.lang.Integer">
        SELECT COUNT(1)
        FROM sys_user
        WHERE status = #{status}
          AND deleted = 0
    </select>

</mapper>

3.4 服务层与控制层

服务接口:

java 复制代码
package com.example.kingbase.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.kingbase.entity.SysUser;

import java.util.List;

/**
 * 用户服务接口
 */
public interface ISysUserService extends IService<SysUser> {
    
    /**
     * 批量保存用户
     */
    boolean batchSaveUsers(List<SysUser> userList);
    
    /**
     * 根据用户名查询用户
     */
    List<SysUser> getUsersByUsername(String username);
    
    /**
     * 更新用户状态
     */
    boolean updateUserStatus(Long userId, Integer status);
}

服务实现类,常规操作:

java 复制代码
package com.example.kingbase.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.kingbase.entity.SysUser;
import com.example.kingbase.mapper.SysUserMapper;
import com.example.kingbase.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 用户服务实现
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSaveUsers(List<SysUser> userList) {
        if (userList == null || userList.isEmpty()) {
            return false;
        }
        
        // 设置默认值
        LocalDateTime now = LocalDateTime.now();
        for (SysUser user : userList) {
            if (user.getStatus() == null) {
                user.setStatus(1);
            }
            if (user.getCreateTime() == null) {
                user.setCreateTime(now);
            }
            if (user.getUpdateTime() == null) {
                user.setUpdateTime(now);
            }
        }
        
        int insertCount = baseMapper.batchInsert(userList);
        log.info("批量插入用户完成,插入条数:{}", insertCount);
        
        return insertCount == userList.size();
    }
    
    @Override
    public List<SysUser> getUsersByUsername(String username) {
        if (username == null || username.trim().isEmpty()) {
            return list();
        }
        return baseMapper.selectByUsernameLike(username);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserStatus(Long userId, Integer status) {
        SysUser user = getById(userId);
        if (user == null) {
            log.warn("用户不存在,userId:{}", userId);
            return false;
        }
        
        user.setStatus(status);
        user.setUpdateTime(LocalDateTime.now());
        
        return updateById(user);
    }
}

控制层,就是我们平常用的controller

java 复制代码
package com.example.kingbase.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.kingbase.common.Result;
import com.example.kingbase.entity.SysUser;
import com.example.kingbase.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户管理控制器
 */
@Api(tags = "用户管理")
@RestController
@RequestMapping("/user")
public class SysUserController {

    @Autowired
    private ISysUserService userService;

    /**
     * 分页查询用户
     */
    @ApiOperation("分页查询用户")
    @GetMapping("/page")
    public Result<IPage<SysUser>> getUserPage(
            @ApiParam("当前页") @RequestParam(defaultValue = "1") Integer current,
            @ApiParam("每页条数") @RequestParam(defaultValue = "10") Integer size,
            @ApiParam("用户名") @RequestParam(required = false) String username,
            @ApiParam("状态") @RequestParam(required = false) Integer status) {
        
        Page<SysUser> page = new Page<>(current, size);
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        if (username != null && !username.trim().isEmpty()) {
            queryWrapper.like(SysUser::getUsername, username);
        }
        if (status != null) {
            queryWrapper.eq(SysUser::getStatus, status);
        }
        queryWrapper.orderByDesc(SysUser::getCreateTime);
        
        IPage<SysUser> userPage = userService.page(page, queryWrapper);
        return Result.success(userPage);
    }

    /**
     * 根据ID查询用户
     */
    @ApiOperation("根据ID查询用户")
    @GetMapping("/{id}")
    public Result<SysUser> getUserById(@PathVariable Long id) {
        SysUser user = userService.getById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }
        return Result.success(user);
    }

    /**
     * 新增用户
     */
    @ApiOperation("新增用户")
    @PostMapping
    public Result<String> addUser(@RequestBody SysUser user) {
        if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
            return Result.error("用户名不能为空");
        }
        if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
            return Result.error("密码不能为空");
        }
        
        // 检查用户名是否已存在
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUsername, user.getUsername());
        if (userService.count(queryWrapper) > 0) {
            return Result.error("用户名已存在");
        }
        
        // 设置默认值
        if (user.getStatus() == null) {
            user.setStatus(1);
        }
        LocalDateTime now = LocalDateTime.now();
        user.setCreateTime(now);
        user.setUpdateTime(now);
        
        boolean result = userService.save(user);
        if (result) {
            return Result.success("用户新增成功");
        } else {
            return Result.error("用户新增失败");
        }
    }

    /**
     * 批量新增用户
     */
    @ApiOperation("批量新增用户")
    @PostMapping("/batch")
    public Result<String> batchAddUsers(@RequestBody List<SysUser> userList) {
        if (userList == null || userList.isEmpty()) {
            return Result.error("用户列表不能为空");
        }
        
        // 校验数据
        for (SysUser user : userList) {
            if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
                return Result.error("用户名不能为空");
            }
            if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
                return Result.error("密码不能为空");
            }
        }
        
        boolean result = userService.batchSaveUsers(userList);
        if (result) {
            return Result.success("批量新增用户成功,共" + userList.size() + "条");
        } else {
            return Result.error("批量新增用户失败");
        }
    }

    /**
     * 更新用户
     */
    @ApiOperation("更新用户")
    @PutMapping("/{id}")
    public Result<String> updateUser(@PathVariable Long id, @RequestBody SysUser user) {
        SysUser existingUser = userService.getById(id);
        if (existingUser == null) {
            return Result.error("用户不存在");
        }
        
        // 更新字段
        if (user.getRealName() != null) {
            existingUser.setRealName(user.getRealName());
        }
        if (user.getEmail() != null) {
            existingUser.setEmail(user.getEmail());
        }
        if (user.getPhone() != null) {
            existingUser.setPhone(user.getPhone());
        }
        existingUser.setUpdateTime(LocalDateTime.now());
        
        boolean result = userService.updateById(existingUser);
        if (result) {
            return Result.success("用户更新成功");
        } else {
            return Result.error("用户更新失败");
        }
    }

    /**
     * 更新用户状态
     */
    @ApiOperation("更新用户状态")
    @PutMapping("/{id}/status/{status}")
    public Result<String> updateUserStatus(
            @PathVariable Long id,
            @PathVariable Integer status) {
        if (status != 0 && status != 1) {
            return Result.error("状态值只能是0或1");
        }
        
        boolean result = userService.updateUserStatus(id, status);
        if (result) {
            return Result.success("用户状态更新成功");
        } else {
            return Result.error("用户状态更新失败");
        }
    }

    /**
     * 删除用户
     */
    @ApiOperation("删除用户")
    @DeleteMapping("/{id}")
    public Result<String> deleteUser(@PathVariable Long id) {
        boolean result = userService.removeById(id);
        if (result) {
            return Result.success("用户删除成功");
        } else {
            return Result.error("用户删除失败");
        }
    }

    /**
     * 批量删除用户
     */
    @ApiOperation("批量删除用户")
    @DeleteMapping("/batch")
    public Result<String> batchDeleteUsers(@RequestBody List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return Result.error("用户ID列表不能为空");
        }
        
        boolean result = userService.removeByIds(ids);
        if (result) {
            return Result.success("批量删除用户成功");
        } else {
            return Result.error("批量删除用户失败");
        }
    }

    /**
     * 根据用户名查询用户
     */
    @ApiOperation("根据用户名查询用户")
    @GetMapping("/search")
    public Result<List<SysUser>> searchUsers(@RequestParam String username) {
        List<SysUser> userList = userService.getUsersByUsername(username);
        return Result.success(userList);
    }

    /**
     * 统计用户数量
     */
    @ApiOperation("统计用户数量")
    @GetMapping("/count")
    public Result<Integer> countUsers(@RequestParam(required = false) Integer status) {
        int count;
        if (status == null) {
            count = userService.count();
        } else {
            count = userService.count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getStatus, status));
        }
        return Result.success(count);
    }
}

编写完就可以用postman去测试咯

四、总结

本文分享了KingbaseES V8.6数据库与SpringBoot 2.7.x框架的集成实战经验。内容包括:1. 环境准备(Ubuntu系统安装配置、驱动获取方式);2. JDBC基础操作(连接、查询、事务处理);3. SpringBoot项目完整配置(pom依赖、数据源配置);4. MyBatis-Plus集成(实体类、Mapper、Service层实现);5. RESTful接口开发示例。文章提供了详细的代码示例,涵盖从数据库安装到应用开发的完整流程,帮助开发者快速实现国产数据库适配。

编码不易,希望各位点赞支持,也支持我们国产的数据库,纸上得来终觉浅,希望各位大佬也亲自动手尝试一下,如果遇到什么问题欢迎评论区留言交流,相互学习,共同进步~正在走向自律

本文相关《电科金仓》分类链接推荐:

第一章:基础与入门

1、【金仓数据库征文】政府项目数据库迁移:从MySQL 5.7到KingbaseES的蜕变之路

2、【金仓数据库征文】学校AI数字人:从Sql Server到KingbaseES的数据库转型之路

3、电科金仓2025发布会,国产数据库的AI融合进化与智领未来

4、国产数据库逆袭:老邓的"六大不敢替"被金仓逐一破解

5、《一行代码不改动!用KES V9 2025完成SQL Server → 金仓"平替"迁移并启用向量检索》

6、《赤兔引擎×的卢智能体:电科金仓如何用"三骏架构"重塑AI原生数据库一体机》

7、探秘KingbaseES在线体验平台:技术盛宴还是虚有其表?

8、破除"分布式"迷思:回归数据库选型的本质

9、KDMS V4 一键搞定国产化迁移:零代码、零事故、零熬夜------金仓社区发布史上最省心数据库迁移评估神器

10、KingbaseES V009版本发布:国产数据库的新飞跃

第二章:能力与提升

1、零改造迁移实录:2000+存储过程从SQL Server滑入KingbaseES V9R4C12的72小时
2、国产数据库迁移神器,KDMSV4震撼上线

3、在Ubuntu服务器上安装KingbaseES V009R002C012(Orable兼容版)数据库过程详细记录

4、金仓数据库迁移评估系统(KDMS)V4 正式上线:国产化替代的技术底气

5、Ubuntu系统下Python连接国产KingbaseES数据库实现增删改查

6、Java连接电科金仓数据库(KingbaseES)实战指南

相关推荐
xiaoye37082 小时前
Java 事务失效场景全解析
java
寻星探路2 小时前
数据库造神计划第五天---增删改查(CRUD)(1)
数据库
小虾米vivian2 小时前
达梦:将sql通过shell脚本的方式放在后台执行
服务器·数据库·sql
水无痕simon2 小时前
1. 数据库架构演变与分库分表介绍
数据库·数据库架构
weixin_436525072 小时前
Spring Boot 集成 EasyExcel 的最佳实践:优雅实现 Excel 导入导出
java·spring boot·后端
ChinaRainbowSea2 小时前
9. LangChain4j + 整合 Spring Boot
java·人工智能·spring boot·后端·spring·langchain·ai编程
ゞ 正在缓冲99%…2 小时前
leetcode35.搜索插入位置
java·算法·leetcode·二分查找
武昌库里写JAVA3 小时前
Mac下Python3安装
java·vue.js·spring boot·sql·学习
专注代码七年3 小时前
查询 mysql中 所有的 非空记录字段
数据库·mysql