'MS/C#'에 해당되는 글 24건

  1. 2015.02.13 NHibernate 설정 및 HBM Mapping(3)
  2. 2015.02.13 NHibernate 설정 및 HBM Mapping(2)
  3. 2015.02.12 NHibernate 설정 및 HBM Mapping(1)

NHibernate 설정 및 HBM Mapping(3)

|

Table의 Key가 다중일 경우 처리


Database Table : TbCodeIfLayout

COLUMN

TYPE

LENTH

 TcId(PK)

VARCHAR

12

 ItemSeq(PK)

NUMBER

4

 ItemName

VARCHAR

50

 DataType

VARCHAR

10

 DataLength

 NUMBER

3

 Remark

 VARCHAR

30

위와 같이 Pk가 2개 이상일 경우 정의 방법은 구별이 된다.

Model 부터 확인해 보자


model : TbCodeIfLayout.cs

public class TbCodeIfLayout
    {
        public virtual TbCodeIfLayoutKey id { get; set; }
        public virtual string ItemName { get; set; }
        public virtual string DataType { get; set; }
        public virtual int DataLength { get; set; }
        public virtual string Remark { get; set; }
    }

    public class TbCodeIfLayoutKey
    {
        public virtual string TcId { get; set; }
        public virtual int ItemSeq { get; set; }

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            var t = obj as TbCodeIfLayoutKey;
            if (t == null) return false;
            if (TcId == t.TcId && ItemSeq == t.ItemSeq) return true;
            return false;
        }
        public override int GetHashCode()
        {
            return (TcId + "|" + ItemSeq + "|").GetHashCode();
        }
    }

보기와 같이 Pk가 여러개 일 경우 Pk로만 이루어진 Class를 따로 정의 해 준다.

이때 Equals와 GetHashCode를 oerride 해 주는데 이유는 NHibernate에서 Pk로 정의 된 항목이 어떤것인지 구별해 주기 위해서라고 한다.

즉 여러개 있을경우 필수적으로 override해 줘야 된다 이야기가 되겠다.


여기에 대응되는 mapper정의는

TbCodeIfLayout.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DBRepository" namespace="DBRepository.model">
  <class name="TbCodeIfLayout" table="TbCodeIfLayout">
    <composite-id name="id" class="TbCodeIfLayoutKey">
      <key-property name="TcId" column="TcId" type="string" length="12"/>
      <key-property name="ItemSeq" column="ItemSeq" type="Int32" length="4"/>
    </composite-id>
    <property name="ItemName" column="ItemName" type="string" length="50" not-null="true"/>
    <property name="DataType" column="DataType" type="string" length="10" not-null="true"/>
    <property name="DataLength" column="DataLength" type="Int32" length="3" not-null="true"/>
    <property name="Remark" column="Remark" type="string" length="30" not-null="true"/>
  </class>
</hibernate-mapping>

위와 같은형태로 composite-id tag로 따로 PK를 정의한 Class를 mapping 시켜 준다.

나머지 매핑은 앞장에서 설명한 내용과 같다.


And

NHibernate 설정 및 HBM Mapping(2)

|

Database Table : TbSrcMach

COLUMN

TYPE

SIZE

 MachTag(Pk)

Number

4

MachName

VARCHAR

5

MachCode

Number

3

위와 같은 DB Table 구성의 HBM mapping xml 구성시 필요한 model과 mapping은 아래와 같다.


TbSrcMach model

    public class TbSrcMach
    {
        public virtual int MachTag { get; set; }
        public virtual string MachName { get; set; }
        public virtual int MachCode { get; set; }
    }


TbSrcMach.hmb.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DBRepository" namespace="DBRepository.model">
  <class name="TbSrcMach" table="TbSrcMach">
    <id name="MachTag" column="MachTag" type="Int32" length="4">
      <generator class="native"/>
    </id>
    <property name="MachName" column="MachName" type="string" length="15" not-null="true"/>
    <property name="MachCode" column="MachCode" type="Int32" length="3" not-null="true"/>
  </class>
</hibernate-mapping> 


TbSrcMach model의 namespace는 "Assembly.path" 형식으로 구성되며 model의 Class와 Table을 mapping 하기 위한 xml은 위와 같이 구성 하였다.

class name 항목은 model의 Class를 지정해 주며 Table은 DB Table명을 기입해 준다.

id는 하나의 키를 갖는 Table일경우 사용하며 다중키를 가질경우 composite-id Tag를 이용하여 정의 한다.


이제 Data를 조회할 Repository Pattern Class를 정의한다.

TbSrcMachRepository.cs


public class TbSrcMachRepository : NHibernateRepository<TbSrcMach>
    {
        public IList<TbSrcMach> GetMachForName(string Name)
        {
            using(var transaction = session.BeginTransaction())
            {
                //IList<TbSrcMach> rtnVal = session.CreateQuery("from TbSrcMach where MachName = :MachName ").SetParameter("MachName", Name).List<TbSrcMach>();
                //IList<TbSrcMach> rtnVal = session.CreateCriteria<TbSrcMach>().Add(Restrictions.Eq("MachName", Name)).List<TbSrcMach>();
                var query = session.QueryOver<TbSrcMach>();
                query.Where(d => d.MachName == Name);
                return query.List<TbSrcMach>();
            }
        }
    }

위 정의한 Class의 주석 CreateQuery, CreateCriteria Method는 그 밑에 정의한 QueryOver와 같은 기능을 한다.

QueryOver일 경우 MagicString을 제거하여 온전한 Code Type을 제공하여 준다.

And

NHibernate 설정 및 HBM Mapping(1)

|

NHibernate Download : http://nhibernate.info/


기본 Layout

conf -> Oracle.cfg.xml : oracle DB 접속 정의

mapper -> HBM : xml을 이용한 mapping file

model -> HBM : xml과 mapping될 정의 Class

Repository : DB Query 및 DML, DCL 정의








대략 이런 형식의 구조를 갖고 내용정리를 진행 하겠다.


Oracle.cfg.xml

<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
  <session-factory>
    <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
    <property name="connection.connection_string">
      DB Connection String(ex: User ID=id;Password=pwdData Source=source)
    </property>
    <property name="show_sql">false</property>
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <mapping assembly="DBRepository"/>
  </session-factory>
</hibernate-configuration>

xml은 빌드 작업을 리소스 포함으로 한다.



SessinManager Singleton patten

using NHibernate;
using NHibernate.Cfg;


public class SessionManager
 {
        static SessionManager m_currentInstance;
        static ISessionFactory m_sessionFactory;

        public static SessionManager currentInstance
        {
            get
            {
                if(m_currentInstance == null)
                {
                    object sync = new object();
                    lock(sync)
                    {
                        m_currentInstance = new SessionManager();
                    }
                }
                return m_currentInstance;
            }
        }
        public ISession session
        {
            get
            {
                if(m_sessionFactory == null)
                {
                    object sync = new object();
                    lock(sync)
                    {
                        m_sessionFactory = new Configuration().Configure(GetType().Assembly, "DBRepository.conf.Oracle.cfg.xml").BuildSessionFactory();
                    }
                }
                return m_sessionFactory.OpenSession();
            }
        }
        private SessionManager() { }

}

Configure시 리소스 포함으로 xml을 설정 했으므로 설정 xml 경로는 "DBRepository.conf.Oracle.cfg.xml"형태

"namespace.file명" 정도로 정의 가능 하겠다.


Repository pattern의 Interface 정의(제네릭을 사용한다)

public interface IRepository<T>
    {
        T Get(object id);
        void Save(T value);
        void Update(T value);
        void Delete(T value);
        IList<T> GetAll();
    } 


NHibernateRepository pattern 구현

public class NHibernateRepository<T> :IRepository<T> where T :class
    {
        protected readonly ISession session = SessionManager.currentInstance.session;
        public T Get(object id)
        {
            using (var transaction = session.BeginTransaction())
            {
                T returnVal = session.Get<T>(id);
                transaction.Commit();
                return returnVal;
            }
        }
        public void Save(T value)
        {
            using (var transaction = session.BeginTransaction())
            {
                session.Save(value);
                transaction.Commit();
            }
        }
        public void Update(T value)
        {
            using (var transaction = session.BeginTransaction())
            {
                session.Update(value);
                transaction.Commit();
            }
        }
        public void Delete(T value)
        {
            using (var transaction = session.BeginTransaction())
            {
                session.Delete(value);
                transaction.Commit();
            }
        }
        public IList<T> GetAll()
        {
            using (var transaction = session.BeginTransaction())
            {
                IList<T> returnVal = session.CreateCriteria<T>().List<T>();
                transaction.Commit();
                return returnVal;
            }
        }
    }

Repository Interface를 상속 받아 제네릭형식으로 구현한다. 제네릭 형식은 class형으로 제한한다.

위와 같이 정의하여 나머지 Data를 조회할 Repository Class는 NHibernateRepository를 상속받아 사용하기 때문에

메소드 구현부의 session open을 따로 하지 않아도 되겠다.

허나 Transaction이 있을 경우 Session의 Transaction을 가져와 Commit 또는 Rollback을 구현하는 형식으로 진행 한다.



And
prev | 1 | 2 | 3 | 4 | ··· | 8 | next