设为首页 收藏本站
查看: 1275|回复: 0

[Cloudstack] Apache Cloudstack Development 101

[复制链接]

尚未签到

发表于 2015-4-18 09:00:50 | 显示全部楼层 |阅读模式
  刚接触CloudStack,也是第一次翻译英文文档,限于水平有限,不当之处欢迎拍砖!
  原文地址:https://cwiki.apache.org/confluence/display/CloudStack/Data+Access+Layer
  读前必知
  关于CloudStack的数据访问层要知道三件事:
  第一:CloudStack的数据访问层以位于cloud-engine-schema中的VO来表示,底层的数据库只是schema的一个实现。这意味着一个VO可能是一张表的一部分,也可能是联合了多张表。位于VO上层的软件不需要关注这点,对其而言,schema就是VO。
  第二:CloudStack的数据访问层使用JPA。因此,任何类型的ORM,比如Hibernate使用会有一些麻烦。事实上,对于任何类型的API访问schema,我们推荐使用像Hibernate这样的ORM框架。然而,在跃跃欲试之前,还请先阅读完本章节的所有部分。
  第三:目前cloud-engine-schema中的VO集不应用于API访问。这个VO集是CloudStack关系的标准视图。它被用于CloudStack的作业处理引擎。通过API访问时,CloudStack schema要更具描述性。比如说,VM VO包含账号数据库id,但是VM Resource/Response应包含账号名称和uuid而不包含数据库id。因此VO不等于Resource/Response。在cloud-server创建数据库视图以定义CloudStack Resource/Response,但不是完整的,不包含所有的CloudStack Resource/Response。
  在哪里寻找例子?
  鉴于上述,我们很自然的想到在哪里能找到怎样去增加数据库读取CloudStack的例子。


  • 如果你正在编写cloud-engine核心代码或者子系统插件代码(如Nicira),需要存取数据库,那就用位于cloud-engine-schema工程的VO和DAO。
  • 如果你在编写API访问的代码,而且不涉及orchestration和提供硬件资源,那就用位于cloud-server工程的VO和DAO,特别是以JoinVO结尾的。如果你能将这些JoinVO转换为用通用的ORM实现,以便JPQL能用于生成更复杂的查询,那就更好。我期待谁能在这一块做出贡献。
  DAO
  CloudStack选择用DAO实现它的数据访问层,是因为CloudStack的核心是一系列的作业处理引擎,需要直接读取schema。CloudStack也希望实现以下数据库使用模式:


  • 当一个类实体第一次从CloudStack删除时,除非admin在数据库运行expunge 进程,否则它不会从数据库删除。这样在出现错误时更容易恢复。它还可以用来遵守数据保留策略。然而,当一个实体被删除后,该实体对业务逻辑是不可见的。当VO中的字段带有@Column(name=GenericDao.REMOVED_COLUMN)注解时,就会按这种模式执行。当出现这种情况时,DAO层自动将删除操作改为通过时间戳更新被删除列,但是所有的查询操作不会返回被删除列的数据集。
  • 当一个类实体第一次在CloudStack创建时,为了审计而创建时应当被记录。对于更健壮的审计机制,这是在业务逻辑中实现的失败安全策略。通过这些信息,作为最后一种手段,管理员能查看创建时的CloudStack日志推断出可能发生了什么。当VO中的字段带有@Column(name=GenericDao.CREATE_COLUMN)注解时,就会执行这种模式。当出现这种情况时,DAO层自动往列里插入时间戳。我们不需要依靠业务逻辑来记得要填写这些信息。
  • 执行对象映射而不是关系映射。作为大多数ORM实现的一部分的关系映射的问题是,开发者很容易通过@OneToMany注解和饥渴抓取将全部数据库读入内存。因此DAO不支持@OneToMany和@FetchType注解。
  • 独立SQL从数据库连接生成。DAO不管理数据库连接,也不管理将要连接的数据库,而是由业务逻辑管理。这易于支持数据库复制和分区策略。
  • 不支持嵌套事务。
  • 自动释放Connection、PreparedStatements和Results。
  • 自动回滚未提交事务。
  • 自动释放数据库锁。
  • 防止SQL注入攻击。
  CloudStack DAO层由四部分实现:


  • GenericDao和GenericDaoBase提供一组方法供使用。
  • @DB annotation 和TransactionContextBuilder实现Connection, PreparedStatement和Results的自动释放。
  • Transaction 管理数据库连接和数据库事务。
  • SearchBuilder 创建基于VO的查询。
   编写新的VO和DAO
  



//如果需要,使用VO接口,注意在接口中没有set方法
//如果其它代码要用到VO,应该只提供接口,而且它只是只读的对象
public interface Test {
String getText();
String getCreated();
}

// VO....@Entity
@Table(name="test")
public class TestVO implements Test { //假定已设定接口
@Column(name="id")
private long id;
@Column(name="text")
String text;
@Column(name=GenericDao.CREATED_COLUMN)
@Temporal(value=TemporalType.TIMESTAMP)
private Date created;

// 注意移除的字段没有个getter和setter方法
// 由DAO设定和使用
// 如果需要,可以增加getter方法,但是setter方法是没意义的
@Column(name=GenericDao.REMOVED_COLUMN)
@Temporal(value=TemporalType.TIMESTAMP)
private Date removed;

public TestVO(String text) { // 常规构造方法
this.text = text;
}

protected TestVO() {  // 受保护的构造方法用于反射
    }
// getter和setter方法需遵守Java约定,即将get/set放在字段前面
public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}
// 假如你需要用到不使用标准前缀(getXXX或者isXXX)的getter方法,
// 需在方法上标注@Column(name="")注解
// 来指明该方法关联的是哪一列
@Column(name="text")
public String retrieveText() {
return text;
}

// 注意不需要创建setter方法,它有DAO代码自动创建
public Date getCreated() {
return created;
}
}

// DAO... (接口不需要时可略过)
public interface TestDao extends GenericDao {
}

// Impl...
@Local(value={HostDao.class}) // 如果已指定接口
public class TestDaoImpl extends GenericDaoBase implements GenericDao {
protected TestDaoImpl() {
}
}
  创建类似上面的文件,就可以使用继承自GenericDao 的方法,比如通过id查找行、执行查询、删除行等。如果这就满足你访问新的表,那你就真的不用再写其它代码。请注意类中的注释,总结如下:


  • 如果VO要被其它模块使用,则需声明一个接口,通过这个接口跟其它模块通信。
  • 接口不带任何setter方法,它只供其他模块使用,而不被修改。
  • getter和setter方法需遵从Java约定,将get/set置于字段名称前面。在你更新VO对象时,DAO代码由此找到被修改的字段。
  • 如果不打算给其它模块使用,没必要为DAO实现声明接口。我将在下面讨论一个这个的特殊用例。
  • 没必要为移除字段和创建字段提供setter方法,它会由DAO代码自动填充。
  • 对于移除字段和创建字段,必须使用在GenericDao中声明的变量。如果使用@Column(name="removed"),DAO会认为该字段你会更新。
  • 受保护的默认构造方法用来实例化类。
  DAO实现支持的注解
  (此表格请参见原文)
  用法
  使用DAO



public class Foo {
@Inject TestDao _testDao;  // 注入DAO,不要new
public String getText(long id) {
TestVO vo = _testDao.findById(id);  // findById由GenericDaoBase定义
return vo.getText();
}
}
  更新VO



public class Foo {
@Inject TestDao _testDao;
public void updateText(long id, String text) {
TestVO vo = _testDao.findById(id);
vo.setText(text);     // 调用set方法让DAO明白修改的哪个字段
        _testDao.update(vo);
}
}
  查找
  CloudStack提供两种类型的查询结构:SearchBuilder 和SearchCriteria。SearchBuilder 在编译和加载时构造查询语句。它相当于编写一个类似于“SELECT * FROM test WHERE text=?”的查询语句,“?”在运行时填充。这样会在编译和加载时检查全部构造,易于更早地发现错误。在运行时,SearchBuilder 生成SearchCriteria ,SearchCriteria 被用来填充“?”。SearchBuilder 在SQL查询时优先使用,因为通过上下文敏感的编辑器重构时,会自动更改SearchBuilder ,但不会更改SQL。



public class Foo {
@Inject TestDao _testDao;
protected SearchBuilder TestSearch;
public Foo() {
// SELECT * FROM test WHERE text=? AND created

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-58316-1-1.html 上篇帖子: 虚拟化平台cloudstack(5)——参考资料 下篇帖子: Using Eclipse With CloudStack
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表