composite key
Posted 尘埃未定
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了composite key相关的知识,希望对你有一定的参考价值。
CompositeKey的实现
CompositeKey主键的实现。数据库中的一个表如果是组合主键,那么在使用
NHibernate是会有一点麻烦,不说了,用代码例子说话:
1:准备工作,在Oracle中建立表结构,下面的建表的SQL语句(可以利用Toad For
Oracle)
CREATE TABLE ROBOT_TRACKING
(
LUNGUID VARCHAR2(9 BYTE) NOT NULL,
POS VARCHAR2(2 BYTE) NOT NULL,
ACT VARCHAR2(2 BYTE) NOT NULL,
TIMESTAMPS DATE NOT NULL,
TOC DATE DEFAULT sysdate
);
CREATE UNIQUE INDEX ROBOT_TRACKING_PK ON ROBOT_TRACKING
(LUNGUID, ACT);
ALTER TABLE ROBOT_TRACKING ADD (
CONSTRAINT ROBOT_TRACKING_PK
PRIMARY KEY
(LUNGUID, ACT)
USING INDEX )
2:准备数据表对象的数据实体,这一步是关键。还是用代码说话:
using System;
using System.Collections.Generic;
using System.Collections;
namespace OKEC.Sample.NHibernate.NHibernateTest
{
public partial class RobotTracking
{
public override bool Equals(object obj)
{
if ((obj == this))
{
return true;
}
if (((obj == null)
|| (obj.GetType() != this.GetType())))
{
return false;
}
RobotTracking test = obj as RobotTracking;
return (Id.Equals(test.Id));
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
private System.DateTime _tIMESTAMPS;
private System.DateTime _tOC;
public RobotTracking()
{
this._idPK = new RobotTrackingPK();
}
public RobotTracking(string lunguid, string act)
{
this._idPK = new RobotTrackingPK();
this._idPK.LUNGUID = lunguid;
this._idPK .ACT = act;
this.lunguId = lunguid;
this.act = act;
}
private string _pOS;
private string lunguId;
private string act;
public string ACT
{
get
{
return act;
}
set
{
this.Id.ACT = value;
act = value;
}
}
public override string ToString()
{
return string.Format("RobotTracking:{0} {1} {2} {3}
{4}",lunguId,act,_pOS ,_tIMESTAMPS ,_tOC );
}
public string LUNGUID
{
get
{
return lunguId;
}
set
{
this.Id.LUNGUID = value;
lunguId = value;
}
}
private RobotTrackingPK _idPK;
public virtual System.DateTime TIMESTAMPS
{
get
{
return this._tIMESTAMPS;
}
set
{
this._tIMESTAMPS = value;
}
}
public virtual System.DateTime TOC
{
get
{
return this._tOC;
}
set
{
this._tOC = value;
}
}
public virtual string POS
{
get
{
return this._pOS;
}
set
{
this._pOS = value;
}
}
public virtual RobotTrackingPK Id
{
get
{
return this._idPK;
}
set
{
this._idPK = value;
}
}
[Serializable]
public partial class RobotTrackingPK
{
private string _aCT;
private string _lUNGUID;
public virtual string ACT
{
get
{
return this._aCT;
}
set
{
this._aCT = value;
}
}
public virtual string LUNGUID
{
get
{
return this._lUNGUID;
}
set
{
this._lUNGUID = value;
}
}
public override string ToString()
{
return String.Join(":", new string[] {
this._aCT.ToString(),
this._lUNGUID.ToString()});
}
public override bool Equals(object obj)
{
if ((obj == this))
{
return true;
}
if (((obj == null)
|| (obj.GetType() != this.GetType())))
{
return false;
}
RobotTrackingPK test = ((RobotTrackingPK)(obj));
return (((_aCT == test._aCT)
|| ((_aCT != null)
&& _aCT.Equals(test._aCT)))
&& ((_lUNGUID == test._lUNGUID)
|| ((_lUNGUID != null)
&& _lUNGUID.Equals(test._lUNGUID))));
}
public override int GetHashCode()
{
return XorHelper(_aCT.GetHashCode(), _lUNGUID.GetHashCode());
}
private int XorHelper(int left, int right)
{
return left ^ right;
}
}
}
}
对上面代码的一些说明:
将组合键设置为数据实体(也就是类RobotTracking)的内嵌类,这一步非常关键。我
试过,如果不是内嵌类的话,后面的代码就编译不了。例外实体类必须重载Equals()方法,
同时最好也重载GetHash()方法。还有一点需要指出的是组合键的类必须是[Serializable]属
性。建立好以后。
3:对表RobotTrakcing的配置文件(RobotTracking.hbm.xml)文件,这个文件可以通
过CodeSmith生成,但是需要说明的我从网上下载的CodeSmith的NHibernate模版生成的文件不
能直接使用,需要修改。下面是配置文件,继续用代码说话。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="OKEC.Sample.NHibernate.NHibernateTest.RobotTracking,NHibernateTest"
table="ROBOT_TRACKING" lazy="false">
<composite-id>
<key-property name="LUNGUID" type="String">
<column name="LUNGUID" length="9"/>
</key-property>
<key-property name="ACT" type="String">
<column name="ACT" length="2"/>
</key-property>
</composite-id>
<!--
<id name="Id" type="String" unsaved-value="null">
<column name="LUNGUID" length="9" sql-type="VARCHAR2" not-
null="true" index="ROBOT_TRACKING_PK"/>
<column name="ACT" length="2" sql-type="VARCHAR2" not-
null="true" index="ROBOT_TRACKING_PK"/>
<generator class="native" />
</id>
-->
<property name="POS" type="String">
<column name="POS" length="2" sql-type="VARCHAR2" not-
null="true"/>
</property>
<property name="TIMESTAMPS" type="DateTime">
<column name="TIMESTAMPS" sql-type="DATE" not-null="true"/>
</property>
<property name="TOC" type="DateTime">
<column name="TOC" sql-type="DATE" not-null="false"/>
</property>
</class>
</hibernate-mapping>
配置文件的关键点在与
<composite-id>
<key-property name="LUNGUID" type="String">
<column name="LUNGUID" length="9"/>
</key-property>
<key-property name="ACT" type="String">
<column name="ACT" length="2"/>
</key-property>
</composite-id>
数据库中的主键对应,和数据实体类中的RobotTrackingPK类的字段对应。
4:然后是整个使用NHibernate的配置,用代码说话:
<?xml version="1.0" encoding="utf-8"?>
<!--
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in
hibernate.cfg.xml and change it
for your own use before compile tests in VisualStudio.
-->
<!-- This is the System.Data.OracleClient.dll provider for Oracle from MS -->
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="NHibernate.Test">
<property
name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
<property name="connection.connection_string">
User ID=Soctt;Password=tiger;Data Source=localHost
</property>
<property name="show_sql">false</property>
<property
name="dialect">NHibernate.Dialect.OracleDialect</property>
<mapping assembly="NHibernateTest" />
</session-factory>
</hibernate-configuration>
准备好了上面的内容后,就可以开始使用了
需要在工程中引用下列DLL
Common.Logging.DLL
Common.Logging.Log4Net.DLL
logNet4.DLL
NHibernate.DLL
Iesi.Collections.DLL
用代码说话:
using System;
using System.Collections;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Expression;
namespace OKEC.Sample.NHibernate.NHibernateTest
{
class ClientApp
{
static void main(string[] args)
{
//得到NHibernate的配置
Configuration cfg = new Configuration();
cfg.Configure("Oracle.cfg.xml");
ISessionFactory factory = cfg.BuildSessionFactory
();
ISession session = factory.OpenSession();
ITransaction transaction =
session.BeginTransaction();
RobotTracking robotTracking ;
robotTracking = new RobotTracking(string.Concat("09060000",
i.ToString()), "US");
robotTracking.ACT = "US";
robotTracking.POS = "R2";
robotTracking.TIMESTAMPS = DateTime.Now;
robotTracking.TOC = DateTime.Now;
//判断对应的数据是否存在
object obj= session.Get(typeof(RobotTracking), robotTracking);
//不存在进行插入操作
if (obj == null)
session.Save(robotTracking);
//存在进行删除操作
else
session.Delete(robotTracking);
// commit all of the changes to the DB and
close the ISession
transaction.Commit();
session.Close();
// open another session to retrieve the just
inserted user
session = factory.OpenSession();
//查询操作
// IQuery query = session.CreateQuery("from RobotTracking where"+"
robotTracking.LUNGUID="+"090600005"+"");
string lunguid = "090600001";
string act="R3";
string where = " where lunguid >= ‘" + lunguid +"‘ and
act<>‘"+act+"‘" ;
IQuery query = session.CreateQuery("from RobotTracking "+where );
IList<RobotTracking> list = query.List<RobotTracking>();
foreach (RobotTracking tracking in list )
{
Console.WriteLine(tracking.ToString());
}
ICriteria creieria = session.CreateCriteria(typeof
(RobotTracking));
creieria.Add(Expression.Sql("LUNGUID >= ‘" + lunguid+"‘"));
creieria.Add(Expression.Sql(" ACT<>‘" + act+"‘"));
list = creieria.List<RobotTracking>();
foreach (RobotTracking tracking in list)
{
Console.WriteLine(tracking.ToString());
}
}
}
}
说明:上面的代码说明了Composite主键的一般用法,同时演示了插入,删除,以及两种不同方
式的查询操作。
补充一点,在插入TOC字段是,虽然数据库的默认值是Sysdate,如果没有robotTracking.TCo=
DateTime.Now这句,那么插入到数据中的值并不是我们期望的Sysdate。想知道具体是什么值的
话可以实际的试试。
以上是关于composite key的主要内容,如果未能解决你的问题,请参考以下文章
JEST @vue/composition-api + Jest 测试套件无法运行 [vue-composition-api] 在使用任何函数之前必须调用 Vue.use(VueComposition
Vue2使用setuprefreactive等Vue3的组合式@vue/composition-apivuex-composition-helpers