Free Hit Counters
http://www.dellasdeals.com

比较Hibernate和ADO.net 2.0,问?Hibernate还有什么特性更值得期待?

本文通过比较Hibernate3.0ADO.net 2.0对数据库存储过程的执行来比较两者的基本情况。

由于本人对Hibernate不熟悉,所有Hibernate代码均转载自http://java.e800.com.cn/articles/2007/515/1179165860296629767_1.html

如果有任何不恰当的地方请多多指教

本文的目的是

如果Nhibernate没有其它的过人之处,在.net环境下要他干嘛呢?

主要还是更针对在.net环境下的NHibernate

微软的ADO.net有着良好的结构。看见很多人在研究ORM。由于对具体的ORM产品没有过多了解,因此感觉这些产品存在的意义似乎不大?

下面表格的比较,试图说明,ADO本身也已经支持对象持久化。如果仅仅是单独一个对象对应一个表或者一行数据,似乎根本不需要使用任何的ORM产品

如果我的论断是对的,那么很多ORM可以洗洗睡了。园子里的某些“兴趣组”也可以关门了

-----------------------------------------------------------------
2007-09-14 14:06 henry
多体验一下NHibernate的对象化操作,而不是简单对象添加,删除和查询.
-----------------------------------------------------------------

我觉得在微软的Linq里面非常强大得可以对对象进行各种操作。自然,在没有Linq支持的地方可能NHibernate的作用能够体现出来一些。算是本贴的第一个成果。

那么,在完全支持Linq的地方NHibernate就没有用处了吧?


------------------------------------------------------------------
2007-09-14 17:11 henry

到底现在Linq是不是真的利害到可以扼杀一切还没有定断,我看来现版本的Linq在数据操远达到SQL优雅高效,唯的好处就是借助于编译器实现检测(不 过的确可以节省很大调试成本,但对于其编写简洁性有所保留),如果编译器直接直入SQL并根据查询返回动太对象类型那这个时候Linq就走一边去了.任何 事物都在发展的别看了一个东西有些甜头就把别东西看成一坨屎......
-------------------------------------------------------------------

恩,那么本主题的最后结论可能是这样的:
不考虑Linq、ADO3.0等未来的变化
目前ADO.net2.0完全可以胜任将数据表映射成对象的操作,以及提供对象间的关系操作
但是NHibernet扩展了强大的面向对象的数据操作性能,可以让程序员方便得以对象的方式进行很多操作,而不用去关心数据库访问的细节。这个是ADO.net不能做到的

因此如果有人不好好学习NHibernate
仅仅拿来做做增删改查
那么最好不要到处跟人家说,俺项目里用了NHibernate
因为丢人家NHibernate的脸


步骤

作用

Hibernate

ADO.net 2.0

数据源连接配置

设定连接到什么数据据库以及具体的连接参数

所在文件:hibernate的配置文件

<property name="connection.url">jdbc:mysql://localhost:3306/test</property>

   <property name="connection.username">root</property>

   <property name="connection.password">root</property>

   <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

   <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

所在文件:app.config

<configuration>

    <configSections>

    </configSections>

    <connectionStrings>

        <add name="WindowsApplication1.Properties.Settings.TestConnectionString"

            connectionString="Data Source=."SQLEXPRESS;AttachDbFilename=|DataDirectory|"Test.mdf;Integrated Security=True;User Instance=True"

            providerName="System.Data.SqlClient" />

    </connectionStrings>

</configuration>

实体类

所谓ORM里面程序中使用到的业务对象类

所在文件:User.java

public class User implements java.io.Serializable {

private static final long serialVersionUID = 1L;

/** 用户id*/

private String userid;

/** 用户姓名*/

private String name;

/** 用户blog*/

private String blog;

//省略get/set方法

}

所在文件:TestDataSet.Designer.cs

        /// <summary>

        ///Represents strongly named DataRow class.

        ///</summary>

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]

        public partial class tbl_userRow : global::System.Data.DataRow {

            private tbl_userDataTable tabletbl_user;

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

            internal tbl_userRow(global::System.Data.DataRowBuilder rb) :

                    base(rb) {

                this.tabletbl_user = ((tbl_userDataTable)(this.Table));

            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

            public string userid {

                get {

                    return ((string)(this[this.tabletbl_user.useridColumn]));

                }

                set {

                    this[this.tabletbl_user.useridColumn] = value;

                }

            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

            public string name {

                get {

                    try {

                        return ((string)(this[this.tabletbl_user.nameColumn]));

                    }

                    catch (global::System.InvalidCastException e) {

                        throw new global::System.Data.StrongTypingException("表“tbl_user”中列“name”的值为 DBNull", e);

                    }

                }

                set {

                    this[this.tabletbl_user.nameColumn] = value;

                }

            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

            public string blog {

                get {

                    try {

                        return ((string)(this[this.tabletbl_user.blogColumn]));

                    }

                    catch (global::System.InvalidCastException e) {

                        throw new global::System.Data.StrongTypingException("表“tbl_user”中列“blog”的值为 DBNull", e);

                    }

                }

                set {

                    this[this.tabletbl_user.blogColumn] = value;

                }

            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

            public bool IsnameNull() {

                return this.IsNull(this.tabletbl_user.nameColumn);

            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

            public void SetnameNull() {

                this[this.tabletbl_user.nameColumn] = global::System.Convert.DBNull;

            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

            public bool IsblogNull() {

                return this.IsNull(this.tabletbl_user.blogColumn);

            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

            public void SetblogNull() {

                this[this.tabletbl_user.blogColumn] = global::System.Convert.DBNull;

            }

        }

映射关系

指定在程序中使用的实体类与数据库中实际表以及列之间的关联关系

所在文件:User.hbm.xml

<?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.amigo.proc.model">

    <class name="User" table="tbl_user">

        <id name="userid" column="userid">

            <generator class="assigned"/>

        </id>

        <property name="name" column="name" type="string" />

        <property name="blog" column="blog" type="string" />

    </class>

    <sql-query name="getUserList" callable="true">

 <return alias="user" class="User">

   <return-property name="userid" column="userid"/>

   <return-property name="name" column="name"/>

   <return-property name="blog" column="blog" />

 </return>

 {call getUserList()}

 </sql-query>

</hibernate-mapping>

所在文件:TestDataSet.Designer.cs

global::System.Data.Common.DataTableMapping tableMapping = new global::System.Data.Common.DataTableMapping();

            tableMapping.SourceTable = "Table";

            tableMapping.DataSetTable = "tbl_user";

            tableMapping.ColumnMappings.Add("userid", "userid");

            tableMapping.ColumnMappings.Add("name", "name");

            tableMapping.ColumnMappings.Add("blog", "blog");

…………

private void InitCommandCollection() {

            this._commandCollection = new global::System.Data.SqlClient.SqlCommand[1];

            this._commandCollection[0] = new global::System.Data.SqlClient.SqlCommand();

            this._commandCollection[0].Connection = this.Connection;

            this._commandCollection[0].CommandText = "dbo.getUserList";

            this._commandCollection[0].CommandType = global::System.Data.CommandType.StoredProcedure;

            this._commandCollection[0].Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@RETURN_VALUE", global::System.Data.SqlDbType.Variant, 0, global::System.Data.ParameterDirection.ReturnValue, 0, 0, null, global::System.Data.DataRowVersion.Current, false, null, "", "", ""));

        }

其它存储过程省略……

查询


// 测试实现查询的存储过程

 private void testProcQuery(Session session) throws Exception ...{

 //查询用户列表

        List list = session.getNamedQuery("getUserList").list();

        for (int i = 0; i < list.size(); i++) ...{

            User user = (User) list.get(i);

            System.out.print("序号: " + (i+1));

            System.out.print(", userid: " + user.getUserid());

            System.out.print(", name: " + user.getName());

            System.out.println(", blog: " + user.getBlog());

        }

 }

private void testProcQuery()
        {
            //定义用户类集合
            TestDataSet.tbl_userDataTable Users = new TestDataSet.tbl_userDataTable();
            //获得数据
            this.tbl_userTableAdapter1.Fill(Users);
            int i = 0;
            //显示内容
            foreach(TestDataSet.tbl_userRow User in Users)
            {
                System.Console.WriteLine(string.Concat("序号:", i++, ",用户ID:", User.userid, ",用户姓名:", User.name, ",Blog:", User.blog));
            }
        }

更新


/**//**

 * 测试实现更新的存储过程

 * @throws Exception

 */

 private void testProcUpdate(Session session) throws Exception ...{

 //更新用户信息

 Transaction tx = session.beginTransaction();

        Connection con = session.connection();

        String procedure = "{call updateUser(?, ?, ?)}";

        CallableStatement cstmt = con.prepareCall(procedure);

        cstmt.setString(1, "xx");

        cstmt.setString(2, "http://www.blogjava.net/sterningChen");

        cstmt.setString(3, "sterning");

        cstmt.executeUpdate();

        tx.commit();

 }

private void testProcUpdate()
        {
            //类似Java的写法
            this.tbl_userTableAdapter1.Update("newID", "陈xx", "http://www.blogjava.net/sterningChen");

            //使用业务对象的写法
            //GetUsserByUserID是另一个因存储过程而产生的方法,自动生成的,以下同
            TestDataSet.tbl_userRow user = this.tbl_userTableAdapter1.GetUserByUserID("NewUserID")[0];
            user.name = "newName";
            user.blog = "newBlog";
            this.tbl_userTableAdapter1.Update(user);
        }

插入


// 测试实现插入的存储过程

 private void testProcInsert(Session session) throws Exception ...{

 //创建用户信息

 session.beginTransaction();

        PreparedStatement st = session.connection().prepareStatement("{call

createUser(?, ?, ?)}");

        st.setString(1, "amigo");

        st.setString(2, "阿蜜果");

        st.setString(3, "http://www.wblogjava.net/amigoxie");

        st.execute();

        session.getTransaction().commit();

 }

private void testProcInsert()
        {
            //直接使用数据
            this.tbl_userTableAdapter1.Insert("newID", "newName", "newBlog");  
            //使用面向对象
            TestDataSet.tbl_userDataTable tb = new TestDataSet.tbl_userDataTable();
            TestDataSet.tbl_userRow user = tb.Newtbl_userRow();
            user.userid = "NewUserID";
            user.name = "NewUser";
            user.blog = "testBlog";
            tb.Addtbl_userRow(user) ;
            this.tbl_userTableAdapter1.Update(user);  
        }


// 测试实现删除的存储过程

 private void testProcDelete(Session session) throws Exception ...{

 //删除用户信息

 session.beginTransaction();

 PreparedStatement st = session.connection().prepareStatement("{call deleteUser

(?)}");

        st.setString(1, "amigo");

        st.execute();

        session.getTransaction().commit();

 }

 private void testProcDelete()
        {
            //直接使用UserID删除
            this.tbl_userTableAdapter1.Delete("newID");

            //面向对象的方法
            TestDataSet.tbl_userRow user = this.tbl_userTableAdapter1.GetUserByUserID("NewUserID")[0];
            user.Delete();
            this.tbl_userTableAdapter1.Update(user);  
        }





posted @ 2007-09-14 12:33  徐少侠  阅读(5796)  评论(69编辑  收藏  举报
作者:徐少侠 出处:http://www.cnblogs.com/Chinese-xu/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过 Chinese_Xu@126.com 联系我,非常感谢。