在ADF实体PK属性中使用MySQL自动增量PK列

大家好。 继续进行ADF + MySQL解决方法系列,今天我们将看到要使用MySQL PK自动增量列和ADF实体PK属性来进行的工作。 如果使用的是Oracle数据库,则可以使用oracle.jbo.domain.DBSequence以及序列和触发器来立即进行操作。

为简单起见,我们将修改与Entity关联的Java文件,但作为一种好的做法,您应该拥有自己的oracle.jbo.server.EntityImpl类实现并配置JDeveloper,以便它对每个新的版本都使用自己的实现应用程序中的实体。 有关更多信息,请查看此帖子

这不是关于如何从表中创建ADF BC的分步教程,我们假设您已经具有业务组件定义。

你需要什么

这是我们将在本文中使用的数据库表:

CREATE  TABLE `test`.`Actor` (
  `id_actor` INT NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(100) NOT NULL ,
  PRIMARY KEY (`id_actor`) );

从表创建实体后,JDeveloper将针对表列映射Entity属性,并根据列的类型设置一些属性。 例如,对于我们的PK列(id_actor),JDeveloper会将属性设置为强制性 Integer并且始终可更新。 我们需要进行更改,因为我们希望我们的PK 在新的 (创建新实例时)是可更新的, 不是强制性的 (因为我们在发布到数据库后正在读取自动增量值):

ADFMySQL_EntityAtt_1

您的数据库中可能有几个表,因此您的ADF应用程序中有多个实体,但是并非所有的表都可能具有自动增量PK列,因此我们需要一种方法来标记或标识实体的PK属性何时来自数据库的自动增量列。 我们将使用Property Set来做到这一点,它允许我们定义键/值属性的集合,然后我们可以将这些属性关联到属性并在运行时访问它们:

  1. 在JDeveloper中,选择: File –> New –> From Gallery…
  2. ADF业务组件中,选择“ 属性集” PropertySet_1
  3. 设置新属性集的名称和包:
    PropertySet_2
  4. 创建之后,我们可以定义键/值属性集,如果要向用户显示这些属性,我们甚至可以以可翻译模式定义它们。 这不是我们的情况,因此我们将定义一个不可翻译的属性:
    PropertySet_3
  5. 将属性名称设置为AI (对于AutoIncrement),并将其值设置为true (因为使用此属性集的属性来自于autoincrement列):
    PropertySet_4
  6. 现在我们已经准备好属性集,可以在Entity PK属性中使用它:
    PropertySet_5

为了检索PK属性的autoincrement值,我们需要重写Entity类的默认实现(请记住,为简单起见,请执行此操作,但是您可以按照本文开头的介绍做得更好)。 我们可以通过为Entity实现Java类,然后重写EntityImpl.doDML(int,TransactionEvent)方法(将更改发布到数据库的方法来实现:

  1. 转到实体的Java部分,然后单击铅笔图标:

    Java_1

  2. 在弹出窗口中,选择Generate Entity Object Class: ...,然后单击OK:
    Java_2
  3. 现在,Entity类的Java部分显示Java文件,单击指向Java File名称的链接:
    Java_3
  4. JDeveloper将打开一个包含Java代码的新窗口。 复制并粘贴以下方法:
    ...
        @Override
        protected void doDML(int i, TransactionEvent transactionEvent) {
            //got to call first to super, so the record is posted 
            //and we can then ask for the last insert id
            super.doDML(i, transactionEvent);
    
            //after the record is inserted, we can ask for the last insert id
            if (i == DML_INSERT) {
                populateAutoincrementAtt();
            }
        }
    
        /*
        * Determines if the Entity PK is marked as an autoincrement col
        * and executes a MySQL function to retrieve the last insert id
        */
        private void populateAutoincrementAtt() {
            EntityDefImpl entdef = this.getEntityDef();
            AttributeDef pk = null;
            //look for primary key with Autoincrement property set
            for (AttributeDef att : entdef.getAttributeDefs()) {
                if (att.isPrimaryKey() && (att.getProperty("AI") != null 
                    && new Boolean(att.getProperty("AI").toString()))) {
                    pk = att;
                    break;
                }
            }
            if (pk != null) {
                try (PreparedStatement stmt = 
                     this.getDBTransaction()
                         .createPreparedStatement("SELECT last_insert_id()", 1)) {
                    stmt.execute();
                    try (ResultSet rs = stmt.getResultSet()) {
                        if (rs.next()) {
                            setAttribute(pk.getName(), rs.getInt(1));
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    ...

    上面的代码将更改发布到数据库,然后询问是否要插入值。 如果是这种情况,我们需要检索自动增量值并将其设置在我们的PK属性中。 有关获取自动增量值的更多信息,请参考MySQL函数LAST_INSERT_ID()

好的,让我们尝试一下我们的解决方案。 首先,运行您的应用程序模块:

RunAppModule_1

一旦出现Oracle ADF Model Tester工具,请选择(双击)左侧面板上的ActorView1视图对象,然后单击右侧面板上的绿色加号图标,以添加新的Actor:

RunAppModule_2

输入Actor的名称,然后按“将更改保存到数据库”按钮(带有工具栏上的清单图标的小数据库):

RunAppModule_4

您会注意到,自动增量值现已设置为
idActor属性!

无需担心并发插入,MySQL文档指出可以(请查看此文档 ):

同时使用多个客户端的LAST_INSERT_ID()和AUTO_INCREMENT列是完全有效的。 每个客户端将收到该客户端执行的最后一条语句的最后插入的ID。

再见!


翻译自: https://www.javacodegeeks.com/2013/11/using-mysql-autoincrement-pk-column-in-adf-entity-pk-attribute.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值