1. 程式人生 > >Java是如何快速煮成C 的 (二) 資料訪問 1

Java是如何快速煮成C 的 (二) 資料訪問 1

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

在上兩篇《 Java是如何快速煮成C#的?》(一):相似的方法 《Java是如何快速煮成C#的?》(一):相似的方法(2) 中,我們開啟了C#與Java中的話題之一:相似的方法。其實我寫主這兩篇文章的目的,有兩個:
1、總結自己的學習歷程,這個是主要的。
2、給c#轉入java的同學一個快速熟悉的感覺,所以這個系列的名稱也是“快速煮成”。
因為我對這兩門語言僅限瞭解,對c#也僅限於熟悉,如有理解不妥之處,請指正。
今天我們看看這兩種語言環境下純粹的資料訪問。
首先我再次宣告:
1、本文不比較這兩種語言的資料訪問的效能差異。


2、本文不涉及各自的OR框架, 如C#的ADO.NET Entity Framework,MVC,Nhibernate,spring.net,以及Java領域的Spring/Hibernate/Struts等第三方框架,只是純粹的資料訪問
3、資料庫採用MS SQL server 2008,其實也可以用mySQL,MySQL提供官方支援。oracle平時很少用,DB2沒用過。
準備工作:一個用於測試的部門表DepartDemo,表結構如下:
 邀月工作室
相關的SQL語句:

[ruby] view plain copy print ?
  1. Create database Db2010Demo  
  2. go  
  3. use Db2010Demo  
  4. go  
  5. if exists (select 1  
  6. from sysobjects  
  7. where id = object_id('DepartDemo')  
  8. and type = 
    'U')  
  9. drop table DepartDemo  
  10. go  
  11. /*==============================================================*/  
  12. /* Table: DepartDemo */  
  13. /*==============================================================*/  
  14. create table DepartDemo (  
  15. PKID int identity(101,1),  
  16. DName nvarchar(200) null,  
  17. DCode nvarchar(500) null,  
  18. Manager nvarchar(50) null,  
  19. ParentID int null default 0,  
  20. AddUser nvarchar(50) null,  
  21. AddTime datetime null,  
  22. ModUser nvarchar(50) null,  
  23. ModTime datetime null,  
  24. CurState smallint not null default 0,  
  25. Remark nvarchar(500) null,  
  26. F1 int not null default 0,  
  27. F2 nvarchar(300) null,  
  28. constraint PK_DEPARTDEMO primary key (PKID)  
  29. )  
  30. go  
  31. --插入一條測試資料  
  32. insert into DepartDemo  
  33. select '國家統計局房產審計一科','0','胡不歸',0,'DeomUser',getdate(),  
  34. '','1900-01-01',1,'專業評估全國房價,為老百姓謀福祉',0,''  
  35. --建立一個儲存過程,在C#程式中用到  
  36. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[DepartDemoSelectByPKID]') AND type='P')  
  37. DROP PROCEDURE [dbo].[DepartDemoSelectByPKID]  
  38. GO  
  39. CREATE PROCEDURE [dbo].[DepartDemoSelectByPKID]  
  40. (  
  41. @Pkid int  
  42. )  
  43. AS  
  44. BEGIN TRAN  
  45. Select * From [DepartDemo] Where [Pkid]=@Pkid  
  46. IF @@ERROR!=0  
  47. BEGIN  
  48. ROLLBACK  
  49. END  
  50. ELSE  
  51. BEGIN  
  52. COMMIT  
  53. END  
  54. GO  
Create database Db2010Demogouse Db2010Demogoif exists (select 1from sysobjectswhere id = object_id('DepartDemo')and type = 'U')drop table DepartDemogo/*==============================================================*//* Table: DepartDemo *//*==============================================================*/create table DepartDemo (PKID int identity(101,1),DName nvarchar(200) null,DCode nvarchar(500) null,Manager nvarchar(50) null,ParentID int null default 0,AddUser nvarchar(50) null,AddTime datetime null,ModUser nvarchar(50) null,ModTime datetime null,CurState smallint not null default 0,Remark nvarchar(500) null,F1 int not null default 0,F2 nvarchar(300) null,constraint PK_DEPARTDEMO primary key (PKID))go--插入一條測試資料insert into DepartDemoselect '國家統計局房產審計一科','0','胡不歸',0,'DeomUser',getdate(),'','1900-01-01',1,'專業評估全國房價,為老百姓謀福祉',0,''--建立一個儲存過程,在C#程式中用到IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[DepartDemoSelectByPKID]') AND type='P')DROP PROCEDURE [dbo].[DepartDemoSelectByPKID]GOCREATE PROCEDURE [dbo].[DepartDemoSelectByPKID](@Pkid int)ASBEGIN TRANSelect * From [DepartDemo] Where [Pkid][email protected] @@ERROR!=0BEGINROLLBACKENDELSEBEGINCOMMITENDGO

一、我們看看C#環境下一個資料訪問的簡單例子。

在vs2010中新建一控制檯專案,結構如下:

邀月工作室

相應的程式碼,

基礎資料層:

Database.cs:

[c-sharp] view plain copy print ?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Data;  
  5. using System.Data.SqlClient;  
  6. namespace demo2010.database  
  7. {  
  8.     public class DataBase  
  9.     {  
  10.         private static string connectionString = System.Configuration.ConfigurationManager.AppSettings["GlobalsConnString"];  
  11.         public static string ConnectionString  
  12.         {  
  13.             get { return connectionString; }  
  14.             set { connectionString = value; }  
  15.         }  
  16.         #region Helpers  
  17.         internal protected static IDataReader GetReader(string commandText, SqlParameter[] p)  
  18.         {  
  19.             return SqlHelper.ExecuteReader(ConnectionString, CommandType.StoredProcedure, commandText, p);  
  20.         }  
  21.         internal protected static IDataReader GetReader(string commandText)  
  22.         {  
  23.             return SqlHelper.ExecuteReader(ConnectionString, CommandType.StoredProcedure, commandText);  
  24.         }  
  25.         internal protected static int NonQueryInt(string commandText, SqlParameter[] p)  
  26.         {  
  27.             return SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure, commandText, p);  
  28.         }  
  29.         internal protected static bool NonQueryBool(string commandText, SqlParameter[] p)  
  30.         {  
  31.             return NonQueryInt(commandText, p) > 0;  
  32.         }  
  33.         internal protected void RunSql(string commandText)  
  34.         {  
  35.             SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, commandText);  
  36.         }  
  37.         public static void ExecuteSQL(string commandText)  
  38.         {  
  39.             SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, commandText);  
  40.         }  
  41.         public static DataTable GetDataTable(string commandText)  
  42.         {  
  43.             return SqlHelper.ExecuteDataTable(ConnectionString, CommandType.Text, commandText);  
  44.         }  
  45.         public static DataTable GetDataTable(string commandText, CommandType commandType)  
  46.         {  
  47.             return SqlHelper.ExecuteDataTable(ConnectionString, commandType, commandText);  
  48.         }  
  49.          
  50.         internal protected static string ReturnString(string commandText, SqlParameter[] p)  
  51.         {  
  52.             object result = SqlHelper.ExecuteScalar(ConnectionString, System.Data.CommandType.StoredProcedure, commandText, p);  
  53.             return result.ToString();  
  54.         }  
  55.         internal protected static SqlParameter ReTurnStringValue  
  56.         {  
  57.             get  
  58.             {  
  59.                 return SqlHelper.MakeOutParam("@ReTurnValue", SqlDbType.NVarChar, 200);  
  60.             }  
  61.         }  
  62.         internal protected static SqlParameter ReTurnLongValue  
  63.         {  
  64.             get  
  65.             {  
  66.                 return SqlHelper.MakeOutParam("@ReTurnValue", SqlDbType.BigInt, 8);  
  67.             }  
  68.         }  
  69.         #endregion  
  70.     }  
  71. }  
using System;using System.Collections.Generic;using System.Text;using System.Data;using System.Data.SqlClient;namespace demo2010.database{    public class DataBase    {        private static string connectionString = System.Configuration.ConfigurationManager.AppSettings["GlobalsConnString"];        public static string ConnectionString        {            get { return connectionString; }            set { connectionString = value; }        }        #region Helpers        internal protected static IDataReader GetReader(string commandText, SqlParameter[] p)        {            return SqlHelper.ExecuteReader(ConnectionString, CommandType.StoredProcedure, commandText, p);        }        internal protected static IDataReader GetReader(string commandText)        {            return SqlHelper.ExecuteReader(ConnectionString, CommandType.StoredProcedure, commandText);        }        internal protected static int NonQueryInt(string commandText, SqlParameter[] p)        {            return SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.StoredProcedure, commandText, p);        }        internal protected static bool NonQueryBool(string commandText, SqlParameter[] p)        {            return NonQueryInt(commandText, p) > 0;        }        internal protected void RunSql(string commandText)        {            SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, commandText);        }        public static void ExecuteSQL(string commandText)        {            SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, commandText);        }        public static DataTable GetDataTable(string commandText)        {            return SqlHelper.ExecuteDataTable(ConnectionString, CommandType.Text, commandText);        }        public static DataTable GetDataTable(string commandText, CommandType commandType)        {            return SqlHelper.ExecuteDataTable(ConnectionString, commandType, commandText);        }               internal protected static string ReturnString(string commandText, SqlParameter[] p)        {            object result = SqlHelper.ExecuteScalar(ConnectionString, System.Data.CommandType.StoredProcedure, commandText, p);            return result.ToString();        }        internal protected static SqlParameter ReTurnStringValue        {            get            {                return SqlHelper.MakeOutParam("@ReTurnValue", SqlDbType.NVarChar, 200);            }        }        internal protected static SqlParameter ReTurnLongValue        {            get            {                return SqlHelper.MakeOutParam("@ReTurnValue", SqlDbType.BigInt, 8);            }        }        #endregion    }}

DynamicBuilder.cs:

[c-sharp] view plain copy print ?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Data.SqlClient;  
  4. using System.Reflection;  
  5. using System.Reflection.Emit;  
  6. using System.Data;  
  7. namespace demo2010.database  
  8. {  
  9.     /// <summary>  
  10.     /// Tony 2008.8.28 Add   
  11.     /// </summary>  
  12.     /// <typeparam name="T"></typeparam>  
  13.     public class DynamicBuilder<T>  
  14.     {  
  15.         private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item"new Type[] { typeof(int) });  
  16.         private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull"new Type[] { typeof(int) });  
  17.         private delegate T Load(IDataRecord dataRecord);  
  18.         private const BindingFlags BINDING_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase;//Added by Tony 2008.09.25  
  19.         private Load handler;  
  20.         private DynamicBuilder() { }  
  21.         public T Build(IDataRecord dataRecord)  
  22.         {  
  23.             return handler(dataRecord);  
  24.         }  
  25.         public static DynamicBuilder<T> CreateBuilder(IDataRecord dataRecord)  
  26.         {  
  27.             DynamicBuilder<T> dynamicBuilder = new DynamicBuilder<T>();  
  28.             DynamicMethod method = new DynamicMethod("DynamicCreate"typeof(T), new Type[] { typeof(IDataRecord) }, typeof(T), true);  
  29.             ILGenerator generator = method.GetILGenerator();  
  30.             LocalBuilder result = generator.DeclareLocal(typeof(T));  
  31.             generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));  
  32.             generator.Emit(OpCodes.Stloc, result);  
  33.             for (int i = 0; i < dataRecord.FieldCount; i++)  
  34.             {  
  35.                 PropertyInfo propertyInfo = typeof(T).GetProperty(dataRecord.GetName(i),BINDING_FLAGS);//performance'Maxvalue decrease 5% **** Test By Tony 2008.09.25   
  36.                 Label endIfLabel = generator.DefineLabel();  
  37.                 if (propertyInfo != null && propertyInfo.GetSetMethod() != null)  
  38.                 {  
  39.                     generator.Emit(OpCodes.Ldarg_0);  
  40.                     generator.Emit(OpCodes.Ldc_I4, i);  
  41.                     generator.Emit(OpCodes.Callvirt, isDBNullMethod);  
  42.                     generator.Emit(OpCodes.Brtrue, endIfLabel);  
  43.                     generator.Emit(OpCodes.Ldloc, result);  
  44.                     generator.Emit(OpCodes.Ldarg_0);  
  45.                     generator.Emit(OpCodes.Ldc_I4, i);  
  46.                     generator.Emit(OpCodes.Callvirt, getValueMethod);  
  47.                     generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));  
  48.                     generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());  
  49.                     generator.MarkLabel(endIfLabel);  
  50.                 }  
  51.             }  
  52.             generator.Emit(OpCodes.Ldloc, result);  
  53.             generator.Emit(OpCodes.Ret);  
  54.             dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load));  
  55.             return dynamicBuilder;  
  56.         }  
  57.     }  
  58. }  
using System;using System.Collections.Generic;using System.Data.SqlClient;using System.Reflection;using System.Reflection.Emit;using System.Data;namespace demo2010.database{    /// <summary>    /// Tony 2008.8.28 Add     /// </summary>    /// <typeparam name="T"></typeparam>    public class DynamicBuilder<T>    {        private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) });        private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) });        private delegate T Load(IDataRecord dataRecord);        private const BindingFlags BINDING_FLAGS = BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase;//Added by Tony 2008.09.25        private Load handler;        private DynamicBuilder() { }        public T Build(IDataRecord dataRecord)        {            return handler(dataRecord);        }        public static DynamicBuilder<T> CreateBuilder(IDataRecord dataRecord)        {            DynamicBuilder<T> dynamicBuilder = new DynamicBuilder<T>();            DynamicMethod method = new DynamicMethod("DynamicCreate", typeof(T), new Type[] { typeof(IDataRecord) }, typeof(T), true);            ILGenerator generator = method.GetILGenerator();            LocalBuilder result = generator.DeclareLocal(typeof(T));            generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));            generator.Emit(OpCodes.Stloc, result);            for (int i = 0; i < dataRecord.FieldCount; i++)            {                PropertyInfo propertyInfo = typeof(T).GetProperty(dataRecord.GetName(i),BINDING_FLAGS);//performance'Maxvalue decrease 5% **** Test By Tony 2008.09.25                 Label endIfLabel = generator.DefineLabel();                if (propertyInfo != null && propertyInfo.GetSetMethod() != null)                {                    generator.Emit(OpCodes.Ldarg_0);                    generator.Emit(OpCodes.Ldc_I4, i);                    generator.Emit(OpCodes.Callvirt, isDBNullMethod);                    generator.Emit(OpCodes.Brtrue, endIfLabel);                    generator.Emit(OpCodes.Ldloc, result);                    generator.Emit(OpCodes.Ldarg_0);                    generator.Emit(OpCodes.Ldc_I4, i);                    generator.Emit(OpCodes.Callvirt, getValueMethod);                    generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));                    generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());                    generator.MarkLabel(endIfLabel);                }            }            generator.Emit(OpCodes.Ldloc, result);            generator.Emit(OpCodes.Ret);            dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load));            return dynamicBuilder;        }    }}

SqlHelper.cs:(我們將最常用的SQL在大家熟悉的SqlHelper中。)

[c-sharp] view plain copy print ?
  1. using System;  
  2. using System.Configuration;  
  3. using System.Data;  
  4. using System.Xml;  
  5. using System.Data.SqlClient;  
  6. using System.Collections;  
  7. namespace demo2010.database  
  8. {  
  9.     #region Disclaimer/Info  
  10.     #endregion  
  11.     /// <summary>  
  12.     /// The SqlHelper class is intended to encapsulate high performance, scalable best practices for   
  13.     /// common uses of SqlClient.  
  14.     /// </summary>  
  15.     public sealed class SqlHelper  
  16.     {  
  17.         #region private utility methods & constructors  
  18.         //Since this class provides only static methods, make the default constructor private to prevent   
  19.         //instances from being created with "new SqlHelper()".  
  20.         private SqlHelper() { }  
  21.         /// <summary>  
  22.         /// This method is used to attach array of SqlParameters to a SqlCommand.  
  23.         ///   
  24.         /// This method will assign a value of DbNull to any parameter with a direction of  
  25.         /// InputOutput and a value of null.    
  26.         ///   
  27.         /// This behavior will prevent default values from being used, but  
  28.         /// this will be the less common case than an intended pure output parameter (derived as InputOutput)  
  29.         /// where the user provided no input value.  
  30.         /// </summary>  
  31.         /// <param name="command">The command to which the parameters will be added</param>  
  32.         /// <param name="commandParameters">an array of SqlParameters tho be added to command</param>  
  33.         private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)  
  34.         {  
  35.             foreach (SqlParameter p in commandParameters)  
  36.             {  
  37.                 //check for derived output value with no value assigned  
  38.                 if ((p.Direction == ParameterDirection.InputOutput) && (p.Value == null))  
  39.                 {  
  40.                     p.Value = DBNull.Value;  
  41.                 }  
  42.                 command.Parameters.Add(p);  
  43.             }  
  44.         }  
  45.         /// <summary>  
  46.         /// This method assigns an array of values to an array of SqlParameters.  
  47.         /// </summary>  
  48.         /// <param name="commandParameters">array of SqlParameters to be assigned values</param>  
  49.         /// <param name="parameterValues">array of Components holding the values to be assigned</param>  
  50.         private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)  
  51.         {  
  52.             if ((commandParameters == null) || (parameterValues == null))  
  53.             {  
  54.                 //do nothing if we get no data  
  55.                 return;  
  56.             }  
  57.             // we must have the same number of values as we pave parameters to put them in  
  58.             if (commandParameters.Length != parameterValues.Length)  
  59.             {  
  60.                 throw new ArgumentException("Parameter count does not match Parameter Value count.");  
  61.             }  
  62.             //iterate through the SqlParameters, assigning the values from the corresponding position in the   
  63.             //value array  
  64.             for (int i = 0, j = commandParameters.Length; i < j; i++)  
  65.             {  
  66.                 commandParameters[i].Value = parameterValues[i];  
  67.             }  
  68.         }  
  69.         /// <summary>  
  70.         /// This method opens (if necessary) and assigns a connection, transaction, command type and parameters   
  71.         /// to the provided command.  
  72.         /// </summary>  
  73.         /// <param name="command">the SqlCommand to be prepared</param>  
  74.         /// <param name="connection">a valid SqlConnection, on which to execute this command</param>  
  75.         /// <param name="transaction">a valid SqlTransaction, or 'null'</param>  
  76.         /// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>  
  77.         /// <param name="commandText">the stored procedure name or T-SQL command</param>  
  78.         /// <param name="commandParameters">an array of SqlParameters to be associated with the command or 'null' if no parameters are required</param>  
  79.         private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters)  
  80.         {  
  81.             //if the provided connection is not open, we will open it  
  82.             if (connection.State != ConnectionState.Open)  
  83.             {  
  84.                 connection.Open();  
  85.             }  
  86.             //associate the connection with the command  
  87.             command.Connection = connection;  
  88.             //set the command text (stored procedure name or SQL statement)  
  89.             command.CommandText = commandText;  
  90.             //if we were provided a transaction, assign it.  
  91.             if (transaction != null)  
  92.             {  
  93.                 command.Transaction = transaction;  
  94.             } &nb