You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非云Confluence插件开发:如何通过Atlassian框架访问数据库?

Confluence 非云版插件:自定义SQL查询功能实现指南

1. atlassian-plugin.xml 核心配置

依赖与权限声明

  • REST端点配置:限制仅管理员访问,确保数据库操作的安全性
<rest name="Custom SQL Endpoint" key="custom-sql-rest" path="/custom-sql" version="1.0">
    <description>执行自定义SQL查询的后端接口</description>
    <package>com.yourcompany.confluence.plugins.customsql.rest</package>
    <permission>administer-confluence</permission>
</rest>
  • 管理员页面挂载:将查询UI嵌入Confluence全局设置页面
<web-panel key="custom-sql-admin-panel" location="system.admin/globalsettings" weight="100">
    <description>管理员自定义SQL查询面板</description>
    <label>自定义SQL查询</label>
    <resource type="velocity" name="view" location="/templates/custom-sql-admin.vm"/>
    <permission>administer-confluence</permission>
</web-panel>

2. 数据库访问实现(替代Jira的Manager类)

Confluence基于Hibernate而非OFBiz,推荐以下两种标准方式:

方式1:Hibernate会话管理器(推荐)

注入HibernateSessionManager获取会话,执行原生SQL:

import com.atlassian.confluence.core.persistence.hibernate.HibernateSessionManager;
import com.atlassian.sal.api.transaction.TransactionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.Map;

@Path("/query")
public class CustomSqlResource {

    private final HibernateSessionManager hibernateSessionManager;
    private final TransactionTemplate transactionTemplate;

    @Autowired
    public CustomSqlResource(HibernateSessionManager hibernateSessionManager, TransactionTemplate transactionTemplate) {
        this.hibernateSessionManager = hibernateSessionManager;
        this.transactionTemplate = transactionTemplate;
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public List<Map<String, Object>> executeSql(Map<String, String> request) {
        String sql = request.get("sql");
        // 强制校验:仅允许SELECT查询,防止数据破坏
        if (!sql.trim().toUpperCase().startsWith("SELECT")) {
            throw new IllegalArgumentException("仅支持SELECT查询");
        }
        // 事务内执行,避免连接泄漏
        return transactionTemplate.execute(() -> {
            return hibernateSessionManager.getSession()
                    .createNativeQuery(sql)
                    .setResultTransformer(org.hibernate.transform.AliasToEntityMapResultTransformer.INSTANCE)
                    .list();
        });
    }
}

方式2:直接使用DataSource(不推荐)

若需JDBC原生操作,可注入javax.sql.DataSource,但需自行管理连接和事务:

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
// 注入DataSource后执行查询

3. 前端UI实现(Velocity模板)

创建/templates/custom-sql-admin.vm,实现SQL输入、执行按钮和结果表格渲染:

<div class="aui-page-panel">
    <h2>自定义SQL查询工具</h2>
    <div class="aui-group">
        <textarea id="sqlQuery" class="aui-textarea" rows="5" placeholder="输入SELECT查询语句..."></textarea>
    </div>
    <div class="aui-group">
        <button id="executeBtn" class="aui-button aui-button-primary">执行查询</button>
    </div>
    <div id="resultContainer" class="aui-group" style="margin-top: 20px; display: none;">
        <h3>查询结果</h3>
        <table id="resultTable" class="aui aui-table-stripes"></table>
    </div>
</div>

<script>
AJS.toInit(function() {
    AJS.$("#executeBtn").click(function() {
        var sql = AJS.$("#sqlQuery").val().trim();
        if (!sql) {
            AJS.messages.error({title: "错误", body: "请输入SQL查询语句", container: "#resultContainer"});
            return;
        }
        AJS.$.ajax({
            url: AJS.contextPath() + "/rest/custom-sql/1.0/query",
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify({sql: sql}),
            success: function(data) {
                var table = AJS.$("#resultTable").empty();
                if (data.length === 0) {
                    table.append("<tr><td colspan='100%'>无查询结果</td></tr>");
                } else {
                    // 构建表头
                    var headers = Object.keys(data[0]);
                    var headerRow = "<tr>" + headers.map(h => `<th>${h}</th>`).join("") + "</tr>";
                    table.append(headerRow);
                    // 构建数据行
                    data.forEach(row => {
                        var dataRow = "<tr>" + headers.map(h => `<td>${row[h] || ""}</td>`).join("") + "</tr>";
                        table.append(dataRow);
                    });
                }
                AJS.$("#resultContainer").show();
            },
            error: function(xhr) {
                AJS.messages.error({title: "执行失败", body: xhr.responseText || "查询执行出错", container: "#resultContainer"});
                AJS.$("#resultContainer").show();
            }
        });
    });
});
</script>

4. 关键注意事项

  • SQL注入防护:必须限制仅允许SELECT操作,禁止DDL/DML语句,避免数据库被恶意修改
  • 事务管理:所有数据库操作需通过TransactionTemplate包裹,防止连接泄漏和数据不一致
  • 权限控制:所有UI和REST端点必须添加administer-confluence权限校验,仅开放给管理员
  • 版本兼容性:不同Confluence版本的Hibernate依赖可能不同,需在pom.xml中匹配对应版本的confluence-core依赖

内容的提问来源于stack exchange,提问作者MIkailK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:47:03