Archive

Archive for the ‘XML’ Category

NHibernate สะพานเชื่อมระหว่าง Object world และ Database world

January 10, 2011 2 comments

นักพัฒนาทั้งหลายครับ สวัสดีปีใหม่ครับหวังว่าปีนี้คงจะมีอะไรที่ ใหม่ ๆ กับชีวิตนะครับ เงินทองหลั่งไหล สุภาพแข็งแรงนะครับ นับว่าเป็นเวลานานมากแล้วที่ผมไม่ได้เข้ามาเขียนบทความเลย ปีใหม่นี้ก็หวังว่าจะเริ่มเขียนให้มากขึ้น อยากจะแบ่งปัน ความรู้ให้กับเพื่อน ๆ โปรแกรมเมอร์ทั้งหลาย นะครับ

เรื่องในวันนี้นับเป็นเรื่องแรกแห่งปีนี้ ครับ  อย่างที่ได้ขึ้นหัวไว้นะครับ  NHibernate ถือว่าเป็น นวัตกรรม ของการพัฒนาซอฟต์แวร์ แห่งปีก็ว่าได้นะครับ นักพัฒนาระบบอย่างเรา คงจะเข้าใจได้นะครับ ว่าระบบฐานข้อมูลส่วนใหญ่ที่เราใช้งานั้น จะเป็น relational database ซะส่วนใหญ่ และการพัฒนาระบบในภาษาใหม่นั้น เราก็จะเน้นการเขียน แบบ Object oriented  เมื่อเราทำงานในลักษณะ Object เราก็น่าจะสามารถมองเห็น ข้อมูลเป็น Object ด้วย แต่การ ทำ Data access Layer นั้น เป็นงานหนักทีเดียว ถ้าต้องการทำให้ การเขียนเป็น เชิง Object ทั้งหมด ทั้งนี้ผมกล่าวไปตามความเข้าใจ นะครับ และก็เข้าใจว่า NHibernate เป็นหนทางที่จะนำเราไปสู่การส้รางงานที่ง่ายขึ้น แต่จะเป็นอย่างไรนั้นคงจะต้องหาคำตอบ ไปด้วยกันนะครับ

คงจะต้องกล่าวถึง NHibernate ก่อนที่จะลองสัมผัส กันสักนิด นะครับ สำหรับ NHibernate นี่นั้นเขาเรียกกันว่า Object Relational Mapper (ORM) ทำหน้าที่ Map จาก Relational database มาเป็น Object ให้เราครับ ทำให้เราทำงานได้ง่ายขึ้นครับเพราะเราไม่ต้องไปงุ่มง่ามอยู่กับการเขียน Data access layer  ง่ายอย่างไรนั้นคงต้อง ค่อย ๆ ดูตามผมไปก็แล้วกันนะครับ เพราะผมเองก็อยากรู้มากเหมือนกัน

เอาเป็นว่าเราเรียนรู้ NHibernate ผ่านทางต้วอย่างที่ผมจะรวบรวมมา จากง่ายไปหาอยากและเอาไปใช้งานจริง ๆ นะครับ

เครื่องมือที่เราจะใช้ใน ตัวอย่างแรกนี้ก็คงจะเป็น

  • NHibernate version 2.1.2 ครับ load ตาม link นี้เลยครับ NHibernate-2.1.2.GA-bin
  • Visual studio 2008 Express, C#
  • SQL Server 2005 Express

ขั้นตอนการติดตั้ง NHibernate ก็ไม่ยากนะครับ ผมแตกออกแล้วเอาไว้ที่ c:\NHibernate-2.1.2 GA\ แล้ว ทำตามขั้นตอนต่อไปนี้นะครับ

ขั้นตอนที่ 1 :

  • สร้าง Project ชื่อ Lesson3 แล้วสร้าง form แล้ววาง datagrideview ไว้ บน form นั้น นะครับแล้วทิ้งไว้ก่อน
  • Add Reference -> NHibernate
    • Click ขวาที่ชื่อ Project เลือก Add Reference
    • Brows ไปยัง folder ที่แตกไว้แล้วเลือก NHibernate.dll ใน \Required_Bins
    • ทำอีกครั้ง เพื่อ Add    NHibernate.ByteCode.Castle.dll  ใน \Required_For_LazyLoading\Castle

ขั้นตอนที่ 2 :

  • Add new class -> company.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lesson3
{
 public class company
 {
 public company() { }

 public virtual string companyid { get; set; }
 public virtual string companyname { get; set; }
 public virtual string companyemail { get; set; }
 public virtual string companysize { get; set; }

 }
}
  • Add new XML ->    Set as Embedded Resource [company.hbm.xml]
  • สำคัญมากสำหรับ ไฟล์นี้ ต้องกำหนด properties ให้เป็น  embedded resource
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Lesson3" auto-import="true">
 <class name="Lesson3.company, Lesson3" table="company" lazy="true">
 <id name="companyid" type="string">
 <generator/>
 </id>
 <property name="companyname" type="string"/>
 <property name="companyemail" type="string"/>
 <property name="companysize" type="string"/>

 </class>

</hibernate-mapping>

ขั้นตอนที่ 3 :

  • config and Execute
    • Add using statment , เปิด form1 ที่เราวาง datagridview ไว้แล้วเพิ่ม using statement ตามนี้ครับ
...
using NHibernate;
using NHibernate.Cfg;
using NHibernate.ByteCode.Castle;
using System.Collections;

  • แล้ว เพิ่ม code ลงใน constructor ดังนี้
Configuration config = new Configuration();
ISessionFactory factory;

 config.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider");
 config.SetProperty(NHibernate.Cfg.Environment.Dialect, "NHibernate.Dialect.MsSql2005Dialect");
 config.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, "NHibernate.Driver.SqlClientDriver");
 config.SetProperty(NHibernate.Cfg.Environment.ConnectionString, @"Data Source=.\SQLEXPRESS;Initial Catalog=enterprise4;User ID=sa;Password=xxxx;Pooling=False");
 config.SetProperty(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, "NHibernate.ByteCode.Castle.ProxyFactoryFactory,NHibernate.ByteCode.Castle");

 config.AddAssembly(typeof(Lesson3.company).Assembly);

 factory = config.BuildSessionFactory();
 ISession session = null;
 try
 {
 session = factory.OpenSession();
 dataGridView1.DataSource = session.CreateCriteria(typeof(Lesson3.company)).List();
 }
 catch (Exception ex)
 {
 session.Close();
 MessageBox.Show(ex.Message);
 //throw;
 }

ลืมไปว่าท่านต้องทำการ สร้าง database ชื่อ enterprise4 โดยที่มี โครงส้รางข้อมูลดังนี้

CREATE TABLE [dbo].[company](
[companyid] [nchar](10) NOT NULL,
[companyname] [nchar](150) NULL,
[companyemail] [nchar](150) NULL,
[companysize] [nchar](10) NULL,
CONSTRAINT [PK_company] PRIMARY KEY CLUSTERED
(
[companyid] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

หลังจากนี้ก็ลอง compile แล้วrun ดูนะครับ จะได้ข้อมูลขึ้นมาแสดง ให้ท่านเห็น อ้อ แต่อย่าลืม ใส่ข้อมูลลงตารางซะก่อนนะครับ
จาก เห็นมั้ยครับ ว่ามันจัดการอะไรให้เราบ้างเราแค่เขียน แค่นี้เราก็สามารถที่จะแสดงข้อมูลจาก table ได้แล้ว ดังนั้น ต้องติดตามกันต่อไปนะครับว่า การทำ operation ต่าง ๆ กับข้อมูลทำได้อย่างไรบ้าง
เช่นการ insert update และการ delete ซึ่งจะเก็บไว้เป็นตอนต่อไป ครับ ถ้ามีอะไรที่ต้องการ ถามก่อนก็ ว่ากันไปตามนี้นะครับ s_teerapong2000@yahoo.com ครับ Bye…

XML Schema ความเข้าใจเกี่ยวกับ namespace

October 26, 2008 5 comments

จากข้อกำหนด ของ W3C  Namespace in recommendation  XML Namspeces คือกลุ่มขอล elements และ attributes ที่เป็นไปตามข้อกำหนด IRI – กลุ่มของ elements และ attributes เหล่านี้เราเรียกกว่า  XML vocabulary ครับ  สิ่งสำคัญเลยที่ทำให้ต้องมี Namespace ก็คือการหลีกเลี่ยง naming conflicts เมื่อมีการ สร้าง XML documents และมีการ เรียกใช้หลาย ๆ ที่ หรือ เรียกใช้ Vocabularies หลาย ๆ ที่  ตัวที่ต้องใช้งาน Namespace มาก ๆ ก็คือ XML schema ซึ่ง XML schema นี้เราใช้สำหรับการกำหนด vocabulary หรือ โครงสร้างของ XML ที่เราต้องการใช้งาน แฮะ แฮะ ไม่ทราบว่าจะ get หรือปล่าว  ( เราอาจจะต้องเข้าใจ XML schema และ ก็ concept ต่าง ๆ ด้วย )

Namespace ก็มีลักษณะคล้ายกับ packages ใน Java หรือ  namespace ใน C# ครับ

ครับก็คง พอจะอ้างอิงให้เห็น จากความคล้ายคลึงกันนะครับ นั่นก็เป็นเพียงการ กล่าวนำเข้าเรื่อง นะครับ ถ้าไม่เห็นตัวอย่างจากการใช้งานต่าง ๆ ก็คงยังไม่ ซึ่งใช่ไหมครับ ก็เราก็จะพูดถึง ในหัวข้อต่าง ดังนี้นะครับ

  • หน้าที่ ของ XML
  • การประกาศ ( declare ) และการใช้งาน namspaces
  • ความแตกต่างระหว่าง default-namespace และ no-namespace
  • การสร้าง Namespaces โดยใช่ XML schema และ
  • ความแตกต่างกันระหว่าง qualified และ unqualified element/attributes

การประกาศ และ การประยุกต์ใช้

Namespaces นั้นเราประกาศใน attribute ของ XML element ครับ  และก็ไม่จำเป็นว่าเราจะต้องประกาศ มันไว้ที่ root element มันสามารถที่จะประกาศไว้ใน element ใด ๆ ก็ได้ใน XML document. นั่นก็หมายความว่า มันต้องมี scope นะสิครับ  scope ของ namespace ก็ จะอยู่ภายใต้ที่ element ที่ namespace นั้นถูกประกาศครับ เริ่มตั้งแต่ opening-tag ไปจนถึง ending-tag ของ element

การประกาศ Namespace ทำดังนี้นะครับ

<someElement xmlns:pfx=”http://www.Teerapong.com”/&gt;

จากตัวอย่างจะเห็นว่า xmlns ก็คือ attribute ของ someElement นะครับ มันใช้สำหรับการ ประกาศ namespace ซึ่งชื่อของ namespace ก็คือ http://www.Teerapong.com  และ เจ้า xmlns นี้นอกจากจะประกาศ namespace แล้วยังก็หนด aliase หรือ prefix สำหรับการใช้งานอ้าง อิง namespace นี้ด้วย ฝรั่งเขาใช้คำว่า binding นะครับเวลาอ้างอิง namespace นี้ทีไหนก็ตาม ก็ใช้เฉพาะั ตัว alias หรือ prefix เท่านั้นนะครับ พอเข้าใจนะครับ อย่างเช่น เมื่อเราสร้าง XSD schema เราประกาศ แบบนี้

<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; .. />

หลังจากนี้เมื่อเราต้องอางอิง element หรือ types ต่าง ๆ เราก็ prefix ด้วย xsd ด้วยเสมอ แม่นบ่ครับ ไม่เช่นนั้นมันก็จะฟ้อง error ต่อว่าเราว่า ไม่มี element หรือ ไม่มี type ที่กำหนด ไว้ใน http://www.w3.org/2001/XMLSchema

อันที่จริงแล้ว prefix หรือ aliase นั้นเราจะกำหนดเป็นอะไรก็ได้นะครับ ผมรู้ว่ามีคำถามนี้อยู่ในใจ เราสามารถกำหนดให้เป็นอะไรก็ได้ตามใจท่านนะครับ แต่ก็ต้องไม่ลืมนะครับ ว่าต้องให้มันสื่อความหมายด้วยไม่เช่นนั้น ปัญหาผมร่วงจะมาสู่ท่านภายหลัง นะครับ software engineer เข้าเรียกว่า meaningful นะครับ

ยังมีอีก คำถาม หนึ่งมั้ง บางคนเข้าใจว่ามันจะต้องอ้างอิงไป URL หรือป่าวเห็นประกาศเป็น URL คำตอบก็คือไม่ใช่นะครับ เราจะกำหนดให้มันเป็นอะไรก็ได้ ไม่จำเป็นต้องเป็น URL ก็ได้ เนื่องจากว่า namespace นั้นใช้สำหรับการกำหนด virtual container สำหรับที่เราจะ group XML ไว้เป็นกลุ่ม ๆ ให้ง่ายต่อการอ้างอิงใช้งาน ครับ ที่เขา URL ก็เพราะว่ามันน่าจะ unique การที่จะมีการกำหนดซ้ำกันก็คงเกิดขึ้นได้น้อย ครับ

คุณอยากจะกำหนดแบบนี้ก็ได้

<someElement xmlns:pfx=”Teerapong” />

ซึ่งก็ไม่ได้ผิดกฏ หรือ ข้อกำหนดใด ๆ แต่ก็ควรให้เป็นไปตาม W3C Namespace in XML Recommendation ก็จะดี….

ครับถึงนี่แล้วก็คงจะพอเข้าใจนะครับ การใช้ namespace อันดับแรก เราจะ bind เข้ากับ aliase หรือ prefix เสร็จแล้วเวลาอ้างอิงเราก็ใช้ aliase หรือ prefix ในการอ้างอิง namespace ผมคิดว่าก็คงจะมีข้อสงสัยตามมาอีกว่าทำไมถึงไม่ใช้ namespace อ้างอิงตรง ๆ เลยหล่ะเหตุผล ก็คือ namespace ที่เรากำหนด ตาม recommendation นั้นมันจะยาวววว และที่สำคัญก็คือมันอาจจะส่งผลกระทบอัน ใหญ่หลวงกับ syntax ของ XML ก็ได้เพราะว่า มันจะมี characters ที่ไม่อนุญาตุให้ใช้ใน tags ไงครับ  🙂

<http://www.library.com:Book /> ผิด

<lib:Book xmlns:lib=”http://www.library.com”/&gt; ถูกต้อง

ดูตัวอย่าง เต็ม อีกนิด

<?xml version="1.0"?>
<Book xmlns:lib="http://www.library.com">
	<lib:Title> Sherlock Holmes</lib:Title>
	<lib:Author>Arthur Conan Doyle</lib:Author>
</Book>

อีกตัวอย่างนะครับ

<?xml version="1.0"?>
<Book xmlns:lib="http://www.library.com">
	<lib:Title>Sherlock Holmes - I</lib:Title>
	<lib:Author>Arthur Conan Doyle</lib:Author>
   <Purchase xmlns:lib="http://www.otherlibrary.com">
	<lib:Title>Sherlock Holmes - II</lib:Title>
	<lib:Author>Arthur Conan Doyle</lib:Author>
   </Purchase>
	<lib:Title>Sherlock Holmes - III</lib:Title>
	<lib:Author>Arthur Conan Doyle</lib:Author>
</Book>

ตัวอย่างนี้ จะให้เห็น ในเรื่อง scope นะครับ สังเกตุดูจะเห็นว่ามี 2 namespace ซึ่งประกาศใน Book และ purchase contentของทั้ง แม้จะกำหนด ให้มี prefix เหมือนกันก็ตาม content ของ purchase จะอ้างอิงกับ http://www.otherlibrary.com ส่วน content ของ Book จะ อ้างอิงไปยัง http://www.library.com ดังนั้น element  Title และ Author ของ Cherlock Holmes I กับ Title และ Author ของ Cherlock Holmes III จะอ้างอิงที่ namespace เดียวกัน 🙂

Default-namespace และ  No-namespace

บ้างครั้งการทำงานก็มักจะเกิเอาการขี้เกียจขึ้น บ้างท่านก็ไม่อยากจะพิมพ์ prefix หรือ aliase นำหน้า element หรือ attribute ทุกครั้ง ๆ  ในกรณีนี้ นะครับ เราสามารถที่จะใช้ default namespace แทนนะครับ แต่ต้องจำไว้นะครับ ว่าเราจะประกาศ default namespace ได้ที่ namespace เดียวนะครับ  ไม่เช่นนั้นก็จะนำซึ่งปัญหา ผมร่วงได้นะครับ

การประกาศ default namespace นี้จะทำให้ element ใดก็ตามที่อยู่ใน scope ของ default namespace นั้น จะอ้างอิงไปยัง namespace นั้นอย่างอัตโนมัติ เขาใช้ำว่า implicitly qualifies นะครับ ( ในกรณีที่เราไม่ได้กำหนด prefix ใดใด นะครับ ก็คือ ไม่ได้ explicitly qualifies ) ใช้ technical term เยอะ ก็จะงงนะครับ แต่ผ๊มมมว่า มันได้ใจความดีกว่าใช้ภาษาไทยนะครับ อย่า บ่น ผมเลยย ดูการประกาศดีกว่า


<?xml version="1.0"?>
<Book xmlns="http://www.library.com">
   <Title>Sherlock Holmes</Title>
   <Author> Arthur Conan Doyle</Author>
</Book>

ครับ นี่แหละครับ default namspace ประกาศดังนี้ทำให้เราไม่ต้อง ใส่ prefix ให้กับ element ภายใต้ scope ของ element ที่ declare  default namespace นะครับ เช่นเดียวกันนะครับ ถ้าผมยกตัวอย่างเดิมดังนี้

 <?xml version="1.0"?>
<Book xmlns="http://www.library.com">
   <Title>Sherlock Holmes - I</Title>
   <Author>Arthur Conan Doyle</Author>
   <Purchase xmlns="http://www.otherlibrary.com">
      <Title>Sherlock Holmes - II</Title>
      <Author>Arthur Conan Doyle</Author>
   </Purchase>
   <Title>Sherlock Holmes - III</Title>
   <Author>Arthur Conan Doyle</Author>
</Book>

ครับก็ ความหมายเหมือนกับ ตัวอย่างที่แล้วนะครับ scope ใครก็ scope มันนะครับ ถึงแม้จะไม่มี prefix ก็ตาม 🙂

Default Namespace และ Attribute

มันก็แปลก ๆ เล็กน้อยสำหรับ attribute กับเรื่อง Default Namespace  ไม่สามารถใช้กันได้ เป็นงั้นซะอีก นะครับ ดังนั้นการที่จะให้ attribute มันสามารถอ้างอิงไปยัง namespace ได้ก็ต้อง explicitly qualified นะครับ  สมมุติว่า element Book มี attribute ชื่อว่า isbn เราจะต้องประกาศแบบนี้นะครับ


<?xml version="1.0"?>

<Book  pfx:isbn="1234"
            xmlns="http://www.library.com"
            xmlns:pfx="http://www.library.com">
    <Title>Cherlock Holmes</Title>
    <Author>Arthur Conan Doyle</Author>
</Book>

วันนี้ต้อง หยุดไว้แค่นี้ก่อนะครับ แล้วจะมาต่อ ให้จบนะครับ