在hibernate中实现oracle的自动增长

本文介绍在Oracle数据库中使用Hibernate实现主键自增的两种方法:通过Sequence直接生成及使用触发器配合全局Sequence生成。

关键字: hibernate oracle sequence native 
根据hibernate的文档,有两种方式实现实体对象的主键自动增长。 
第一种:设置ID的增长策略是sequence,同时指定sequence的名字,最好每个表建一个sequence,此种做法就如同MS-SQL,MY-SQL中的自动增长一样,不需要创建触发器,具体的oracle数据库脚本及hibernate配置文件如下: 


[1]oracle数据表的创建脚本: 
Java代码

CREATE TABLE DEPARTMENT (   
    ID NUMBER(19,0) DEFAULT '0' NOT NULL,   
    NAME VARCHAR2(255) NOT NULL,   
    DESCRIPTION CLOB   
);   
ALTER TABLE DEPARTMENT ADD CONSTRAINT PRIMARY_0 PRIMARY KEY(ID) ENABLE;   
ALTER TABLE DEPARTMENT ADD CONSTRAINT UK_DEPARTMENT_1 UNIQUE (NAME);   
  
CREATE SEQUENCE DEPARTMENT_ID_SEQ MINVALUE 10000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;  

创建DEPARTMENT表,并为DEPARTMENT表创建一个单独的SEQUENCE,名字为SEQUENCE_ID_SEQ,并不需要创建触发器。 

[2]hibernate映射文件的配置: 
Java代码 

<?xml version="1.0"?>   
<!DOCTYPE hibernate-mapping PUBLIC   
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">   
<hibernate-mapping package="com.liyanframework.demo.domain">   
    <class name="Department" table="DEPARTMENT">   
        <id name="id" column="ID">   
            <generator class="sequence">   
                <param name="sequence">DEPARTMENT_ID_SEQ</param>   
            </generator>   
        </id>   
        <property name="name" column="NAME" type="string" />   
        <property name="description" column="DESCRIPTION" type="text" />   
    </class>   
</hibernate-mapping>  

在hibernate映射文件中,对ID的生成策略选择sequence,指定sequence的名字DEPARTMENT_ID_SEQ就可以了,当你 保存新对象的时候,hibernate会自动取得DEPARTMENT_ID_SEQ.NEXTVAL作为新对象的ID保存到数据库,所以不需要再使用触 发器再来生成新记录的ID。 


第二种:设置ID的增长策略是native,但是需要创建一个名字为hibernate_sequence(这个名字好像是hibernate默认的 sequence名字,不创建会出错的)的全局使用的sequence,然后再对每一个表的ID生成的时候,使用触发器,取得 hibernate_sequence.CURRVAL作为新记录的ID,具体的oracle数据库脚本及hibernate配置文件如下: 


[1]oracle数据表的创建脚本: 
Java代码 


CREATE TABLE STAFF (   
    ID NUMBER(19,0) DEFAULT '0' NOT NULL,   
    NAME VARCHAR2(255) NOT NULL,   
    AGE NUMBER(3,0) NOT NULL,   
    BIRTHDAY DATE NOT NULL,   
    SALARY NUMBER(10,2) NOT NULL,   
    LEVELNESS FLOAT NOT NULL,   
    CREATETIME TIMESTAMP NOT NULL,   
    ENABLE CHAR(2) DEFAULT 'Y' NOT NULL,   
    STATUS VARCHAR2(64) NOT NULL,   
    DEPARTMENT_ID NUMBER(19,0)   
);   
ALTER TABLE STAFF ADD CONSTRAINT PRIMARY_1 PRIMARY KEY(ID) ENABLE;   
ALTER TABLE STAFF ADD CONSTRAINT STAFF_IBFK_0 FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(ID) ENABLE;   
ALTER TABLE STAFF ADD CONSTRAINT UK_STAFF_1 UNIQUE (NAME);   
CREATE INDEX IDX_STAFF_STATUS ON STAFF(STATUS);   
  
CREATE SEQUENCE HIBERNATE_SEQUENCE MINVALUE 90000 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE;   
  
CREATE OR REPLACE TRIGGER STAFF_ID_TRG BEFORE INSERT ON STAFF   
FOR EACH ROW   
BEGIN   
    IF INSERTING AND :NEW.ID IS NULL THEN   
        SELECT HIBERNATE_SEQUENCE.CURRVAL INTO :NEW.ID FROM DUAL;   
    END IF;   
END;  

创建STAFF表,但是并没有为STAFF创建相应的主键sequence,而是创建了一个名字为HIBERNATE_SEQUENCE的 sequence,然后创建一个触发器STAFF_ID_TRG,当执行INSERT操作时,hibernate会先执行一次 HIBERNATE_SEQUENCE.NEXTVAL,所以在触发器中只需要取得HIBERNATE_SEQUENCE.CURRVAL作为新记录的 ID。 

[2]hibernate映射文件的配置: 
Java代码 


<?xml version="1.0"?>   
<!DOCTYPE hibernate-mapping PUBLIC   
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">   
<hibernate-mapping package="com.liyanframework.demo.domain">   
    <class name="Staff" table="STAFF">   
        <id name="id" column="ID">   
            <generator class="native" />   
        </id>   
        <property name="name" column="NAME" type="string" />   
        <property name="age" column="AGE" type="integer" />   
        <property name="birthday" column="BIRTHDAY" type="date" />   
        <property name="salary" column="SALARY" type="big_decimal" />   
        <property name="level" column="LEVELNESS" type="float" />   
        <property name="createTime" column="CREATETIME" type="timestamp" />   
        <property name="enable" column="ENABLE" type="character" />   
        <property name="status" column="STATUS" type="string" />   
        <many-to-one name="department" column="DEPARTMENT_ID" class="Department" />   
    </class>   
</hibernate-mapping>  

在hibernate映射文件中,对ID的生成策略选择native,hibernate会根据你数据库的触发器来生成新记录的ID。 

比 较两种做法,第二种做法也就是hibernate在代码中,实现了oracle中的触发器功能。对于不同的情况,选择不懂的做法。如果新的系统,新建的 oracle数据库,推荐使用第一种做法,简单,容易移植到其他支持自动增长的数据库;如果是老的系统,需要把其他数据库转换为oracle的,那就要用 第二种了,使用native的方式,可以不改动配置文件,兼容oracle和mysql之类带有自动增长的数据库。




安装有oracle数据库,创建数据库,总是要创建一个主键ID,唯一标示各条记录,但oracle不支持自动编号,所以还得创建一个SEQUENCE(序列)语句如
    
create sequence bign nocycle maxvalue 9999999999 start with1;//增加数据

insertintotable (ID,..) values(bign.nextval,..)

     在hibernate中的映射文件可这么写
   <id name="id" type="java.lang.Long" column="ID">
            
<generator class="sequence">
                 
<param name="sequence">bign</param>
            
</generator>
   
</id>



<id name="id" type="java.lang.Long" column="ID">
            
<generator class="increment">
  
</id>


(increment 用与为long,short或者int类型生成唯一标示。只有在没有其他进程忘同一张表中插入数据时才能使用。在集群下不要使用)

欧姆龙FINS(工厂集成网络系统)协议是专为该公司自动化设备间数据交互而设计的网络通信标准。该协议构建于TCP/IP基础之上,允许用户借助常规网络接口执行远程监控、程序编写及信息传输任务。本文档所附的“欧ronFins.zip”压缩包提供了基于C与C++语言开发的FINS协议实现代码库,旨在协助开发人员便捷地建立与欧姆龙可编程逻辑控制器的通信连接。 FINS协议的消息框架由指令头部、地址字段、操作代码及数据区段构成。指令头部用于声明消息类别与长度信息;地址字段明确目标设备所处的网络位置与节点标识;操作代码定义了具体的通信行为,例如数据读取、写入或控制器指令执行;数据区段则承载实际交互的信息内容。 在采用C或C++语言实施FINS协议时,需重点关注以下技术环节: 1. **网络参数设置**:建立与欧姆龙可编程逻辑控制器的通信前,必须获取控制器的网络地址、子网划分参数及路由网关地址,这些配置信息通常记载于设备技术手册或系统设置界面。 2. **通信链路建立**:通过套接字编程技术创建TCP连接至控制器。该过程涉及初始化套接字实例、绑定本地通信端口,并向控制器网络地址发起连接请求。 3. **协议报文构建**:依据操作代码与目标功能构造符合规范的FINS协议数据单元。例如执行输入寄存器读取操作时,需准确配置对应的操作代码与存储器地址参数。 4. **数据格式转换**:协议通信过程中需进行二进制数据的编码与解码处理,包括将控制器的位状态信息或数值参数转换为字节序列进行传输,并在接收端执行逆向解析。 5. **异常状况处理**:完善应对通信过程中可能出现的各类异常情况,包括连接建立失败、响应超时及错误状态码返回等问题的处理机制。 6. **数据传输管理**:运用数据发送与接收函数完成信息交换。需注意FINS协议可能涉及数据包的分割传输与重组机制,因单个协议报文可能被拆分为多个TCP数据段进行传送。 7. **响应信息解析**:接收到控制器返回的数据后,需对FINS响应报文进行结构化解析,以确认操作执行状态并提取有效返回数据。 在代码资源包中,通常包含以下组成部分:展示连接建立与数据读写操作的示范程序;实现协议报文构建、传输接收及解析功能的源代码文件;说明库函数调用方式与接口规范的指导文档;用于验证功能完整性的测试案例。开发人员可通过研究这些材料掌握如何将FINS协议集成至实际项目中,从而实现与欧姆龙可编程逻辑控制器的高效可靠通信。在工程实践中,还需综合考虑网络环境稳定性、通信速率优化及故障恢复机制等要素,以确保整个控制系统的持续可靠运行。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值