我的应用程序要求我为实体生成“面向客户的ID”。 ID必须唯一标识实体以供客户参考,但不能是DB中使用的主键。它也不能是一个连续的值,所以它更难预测。
我已经着手为我的实体创建ID字段的排列,我有那部分工作。我现在遇到的问题是我不确定在Hibernate中处理这个问题的最佳方法,因为在生成ID之前我无法生成排列。
我使用Oracle作为数据库,并使用序列生成ID。有没有办法在从序列中检索ID时捕获ID,创建我的排列,并在将实体插入数据库之前在实体上设置值?或者,我是否坚持保存实体,设置排列值,然后更新实体?
另外,我愿意就如何满足这些要求提出更好的建议吗?
答案 0 :(得分:0)
您可以在11g中使用虚拟列。首先,创建一个基本函数,根据您认为应该确定标识符的字段生成md5哈希:
create or replace function get_naddr_hash(i_string in varchar2, i_uppercase in number default 0)
return varchar2 deterministic
as
l_string varchar2(32767);
begin
l_string := substr(i_string, 1, 32767);
if (i_uppercase > 0) then
l_string := upper(l_string);
end if;
return rawtohex(
DBMS_CRYPTO.Hash (
UTL_I18N.STRING_TO_RAW (l_string, 'AL32UTF8'),
2)
);
end;
请注意,此函数要求已在db上设置dbms_crypto。
然后使用此函数创建(或通过ctas重新创建)具有虚拟列的表:
create table tst_tab
(
naddr_hash as (get_naddr_hash(trim(username)||trim(address1)||trim(city)||trim(state), 1)),
username varchar2(100) not null,
address1 varchar2(100) not null,
address2 varchar2(100),
city varchar2(100) not null,
state varchar2(2) not null,
zip varchar2(9),
phone varchar2(20)
);
在这里,我认为用户名,地址1,城市,州将是确定字段。在这个设置之后,你应该很高兴。
insert into tst_tab
(
username, address1, address2, city, state, zip, phone
) values
(
'Joe Smith', '123 Main St', 'Ste 100', 'Denver', 'CO', '12345', '5551212'
);
insert into tst_tab
(
username, address1, address2, city, state
) values
(
'JOE SMITH', '123 Main St', 'Ste 101', 'Denver', 'CO'
);
这两个将具有相同的naddr_hash。以下将使用不同的哈希:
insert into tst_tab
(
username, address1, address2, city, state
) values
(
'JANE SMITH', '123 Main St', 'Ste 101', 'Denver', 'CO'
);
查看数据:
NADDR_HASH USERNAME
2ADCBCAC3A26ED5BD189351B84BFA412 Joe Smith
2ADCBCAC3A26ED5BD189351B84BFA412 JOE SMITH
C56D5007C89284892FDF03A96C5E15E0 JANE SMITH