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

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.2 JDBC驱动获取与配置

1.3 创建测试数据库

二、基础JDBC连接与操作

2.1 最基础的JDBC连接示例

2.2 查询测试

2.3 新增测试

2.4 删除测试

2.5 大数据分配处理

三、Spring Boot集成方案

3.1 完整项目配置

3.2 application.yml配置

3.3 实体类与Mapper

3.4 服务层与控制层

四、总结


前言

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

一、环境准备与驱动获取

1.1 数据库安装与配置

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

# 创建用户 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 访问电科金仓官网(需注册账号):

wget https://www.kingbase.com.cn/download/jdbc/kingbase8-8.6.0.jar

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

/opt/kingbase/ES/V8/Interface/jdbc/kingbase8-8.6.0.jar

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

<dependency> <groupId>cn.com.kingbase</groupId> <artifactId>kingbase8</artifactId> <version>8.6.0</version> </dependency>

1.3 创建测试数据库

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

-- 连接数据库 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,如下图:

-- 创建测试表 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 );

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

-- 创建索引 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', '管理员', '[email protected]', '13800138000'), ('zhangsan', 'e10adc3949ba59abbe56e057f20f883e', '张三', '[email protected]', '13900139000'), ('lisi', 'e10adc3949ba59abbe56e057f20f883e', '李四', '[email protected]', '13700137000');

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

-- 创建订单表 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项目,先验证能否正常连接:

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 查询测试

/** * 查询测试 */ 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 新增测试

 /** * 插入测试 */ 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, "[email protected]"); 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 删除测试

 /** * 事务测试 */ 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 大数据分配处理

/** * 大数据量分批处理 */ 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 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配置

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

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

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接口:

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:

<?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 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 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 resultType="java.lang.Integer"> SELECT COUNT(1) FROM sys_user WHERE status = #{status} AND deleted = 0 </select> </mapper>

3.4 服务层与控制层

服务接口:

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); }

服务实现类,常规操作:

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

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)实战指南

Read more

深挖 DeepSeek 隐藏玩法·智能炼金术2.0版本

深挖 DeepSeek 隐藏玩法·智能炼金术2.0版本

前引:屏幕前的你还在AI智能搜索框这样搜索吗?“这道题怎么写”“苹果为什么红”“怎么不被发现翘课” ,。看到此篇文章的小伙伴们!请准备好你的思维魔杖,开启【霍格沃茨模式】,看我如何更新秘密的【知识炼金术】,我们一起来解锁更加刺激的剧情!友情提醒:《《《前方高能》》》 目录 在哪使用DeepSeek 如何对提需求  隐藏玩法总结 几个高阶提示词 职场打工人 自媒体创作 电商实战 程序员开挂 非适用场地 “服务器繁忙”如何解决 (1)硅基流动平台 (2)Chatbox + API集成方案 (3)各大云平台 搭建个人知识库 前置准备 下载安装AnythingLLM 选择DeepSeek作为AI提供商 创作工作区 导入文档 编辑  编辑 小编寄语 ——————————————————————————————————————————— 在哪使用DeepSeek 我们解锁剧情前,肯定要知道在哪用DeepSeek!咯,为了照顾一些萌新朋友,它的下载方式我放在下面了,拿走不谢!  (1)

By Ne0inhk
【AI大模型】DeepSeek + 通义万相高效制作AI视频实战详解

【AI大模型】DeepSeek + 通义万相高效制作AI视频实战详解

目录 一、前言 二、AI视频概述 2.1 什么是AI视频 2.2 AI视频核心特点 2.3 AI视频应用场景 三、通义万相介绍 3.1 通义万相概述 3.1.1 什么是通义万相 3.2 通义万相核心特点 3.3 通义万相技术特点 3.4 通义万相应用场景 四、DeepSeek + 通义万相制作AI视频流程 4.1 DeepSeek + 通义万相制作视频优势 4.1.1 DeepSeek 优势 4.1.2 通义万相视频生成优势 4.2

By Ne0inhk
【DeepSeek微调实践】DeepSeek-R1大模型基于MS-Swift框架部署/推理/微调实践大全

【DeepSeek微调实践】DeepSeek-R1大模型基于MS-Swift框架部署/推理/微调实践大全

系列篇章💥 No.文章01【DeepSeek应用实践】DeepSeek接入Word、WPS方法详解:无需代码,轻松实现智能办公助手功能02【DeepSeek应用实践】通义灵码 + DeepSeek:AI 编程助手的实战指南03【DeepSeek应用实践】Cline集成DeepSeek:开源AI编程助手,终端与Web开发的超强助力04【DeepSeek开发入门】DeepSeek API 开发初体验05【DeepSeek开发入门】DeepSeek API高级开发指南(推理与多轮对话机器人实践)06【DeepSeek开发入门】Function Calling 函数功能应用实战指南07【DeepSeek部署实战】DeepSeek-R1-Distill-Qwen-7B:本地部署与API服务快速上手08【DeepSeek部署实战】DeepSeek-R1-Distill-Qwen-7B:Web聊天机器人部署指南09【DeepSeek部署实战】DeepSeek-R1-Distill-Qwen-7B:基于vLLM 搭建高性能推理服务器10【DeepSeek部署实战】基于Ollama快速部署Dee

By Ne0inhk

DeepSeek各版本说明与优缺点分析_deepseek各版本区别

DeepSeek各版本说明与优缺点分析 DeepSeek是最近人工智能领域备受瞩目的一个语言模型系列,其在不同版本的发布过程中,逐步加强了对多种任务的处理能力。本文将详细介绍DeepSeek的各版本,从版本的发布时间、特点、优势以及不足之处,为广大AI技术爱好者和开发者提供一份参考指南。 1. DeepSeek-V1:起步与编码强劲 DeepSeek-V1是DeepSeek的起步版本,这里不过多赘述,主要分析它的优缺点。 发布时间: 2024年1月 特点: DeepSeek-V1是DeepSeek系列的首个版本,预训练于2TB的标记数据,主打自然语言处理和编码任务。它支持多种编程语言,具有强大的编码能力,适合程序开发人员和技术研究人员使用。 优势: * 强大编码能力:支持多种编程语言,能够理解和生成代码,适合开发者进行自动化代码生成与调试。 * 高上下文窗口:支持高达128K标记的上下文窗口,能够处理较为复杂的文本理解和生成任务。 缺点: * 多模态能力有限:该版本主要集中在文本处理上,缺少对图像、语音等多模态任务的支持。 * 推理能力较弱:尽管在自然语言

By Ne0inhk