插件发布到市场后,后续版本迭代的过程中,可能会对ao实体类的字段作添加或删除,或者要将某一字段的值映射解析到另一字段上。

本来这个工作,可以在插件启动的时候,在实现了com.atlassian.sal.api.lifecycle.LifecycleAware 接口的类onStart方法类完成。

但是历史版本更新了哪些字段不好维护,以前查看其它插件的代码时有看到版本更新任务的代码,但是因为实际工作中用的很少,就没去细看。

这几天查看atlassian的文档时,发现有一篇专门介绍如何处理upgradTask的文档。其实这篇文档是在一个系列中的,话说回来,atlassian插件开发的文档虽然挺全的,但是总体的文档结构还是有点乱的。

官网链接:处理AO升级任务

下文是对文档上的一些内容的截取


比如说我们之前有一个Todo类,它继承了Entity

 @Preload
public interface Todo extend Entity {
void setUserName (String userName ); String getUserName (); String getDescription (); void setDescription (String description ); boolean isComplete (); void setComplete (boolean complete );
}

Todo类中维护了一个userName字段,但是在后续的开发中,用户需要维护的信息很多,不止是用户名这么简单了。此时我们需要重新建一个User表,用来存放用户信息。

 public interface User extends Entity
{
String getName();
void setName(String name);
}

Todo类也得做修改

 package com.atlassian.tutorial.ao.todo;

 import net.java.ao.Entity;
import net.java.ao.Preload;
import net.java.ao.schema.NotNull; @Preload
public interface Todo extends Entity
{
@NotNull
void setUser(User user); @NotNull
User getUser(); String getDescription(); void setDescription(String description); boolean isComplete(); void setComplete(boolean complete);
}

之前service里的方法当然得修改,但这不是我们这里讨论的重点,接下来我们看,如何使用upgradetask更新数据库数据。

首先在ao包下面新建一个pacakge,名为upgrade.v2(官网上还建了v1包,但是那个升级改动较小,这里就不详述了)。

每次版本更新都要新建一个(v版本号)的包,包内存放需要更新的数据库实体类(从ao.entity包内复制过来,并做相应的改动。它不会在数据库内重新建一张表,只是用来记录更新信息)和更新任务类

 package com.atlassian.tutorial.ao.todo.upgrade.v2;

 import net.java.ao.Entity;
import net.java.ao.Preload;
// 保留了需要更新掉的字段user_name和需要新增的user_id字段(即getUser)
@Preload
public interface Todo extends Entity
{
void setUserName(String userName); String getUserName(); void setUser(User user); User getUser(); String getDescription(); void setDescription(String description); boolean isComplete(); void setComplete(boolean complete);
}

user表是新增的,没有改动,直接复制过来

接下来就是更新的代码类了

 package com.atlassian.tutorial.ao.todo.upgrade.v2; // (1) 引用upgrade.v2包下的类

 import com.atlassian.activeobjects.external.ActiveObjects;
import com.atlassian.activeobjects.external.ActiveObjectsUpgradeTask;
import com.atlassian.activeobjects.external.ModelVersion;
import com.google.common.collect.ImmutableMap;
import net.java.ao.Query; public final class TodoUpgradeTask002 implements ActiveObjectsUpgradeTask
{
@Override
public ModelVersion getModelVersion()
{
return ModelVersion.valueOf("2"); // (2) 版本设置为2
} @Override
public void upgrade(ModelVersion currentVersion, ActiveObjects ao)
{
ao.migrate(Todo.class, User.class); // (3) 声明需要操作的类 Todo[] todos = ao.find(Todo.class); // (4) 实际升级,设置User对应的userName。
for (Todo todo : todos)
{
todo.setUser(getOrCreateUser(ao, todo.getUserName()));
todo.save();
}
} private User getOrCreateUser(ActiveObjects ao, String userName)
{
User[] users = ao.find(User.class, Query.select().where("NAME = ?", userName));
if (users.length == 0) {
return createUser(ao, userName);
} else if (users.length == 1) {
return users[0];
} else {
throw new IllegalStateException("There shouldn't be 2 users with the same username! " + userName);
}
} private User createUser(ActiveObjects ao, String userName)
{
return ao.create(User.class, ImmutableMap.<String, Object>of("NAME", userName));
}
}

最后,需要在atlassian-plugin.xml中配置

  <ao key="ao-module">
<description>The module configuring the Active Objects service used by this plugin</description>
<entity>com.atlassian.tutorial.ao.todo.Todo</entity>
<entity>com.atlassian.tutorial.ao.todo.User</entity>
<upgradeTask>com.atlassian.tutorial.ao.todo.upgrade.v1.TodoUpgradeTask001</upgradeTask>
<upgradeTask>com.atlassian.tutorial.ao.todo.upgrade.v2.TodoUpgradeTask002</upgradeTask>
</ao>

执行,下面是官网给出的执行日志,

 [INFO] [talledLocalContainer]  INFO - assian.activeobjects.internal.ActiveObjectUpgradeManagerImpl - Starting upgrade of data model, current version is 1
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - CREATE TABLE AO_3F7D93_USER (
[INFO] [talledLocalContainer] ID INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
[INFO] [talledLocalContainer] NAME VARCHAR(255),
[INFO] [talledLocalContainer] PRIMARY KEY(ID)
[INFO] [talledLocalContainer] )
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - ALTER TABLE AO_3F7D93_TODO ADD COLUMN USER_ID INTEGER
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - ALTER TABLE AO_3F7D93_TODO ADD CONSTRAINT fk_ao_3f7d93_todo_user_id FOREIGN KEY (USER_ID) REFERENCES AO_3F7D93_USER(ID)
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - CREATE INDEX index_ao_3f7d93_todo_user_id ON AO_3F7D93_TODO(USER_ID)
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - SELECT * FROM AO_3F7D93_TODO
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - SELECT ID FROM AO_3F7D93_USER WHERE NAME = ?
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - INSERT INTO AO_3F7D93_USER (NAME) VALUES (?)
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - UPDATE AO_3F7D93_TODO SET USER_ID = ? WHERE ID = ?
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - SELECT ID FROM AO_3F7D93_USER WHERE NAME = ?
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - UPDATE AO_3F7D93_TODO SET USER_ID = ? WHERE ID = ?
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - SELECT ID FROM AO_3F7D93_USER WHERE NAME = ?
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - INSERT INTO AO_3F7D93_USER (NAME) VALUES (?)
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - UPDATE AO_3F7D93_TODO SET USER_ID = ? WHERE ID = ?
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - SELECT ID FROM AO_3F7D93_USER WHERE NAME = ?
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - UPDATE AO_3F7D93_TODO SET USER_ID = ? WHERE ID = ?
[INFO] [talledLocalContainer] INFO - assian.activeobjects.internal.ActiveObjectUpgradeManagerImpl - Finished upgrading, model is up to date at version 2
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - ALTER TABLE AO_3F7D93_TODO DROP COLUMN USER_NAME
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - ALTER TABLE AO_3F7D93_TODO DROP CONSTRAINT fk_ao_3f7d93_todo_user_id
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - ALTER TABLE AO_3F7D93_TODO ALTER COLUMN USER_ID INTEGER NOT NULL
[INFO] [talledLocalContainer] DEBUG - net.java.ao.sql - ALTER TABLE AO_3F7D93_TODO ADD CONSTRAINT fk_ao_3f7d93_todo_user_id FOREIGN KEY (USER_ID) REFERENCES AO_3F7D93_USER(ID)

最后几行可以看出,在完成升级任务之后,数据库的表结构也变了,user_name字段被移除

jira ao UpgradeTask的更多相关文章

  1. jira的插件开发流程实践

    怎么开头呢,由于自己比较懒,博客一直不怎么弄,以后克己一点,多传点自己遇到的问题和经历上来,供自己以后记忆,也供需要的小伙伴少走点弯路吧 最近公司项目需要竞标一个运维项目,甲方给予了既定的几种比较常用 ...

  2. JIRA FOR LINUX 安装过程

    1.Download 官网下载地址:https://www.atlassian.com/software/jira/download,只看到window下的安装版本,这个时候需要点击? All JIR ...

  3. AO安装需要Microsoft Visual Studio 2013?

    从接触ArcGIS9.2到 10.4,在不断升级的 过程中,既给我们带来了很多惊喜,也带来一些麻烦,因为ArcGIS版本不兼容.出于体验,安装了ArcGIS Desktop10.4,AO也得升到10. ...

  4. 敏捷开发与jira之研发管理模式

    以IPD方法论为基础,采用原型+迭代的开发模式,并以质量优先为原则,持续对用户做价值交付. 使用JIRA+WIKI+SVN管理整个的研发过程:JIRA管理任务和进度:SVN管理代码和过程文档:WIKI ...

  5. 敏捷开发与jira之阶段工作项概述

    每次迭代都分这5个阶段,但每个阶段的时间根据版本情况定,最终目标是:第一个阶段拿到交付范围,在第五个阶段都完成,并拿到本次版本团队所消耗的工时. Jira是项目过程管理的一种手段,跟多体现在工时跟踪, ...

  6. 敏捷开发与jira之流程

    敏捷流程在Jira中的运用

  7. 敏捷开发与jira

    项目背景 项目是基于一套公司自主研发的平台做企业信息化的项目管理业务,经过两个里程碑的交付,已经在客户现场使用,每次版本都能按期交付,延迟较少,客户满意度也高. 项目开发过程采用的敏捷的方法,用类Sc ...

  8. jira任务批量操作示例

    1. 获取jira任务编号 使用字段提取工具获取编号,如WQBNEWSDLDL-347,WQBNEWSDLDL-348: 字段提取正则表达式:(?<2>[\[[](?<1>[A ...

  9. jira 6.3.6安装-汉化-破解

    jira是是一个国外的项目管理软件,收费的,至于功能什么的这里就不具体说了,大家可以网上查看有很多描述的 首先你要在JIRA官网注册一个账户,可以有30天的试用期,网上很多教程是让你去网上搜一个密钥, ...

随机推荐

  1. 顺序表的C、C++实现

    一个线性表表实现,函数声明放在 line_list.h 头文件汇总,函数定义放在line_list.c 中,main.c 用来测试各个函数. 1.文件 line_list.h // line_list ...

  2. FuelPHP 系列(四) ------ Validate 验证

    一.可用规则: 1.required 不能为 null, false or empty string.: 2.required_with 关联某个字段,关联字段有值则该字段必须有值: 3.match_ ...

  3. Java线程池停止空闲线程是否有规则呢?

    Java线程池中线程的数量超过核心线程的数量,且所有线程空闲,空闲时间超过keepAliveTime,会停止超过核心线程数量的线程,那么会保留哪些线程呢?是不是有规则呢? 测试代码: ThreadPo ...

  4. letsencrypt续期 最简单的续期方法更新证书

    Let's Encrypt申请的证书会有三个月的有效期,如何更方便的续期呢? 关于证书续期: 所谓letsencrypt续期,续期相当于重新申请一次证书,然后在服务器端将过期的证书替换掉即可.由于这个 ...

  5. Magical Girl Haze 南京网络赛2018

    题意: 就是使不大于k条路的权值变为零后求最短路 解析: d[i][j]表示使j条路变为权值后从起点到点i的最短路径 这题不能用spfa做  tle #include <iostream> ...

  6. 【刷题】LOJ 6226 「网络流 24 题」骑士共存问题

    题目描述 在一个 \(\text{n} \times \text{n}\) 个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的 \(\t ...

  7. 【题解】 Codeforces 919F A Game With Numbers(拓扑排序+博弈论+哈希)

    懒得复制,戳我戳我 Solution: 我感觉我也说不太好,看Awson的题解吧. 说一点之前打错的地方: 连边存的是hash后的数组下标 if(ans[ num( C[a.hash()] , C[b ...

  8. 【bzoj3132】 Sdoi2013—森林

    http://www.lydsy.com/JudgeOnline/problem.php?id=3123 (题目链接) 题意 给出$n$个点的森林,每个点有一个非负点权,$m$个操作.连接两个点,查询 ...

  9. 【bzoj2961】 共点圆

    http://www.lydsy.com/JudgeOnline/problem.php?id=2961 (题目链接) 题意 按照一定的顺序给出一些圆和一些点,对于每一个点问是否在所有圆内. Solu ...

  10. 解题:THUWC 2017 在美妙的数学王国中畅游

    题面 _“数字和数学规律主宰着这个世界.”_ 在 @i207M 帮助下折腾了半天终于搞懂了导数和泰勒展开,引用某学长在考场上的感受:感觉整个人都泰勒展开了 显然是个奇奇怪怪的东西套上LCT,发现直接维 ...