AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Eclipselink Xugudb Adapter

skill-kourou25-xugudb-dev-skills-eclipselink-xugudb-adapter · by kourou25

EclipseLink 框架适配虚谷数据库(XuguDB)的完整指南。当用户需要将基于 EclipseLink 的 Java 项目配置或适配到虚谷数据库时使用此技能,包括 JPA 配置、实体管理、查询构建、缓存配置、性能优化等。适用于从 Oracle/MySQL 迁移或新建虚谷数据库项目。

— No reviews yet
0 installs
25 views
0.0% view→install

Install

$ agentstack add skill-kourou25-xugudb-dev-skills-eclipselink-xugudb-adapter

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-kourou25-xugudb-dev-skills-eclipselink-xugudb-adapter)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Eclipselink Xugudb Adapter? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

EclipseLink 虚谷数据库适配指南

概述

本技能提供 EclipseLink 框架适配虚谷数据库(XuguDB)的完整配置指南。EclipseLink 是一个成熟的 Java ORM 框架,是 JPA(Java Persistence API)的参考实现,支持多种数据库,现在可以通过虚谷数据库驱动支持虚谷数据库。

适用场景:

  • Java 企业级应用开发
  • JPA 标准应用开发
  • 从 Oracle/MySQL 迁移到虚谷数据库
  • 需要高性能缓存的应用
  • 需要复杂查询和事务管理的应用

核心特性:

  • 完整的 JPA 2.2 规范支持
  • 高级缓存机制(L1/L2 缓存、分布式缓存)
  • 动态查询和 Criteria API
  • 支持多种继承策略
  • 支持复杂关系映射
  • 支持数据库迁移和版本控制
  • 支持多租户架构

快速开始

1. 添加依赖

Maven 配置:


    
    
        org.eclipse.persistence
        eclipselink
        2.7.12
    
    
    
    
        javax.persistence
        javax.persistence-api
        2.2
    
    
    
    
        com.xugu
        xugu-jdbc
        12.0.0
    
    
    
    
        com.zaxxer
        HikariCP
        5.0.1
    

Gradle 配置:

dependencies {
    implementation 'org.eclipse.persistence:eclipselink:2.7.12'
    implementation 'javax.persistence:javax.persistence-api:2.2'
    implementation 'com.xugu:xugu-jdbc:12.0.0'
    implementation 'com.zaxxer:HikariCP:5.0.1'
}

2. 配置 persistence.xml

在 src/main/resources/META-INF/persistence.xml 中配置:


    
    
        org.eclipse.persistence.jpa.PersistenceProvider
        
        
        com.example.entity.User
        com.example.entity.Order
        
        
        
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
    

3. 创建实体类

package com.example.entity;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.List;

@Entity
@Table(name = "users")
@NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "name", length = 100, nullable = false)
    private String name;
    
    @Column(name = "email", length = 200, unique = true, nullable = false)
    private String email;
    
    @Column(name = "phone", length = 20)
    private String phone;
    
    @Column(name = "status", columnDefinition = "SMALLINT DEFAULT 1")
    private Integer status = 1;
    
    @Column(name = "created_at", updatable = false)
    private LocalDateTime createdAt;
    
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
    
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List orders;
    
    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
        updatedAt = LocalDateTime.now();
    }
    
    @PreUpdate
    protected void onUpdate() {
        updatedAt = LocalDateTime.now();
    }
    
    // Getters and Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    
    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }
    
    public Integer getStatus() { return status; }
    public void setStatus(Integer status) { this.status = status; }
    
    public LocalDateTime getCreatedAt() { return createdAt; }
    public LocalDateTime getUpdatedAt() { return updatedAt; }
    
    public List getOrders() { return orders; }
    public void setOrders(List orders) { this.orders = orders; }
}

4. 创建 DAO 层

package com.example.dao;

import com.example.entity.User;
import javax.persistence.*;
import java.util.List;
import java.util.Optional;

public class UserRepository {
    
    private EntityManagerFactory emf;
    private EntityManager em;
    
    public UserRepository() {
        emf = Persistence.createEntityManagerFactory("XuguDB_PU");
        em = emf.createEntityManager();
    }
    
    // 保存用户
    public User save(User user) {
        em.getTransaction().begin();
        try {
            if (user.getId() == null) {
                em.persist(user);
            } else {
                user = em.merge(user);
            }
            em.getTransaction().commit();
            return user;
        } catch (Exception e) {
            em.getTransaction().rollback();
            throw e;
        }
    }
    
    // 根据ID查找用户
    public Optional findById(Long id) {
        User user = em.find(User.class, id);
        return Optional.ofNullable(user);
    }
    
    // 查找所有用户
    public List findAll() {
        TypedQuery query = em.createQuery("SELECT u FROM User u", User.class);
        return query.getResultList();
    }
    
    // 根据邮箱查找用户
    public Optional findByEmail(String email) {
        TypedQuery query = em.createNamedQuery("User.findByEmail", User.class);
        query.setParameter("email", email);
        List results = query.getResultList();
        return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
    }
    
    // 分页查询
    public List findAll(int page, int size) {
        TypedQuery query = em.createQuery("SELECT u FROM User u ORDER BY u.id", User.class);
        query.setFirstResult((page - 1) * size);
        query.setMaxResults(size);
        return query.getResultList();
    }
    
    // 条件查询
    public List findByStatus(Integer status) {
        TypedQuery query = em.createQuery(
            "SELECT u FROM User u WHERE u.status = :status", User.class);
        query.setParameter("status", status);
        return query.getResultList();
    }
    
    // 删除用户
    public void delete(Long id) {
        em.getTransaction().begin();
        try {
            User user = em.find(User.class, id);
            if (user != null) {
                em.remove(user);
            }
            em.getTransaction().commit();
        } catch (Exception e) {
            em.getTransaction().rollback();
            throw e;
        }
    }
    
    // 关闭资源
    public void close() {
        if (em != null && em.isOpen()) {
            em.close();
        }
        if (emf != null && emf.isOpen()) {
            emf.close();
        }
    }
}

JPA 查询语言 (JPQL)

基础查询

// 简单查询
TypedQuery query = em.createQuery("SELECT u FROM User u", User.class);
List users = query.getResultList();

// 带参数查询
TypedQuery query = em.createQuery(
    "SELECT u FROM User u WHERE u.status = :status", User.class);
query.setParameter("status", 1);
List activeUsers = query.getResultList();

// 模糊查询
TypedQuery query = em.createQuery(
    "SELECT u FROM User u WHERE u.name LIKE :name", User.class);
query.setParameter("name", "%张%");
List users = query.getResultList();

关联查询

// 一对一查询
TypedQuery query = em.createQuery(
    "SELECT u FROM User u JOIN u.profile p WHERE p.bio IS NOT NULL", User.class);

// 一对多查询
TypedQuery query = em.createQuery(
    "SELECT u FROM User u JOIN u.orders o WHERE o.amount > 100", User.class);

// 多对多查询
TypedQuery query = em.createQuery(
    "SELECT u FROM User u JOIN u.roles r WHERE r.name = :roleName", User.class);
query.setParameter("roleName", "ADMIN");

聚合查询

// 统计查询
TypedQuery countQuery = em.createQuery(
    "SELECT COUNT(u) FROM User u WHERE u.status = :status", Long.class);
countQuery.setParameter("status", 1);
Long count = countQuery.getSingleResult();

// 分组查询
TypedQuery groupQuery = em.createQuery(
    "SELECT u.status, COUNT(u) FROM User u GROUP BY u.status", Object[].class);
List results = groupQuery.getResultList();

// 联合查询
TypedQuery aggregateQuery = em.createQuery(
    "SELECT COUNT(u), AVG(u.age), MAX(u.createdAt) FROM User u", Object[].class);
Object[] result = aggregateQuery.getSingleResult();

Criteria API

动态查询构建

import javax.persistence.criteria.*;

public List findUsersByCriteria(String name, Integer status, int page, int size) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery cq = cb.createQuery(User.class);
    Root root = cq.from(User.class);
    
    // 构建查询条件
    List predicates = new ArrayList<>();
    
    if (name != null && !name.isEmpty()) {
        predicates.add(cb.like(root.get("name"), "%" + name + "%"));
    }
    
    if (status != null) {
        predicates.add(cb.equal(root.get("status"), status));
    }
    
    // 组合条件
    if (!predicates.isEmpty()) {
        cq.where(cb.and(predicates.toArray(new Predicate[0])));
    }
    
    // 排序
    cq.orderBy(cb.desc(root.get("createdAt")));
    
    // 执行查询
    TypedQuery query = em.createQuery(cq);
    query.setFirstResult((page - 1) * size);
    query.setMaxResults(size);
    
    return query.getResultList();
}

复杂 Criteria 查询

public List findUserDTOsByCriteria() {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery cq = cb.createQuery(UserDTO.class);
    Root root = cq.from(User.class);
    
    // 投影查询
    cq.select(cb.construct(UserDTO.class,
        root.get("id"),
        root.get("name"),
        root.get("email"),
        cb.count(root.get("orders"))
    ));
    
    // 分组
    cq.groupBy(root.get("id"), root.get("name"), root.get("email"));
    
    // 条件
    cq.having(cb.greaterThan(cb.count(root.get("orders")), 0L));
    
    return em.createQuery(cq).getResultList();
}

事务管理

编程式事务

public void transferMoney(Long fromAccountId, Long toAccountId, BigDecimal amount) {
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    
    try {
        tx.begin();
        
        Account fromAccount = em.find(Account.class, fromAccountId);
        Account toAccount = em.find(Account.class, toAccountId);
        
        if (fromAccount.getBalance().compareTo(amount)  users) {
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    
    try {
        tx.begin();
        
        int batchSize = 1000;
        for (int i = 0; i  0 && i % batchSize == 0) {
                em.flush();
                em.clear();
            }
        }
        
        tx.commit();
    } catch (Exception e) {
        if (tx.isActive()) {
            tx.rollback();
        }
        throw e;
    } finally {
        em.close();
    }
}

查询优化

// 使用 JOIN FETCH 避免 N+1 问题
TypedQuery query = em.createQuery(
    "SELECT u FROM User u JOIN FETCH u.orders WHERE u.status = :status", User.class);
query.setParameter("status", 1);
List users = query.getResultList();

// 使用投影查询减少数据传输
TypedQuery query = em.createQuery(
    "SELECT u.id, u.name, u.email FROM User u WHERE u.status = :status", Object[].class);
query.setParameter("status", 1);
List results = query.getResultList();

// 使用分页查询
TypedQuery query = em.createQuery("SELECT u FROM User u ORDER BY u.id", User.class);
query.setFirstResult(0);
query.setMaxResults(10);
List users = query.getResultList();

索引优化

@Entity
@Table(name = "users", indexes = {
    @Index(name = "idx_users_email", columnList = "email", unique = true),
    @Index(name = "idx_users_status", columnList = "status"),
    @Index(name = "idx_users_created_at", columnList = "created_at DESC")
})
public class User {
    // 实体定义
}

高级特性

继承映射

// 单表继承
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public abstract class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
}

@Entity
@DiscriminatorValue("EMPLOYEE")
public class Employee extends Person {
    private String department;
    private BigDecimal salary;
}

@Entity
@DiscriminatorValue("CUSTOMER")
public class Customer extends Person {
    private String customerType;
    private BigDecimal creditLimit;
}

多租户支持

@Entity
@Table(name = "users")
@Multitenant(MultitenantType.TABLE_PER_TENANT)
@TenantTableDiscriminator(type = TenantTableDiscriminatorType.PREFIX, contextProperty = "tenant.id")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
}

// 使用多租户
EntityManager em = emf.createEntityManager();
em.setProperty("tenant.id", "tenant_001");
List users = em.createQuery("SELECT u FROM User u", User.class).getResultList();

数据库迁移

import org.eclipse.persistence.sessions.factories.SessionManager;
import org.eclipse.persistence.tools.schemaframework.SchemaManager;

// 自动创建表结构
SchemaManager schemaManager = new SchemaManager(session);
schemaManager.createDefaultTables(true);

// 手动执行 DDL
schemaManager.createTable("users");
schemaManager.addColumn("users", "new_column", String.class, 100);

// 生成 DDL 脚本
schemaManager.outputCreateDDLToWriter(writer);

Spring Boot 集成

配置 application.yml

spring:
  datasource:
    driver-class-name: com.xugu.cloudjdbc.Driver
    url: jdbc:xugu://127.0.0.1:5138/SYSTEM?current_schema=SYSDBA&CHAR_SET=UTF8
    username: SYSDBA
    password: SYSDBA
    
  jpa:
    database-platform: org.eclipse.persistence.platform.database.DatabasePlatform
    properties:
      eclipselink:
        ddl-generation: create-or-extend-tables
        ddl-generation-output-mode: database
        logging:
          level: INFO
          parameters: true
        cache:
          shared:
            default: true
          size:
            default: 1000
          type:
            default: SOFT
        connection-pool:
          default:
            initial: 5
            min: 5
            max: 50

配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
import javax.sql.DataSource;

@Configuration
public class JpaConfig {
    
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("com.example.entity");
        em.setJpaVendorAdapter(new EclipseLinkJpaVendorAdapter());
        em.setJpaProperties(additionalProperties());
        return em;
    }
    
    private Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("eclipselink.ddl-generation", "create-or-extend-tables");
        properties.setProperty("eclipselink.logging.level", "INFO");
        properties.setProperty("eclipselink.cache.shared.default", "true");
        return properties;
    }
}

测试配置

单元测试

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.persistence.*;
import static org.junit.jupiter.api.Assertions.*;

class UserRepositoryTest {
    
    private EntityManagerFactory emf;
    private EntityManager em;
    private UserRepository userRepository;
    
    @BeforeEach
    void setUp() {
        emf = Persistence.createEntityManagerFactory("TestPU");
        em = emf.createEntityManager();
        userRepository = new UserRepository(em);
    }
    
    @Test
    void testSaveUser() {
        User user = new User();
        user.setName("测试用户");
        user.setEmail("test@example.com");
        
        User savedUser = userRepository.save(user);
        
        assertNotNull(savedUser.getId());
        assertEquals("测试用户", savedUser.getName());
    }
    
    @Test
    void testFindByEmail() {
        User user = new User();
        user.setName("测试用户");
        user.setEmail("test@example.com");
        userRepository.save(user);
        
        Optional found = userRepositor

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [kourou25](https://github.com/kourou25)
- **Source:** [kourou25/xugudb-dev-skills](https://github.com/kourou25/xugudb-dev-skills)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.