FoxOne---一個快速高效的BS框架--WEB控件屬性編輯器
FoxOne---一個快速高效的BS框架--數據訪問(Dao)
數據訪問組件並非本人原創,本人是在前人的代碼的基礎之上稍加改良。
一切都從一個Blog類開始:
先簡單介紹一下上述類中各Attribute的意義
1.Table("BL_Blog")是表明該實體對應的數據表為BL_Blog,如果表名與實體名一致,則可以不用聲明;
2.[PrimaryKey]特征表明該屬性為主健;
3.[Column(DataType="varchar",Length="300")]特征聲明當前屬性在創建數據庫字段時對應的類型和長度;
4.[Column(Update=false)]聲明當前屬性在更新時不用更新該屬性;
下面我們就開始在代碼中使用定義好的Blog類
------------------------------------------------------------------------------
根據實體創建表結構的代碼為:
FoxOne.Data.Dao.Get().CreateTable<Blog>();
插入Blog數據的代碼為:
FoxOne.Data.Dao.Get().Insert(new Blog() { Id = Guid.NewGuid().ToString(), BrowseCount = 0, Content = "world", Title = "hello", CreateTime = DateTime.Now, CreatorId = Security.Sec.User.Id, LastUpdateTime = DateTime.Now });
根據ID更新Blog數據的代碼為:
FoxOne.Data.Dao.Get().Update<Blog>(new Blog() { Id = id, LastUpdateTime = DateTime.Now, Title = "hello1" });
根據當前用戶ID批量更新Blog的代碼為:
FoxOne.Data.Dao.Get().BatchUpdate<Blog>(new { CreatorId = Security.Sec.User.Id }, new { LastUpdateTime = DateTime.Now, Title = "hello1" });
刪除單條Blog數據:
FoxOne.Data.Dao.Get().Delete<Blog>(id);
批量刪除Blog數據的代碼為:
FoxOne.Data.Dao.Get().BatchDelete<Blog>(new { CreatorId=Security.Sec.User.Id});
獲取單條Blog數據的代碼為:
var blog = FoxOne.Data.Dao.Get().Get<Blog>(id)
獲取全部Blog數據的代碼為:
var blogs = FoxOne.Data.Dao.Get().Select<Blog>();
獲取當前登陸用戶創建的所有Blog數據的代碼為:
var blogs = FoxOne.Data.Dao.Get().Select<Blog>(new { CreatorId = Security.Sec.User.Id });
代碼中出現的Security.Sec.User是當前登陸用戶的IUser對象,里面有Id,Name,Roles,Department等豐富的上下文信息可以使用。
當然傳的參數也能是數組,生成的語句也變相應的變成IN
var blogs = FoxOne.Data.Dao.Get().Select<Blog>(new { BrowseCount = new int[] { 10, 20, 30 } });
自定義SQL語句查詢批量Blog數據的代碼為:
1.首先在配置文件中增加自定義的SQL語句
<command key="foxone.business.blog.selectByCondition"> <![CDATA[ SELECT * FROM BL_Blog WHERE BrowseCount>100 AND CreatorId=#CreatorId# ]]> </command>
2.在代碼中使用定義好的語句
var blogs = FoxOne.Data.Dao.Get().QueryEntities<Blog>("foxone.business.blog.selectByCondition", new { CreatorId = Security.Sec.User.Id });
Dao有自動從環境變量中求解值的功能,所以上面的語句又可以簡化為
<command key="foxone.business.blog.selectByCondition"> <![CDATA[ SELECT * FROM BL_Blog WHERE BrowseCount>100 AND CreatorId=#Env:User.Id# ]]> </command>
這樣的代碼中調用此SQL時就不用再傳遞CreatorId
var blogs = FoxOne.Data.Dao.Get().QueryEntities<Blog>("foxone.business.blog.selectByCondition");
上述SQL中出現的Env環境變量是通過Unity注冊進去的
ObjectHelper.RegisterType<ISqlParameters, EnvParameters>("Env");
EnvParameters的代碼如下:
public class EnvParameters : ISqlParameters { public const string Prefix = "Env:"; private static readonly int PrefixLength = Prefix.Length; public object Resolve(string name) { object value; return TryResolve(name, out value) ? value : null; } public bool TryResolve(string name, out object value) { if (name.ToUpper().StartsWith(Prefix.ToUpper())) { string varName = name.Substring(PrefixLength); return Env.TryResolve(varName, out value); } value = null; return false; } }
如果需要擴展更加豐富的環境變量支持,只需要實現如下接口:
namespace FoxOne.Data { public interface ISqlParameters { object Resolve(string name); bool TryResolve(string name, out object value); } }
此外DAO支持動態SQL語句:
<command key="foxone.business.blog.selectByCondition"> <![CDATA[ SELECT * FROM BL_Blog WHERE 1=1 {? AND Title LIKE '%$Title$%' } {? AND CreatorId=#CreatorId# } {? AND BrowseCount>#Count# } ]]> </command>
所謂的動態SQL,就是根據你在代碼中傳的參數來動態接拼SQL語句
當代碼中這樣調用時:
var blogs = FoxOne.Data.Dao.Get().QueryEntities<Blog>("foxone.business.blog.selectByCondition");
則執行的SQL語句為
SELECT * FROM BL_Blog WHERE 1=1
而當代碼中這樣調用時:
var blogs = FoxOne.Data.Dao.Get().QueryEntities<Blog>("foxone.business.blog.selectByCondition", new { Title="今天"});
則執行的SQL語句為:
SELECT * FROM BL_Blog WHERE 1=1 AND Title LIKE '%今天%'
除此之外還可以按頁獲取數據
var blogs = FoxOne.Data.Dao.Get().PageQueryEntities<Blog>( "foxone.business.blog.selectByCondition", 1, 10, "CreateTime DESC", new { Title = "今天" });
所有DAO自動生成的SQL都會自動兼容不同的數據庫產品,自定義的SQL則可以存在不同后綴名的config文件中,Blog.Oracle.Config文件中的SQL都是給Oracle環境下使用的,Blog.MySQL.config文件中的SQL都是在MYSQL環境下使用的。
最后DAO還有查詢其它類型的結果的方法,如下:
/// <summary> /// 查詢多條數據,並以IDataReader返回 /// </summary> /// <param name="sql">select sql語句</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>以IDataReader返回結果集</returns> public abstract IDataReader QueryReader(string sql, object parameters = null); /// <summary> /// 查詢多條數據,並以DataSet返回 /// </summary> /// <param name="sql">select sql語句</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>以DataSet返回結果集</returns> public abstract DataSet QueryDataSet(string sql, object parameters = null); /// <summary> /// 查詢多條數據,並以IDictionary為元素的IList返回 /// </summary> /// <param name="sql">select sql語句</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>以IDictionary為元素的IList返回結果集,數據不存在則返回空IList</returns> public abstract IList<IDictionary<string, object>> QueryDictionaries(string sql, object parameters = null); /// <summary> /// 查詢單條數據,並以IDictionary返回 /// </summary> /// <param name="sql">查詢單條數據的select sql語句</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>以IDictionary返回單條數據,數據不存在則返回Null</returns> public abstract IDictionary<string, object> QueryDictionary(string sql, object parameters = null); /// <summary> /// 查詢單條數據,並以實體類返回 /// </summary> /// <typeparam name="T">實體類類型</typeparam> /// <param name="sql">查詢單條數據的select sql語句(字段名必須與實體類屬性名一致)</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>以實體類返回單條數據,數據不存在則返回Null</returns> public abstract T QueryEntity<T>(string sql, object parameters = null) where T : class, new(); /// <summary> /// 查詢單條數據,並以實體類返回 /// </summary> /// <typeparam name="T">實體類類型</typeparam> /// <param name="type">實體類接口</param> /// <param name="sql">查詢單條數據的select sql語句(字段名必須與實體類屬性名一致)</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>以實體類返回單條數據,數據不存在則返回Null</returns> public abstract T QueryEntity<T>(Type type, string sql, object parameters = null); /// <summary> /// 執行select sql語句,檢查是否有數據返回 /// </summary> /// <param name="sql">select sql語句</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>True有數據 false沒有數據</returns> public abstract bool Exists(string sql, object parameters = null); /// <summary> /// 查詢單條數據的單個字段 /// </summary> /// <typeparam name="T">單個字段的返回類型</typeparam> /// <param name="sql">查詢單個字段的sql語句</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>以指定的類型返回制定字段。在查詢出來字段值為空的情況時,如果指定以string或其他類型返回,則返回null,如果以int等數值型類型返回,則返回0</returns> public abstract T QueryScalar<T>(string sql, object parameters = null); /// <summary> /// 查詢多條數據的單個字段 /// </summary> /// <typeparam name="T">單個字段的返回類型</typeparam> /// <param name="sql">查詢多條數據單個字段的sql語句</param> /// <param name="parameters">普通Object或者IDictionary,分別通過屬性名和Key與sql中的參數名匹配</param> /// <returns>以制定元素的IList返回多條數據的單個字段,數據不存在在返回空IList</returns> public abstract IList<T> QueryScalarList<T>(string sql, object parameters = null);
github:https://github.com/gameking0124/FoxOne