光阴似箭,日月如梭,套用小学作文惯用的一句开场白来开始重新开始我的博客园生涯吧。
8年的风霜雪雨,不断的击打着我内心的哀伤,可我依旧坚挺的屹立在这里,是因为技术是我一直坚持的梦想。
追寻着先辈和高人的脚步,多希望能见见他们的模样,仰望着他们高高在上,心中不禁黯然神伤。
三十功名尘与土,八千里路云和月,或许正是这样。
一路荆棘密布,坎坷不堪,是进是退,此时的你究竟想闹哪样。
技术生涯是枯燥的、乏味的。
当别人搂着小三进入梦乡,而你还在冥思苦想。
远望着路边昏暗的灯光,倾听着青蛙与蛐蛐的鸣响。
你思索着,也许明天就会变得晴朗,蓝天白云,鸟语花香。
也许没有人懂得你的浪漫,你只会傻傻的说出一句程式搬的诗句,如果爱,所以爱。
如果她听懂了,那就好好珍惜吧。
不好意思,跑题了,最近思绪太多了,改天再为各位大侠写诗啊。
诗中提到,技术生涯是枯燥的、乏味的,一直以来,我都想让开发变得更加简单,让代码更加优雅。让你看到代码就像见到美女一样。
今天我提到的 Restful.Data ,是一个通用的数据持久层组件。
有的博友肯定会说干嘛老是重复造轮子呢,我想说,你的想法和当年米其林轮胎公司生产出全世界第一条全钢丝子午线轮胎时的想法一样。
对啊,我已经造出轮子了,你普利司通、韩泰、横滨、锦湖干嘛还造啊,都用我家生产的轮胎好了啊。
正是因为有了更多的企业重复制造的轮子,你才有了更多的选择,才让这个世界变得更加丰富多彩。
在.NET世界里,有很多持久层组件让我们选择:
- entity framework
- nherbinate
- ibatis.net
- castle
- ...
我无法评判它们孰胜孰劣,它们都是优秀的,这一点是值得肯定的。可是它们都不是我想要的。
有的过于复杂,有的过于庞大,有的需要大量的配置,有的让你难以轻松上手。
我希望我的工具就像一把尖刀,拿过来就能杀鬼子的,而它们至少还需要你在磨刀石上磨一下。
今天我所提到的 Restful.Data,也许就是你想要的。
首先,Restful.Data 对 ado.net 做了进一步的封装,提供了对数据库访问的基本操作:
#region ADO.NET 封装 #region Transaction /// <summary> /// 开始一个事务 /// </summary> /// <returns></returns> DbTransaction BeginTransaction(); #endregion #region ExecuteScalar /// <summary> /// 执行 SQL 语句,返回一个单一对象 /// </summary> /// <param name="sql">SQL 语句</param> /// <returns>单一对象</returns> T ExecuteScalar<T>( string sql ); /// <summary> /// 执行带参数的 SQL 语句,返回一个单一对象 /// </summary> /// <param name="sql">SQL 语句</param> /// <param name="parameters">参数</param> /// <returns>单一对象</returns> T ExecuteScalar<T>( string sql, IDictionary<string,object> parameters ); #endregion #region ExecuteDataReader /// <summary> /// 执行 SQL 语句,返回一个 DataReader 对象 /// </summary> /// <param name="sql">SQL 语句</param> /// <returns>DataReader 对象</returns> DbDataReader ExecuteDataReader( string sql ); /// <summary> /// 执行带参数 SQL 语句,返回一个 DataReader 对象 /// </summary> /// <param name="sql">SQL 语句</param> /// <param name="parameters">参数</param> /// <returns>DataReader 对象</returns> DbDataReader ExecuteDataReader( string sql, IDictionary<string, object> parameters ); #endregion #region ExecuteDataTable /// <summary> /// 执行 SQL 语句,返回一个 DataTable 对象 /// </summary> /// <param name="sql">SQL 语句</param> /// <returns>DataTable 对象</returns> DataTable ExecuteDataTable( string sql ); /// <summary> /// 执行带参数 SQL 语句,返回一个 DataTable 对象 /// </summary> /// <param name="sql">SQL 语句</param> /// <param name="parameters">参数</param> /// <returns>DataTable 对象</returns> DataTable ExecuteDataTable( string sql, IDictionary<string,object> parameters ); #endregion #region ExecuteDataSet /// <summary> /// 执行 SQL 语句,返回一个 DataSet 对象 /// </summary> /// <param name="sql">SQL 语句</param> /// <returns>DataSet 对象</returns> DataSet ExecuteDataSet( string sql ); /// <summary> /// 执行带参数 SQL 语句,返回一个 DataTable 对象 /// </summary> /// <param name="sql">SQL 语句</param> /// <param name="parameters">参数值</param> /// <returns>DataSet 对象</returns> DataSet ExecuteDataSet( string sql, IDictionary<string, object> parameters ); #endregion #region ExecuteNonQuery /// <summary> /// 执行非查询 SQL 语句,返回受影响的行数 /// </summary> /// <param name="sql">SQL 语句</param> /// <returns>受影响的行数</returns> int ExecuteNonQuery( string sql ); /// <summary> /// 执行带参数的非查询 SQL 语句,返回受影响的行数 /// </summary> /// <param name="sql">SQL 语句</param> /// <param name="values">参数值</param> /// <returns>受影响的行数</returns> int ExecuteNonQuery( string sql, IDictionary<string,object> parameters ); #endregion #endregion
使用方法:
#region 使用Session using( ISession session = SessionFactory.CreateDefaultSession() ) { return session.ExecuteDataTable( "select * from T" ); } #endregion #region 使用DbHelper return DbHelper..ExecuteDataTable( "select * from T" ); #endregion
支持事务处理:
#region 事务处理 using( ISession session = SessionFactory.CreateDefaultSession() ) { session.BeginTransaction(); session.ExecuteNonQuery( "insert into t value( '', '' )" ); session.ExecuteNonQuery( "update t set a = 1, b = 2 where c = 3" ); session.Commit(); } #endregion
当执行过程中出现异常,事务自动回滚。
在ORM方面,支持对单表的增删改查操作,对我来说这够用了。
先定义一个实体类:
#region 实体类 public class User : EntityObject<User> { /// <summary> /// 构造方法 /// </summary> public User() : base() { } private long m_ID; private string m_Account; private string m_Password; private bool m_IsActived; /// <summary> /// /// </summary> [Column( IsPrimaryKey = true, IsAutoIncrease = true )] public long ID { get { return this.m_ID; } set { this.m_ID = value; this.OnPropertyChanged( "ID", value ); } } /// <summary> /// /// </summary> public string Account { get { return this.m_Account; } set { this.m_Account = value; this.OnPropertyChanged( "Account", value ); } } /// <summary> /// /// </summary> public string Password { get { return this.m_Password; } set { this.m_Password = value; this.OnPropertyChanged( "Password", value ); } } /// <summary> /// /// </summary> public bool IsActived { get { return this.m_IsActived; } set { this.m_IsActived = value; this.OnPropertyChanged( "IsActived", value ); } } } #endregion
实体类代码可通过工具自动生成,对于Column特性只需设置 IsPrimaryKey和IsAutoIncrease。
如何实现增删改:
#region 增删改 DbHelper.Insert<User>( user ); DbHelper.Update<User>( user ).Execute(); DbHelper.Update<User>( user ).Where( s => s.IsActive ).Execute(); DbHelper.Delete<User>( user ).Execute(); DbHelper.Delete<User>().Where( s => s.ID == 1 ).Execute(); #endregion
对于查询,集成了LINQ,但仅支持单表的查询:
#region 查询 var source = session.Find<User>() .Where( s => !string.IsNullOrEmpty( s.Account ) ) .Where( s => s.Account.StartsWith( "xxx" ) ) .Where( s => s.IsActive ) .OrderBy( s => s.ID ) .Skip( 1 ).Take( 2 ); var target = source.ToList(); source = from s in session.Find<User>() where s.Account.StartsWith( "xxx" ) orderby s.ID select new { ID = s.ID, Account = s.Account }; target = source.ToList(); #endregion
使用前,你只需要简单的将Web.config或App.config中的connectionStrings节点中的providerName改成Restful.Data.MySql、Restful.Data.SQLServer、Restful.Data.Oracle等等,并在程序启动时调用
SessionProviderFactories.Register<T>()方法注册一下provider即可。
整个 Restful.Data 介绍完了,如果觉得不好请拍砖,并留下你宝贵的意见和建议,我将持续改进。
目前只实现了核心功能和MySql的provider,所以想找几个有为骚年一起完善,有兴趣者请加群 338570336
已是深夜,你是否已经酣然入睡,静静的等待那可恶的闹铃将你从春梦中吵醒,而我明天不用上班...