接着上一篇的教程,本章咱們繼續講SmartSql。今天的主題是動態倉儲。git
老規矩,先上一個項目結構github
從第二章開始。咱們將原來的單一項目作了一個分離。方便以後的更新。ide
在這個結構中。本來上一章的DataAccess沒有了。取而代之的是Repository。這個就是動態倉儲的項目。接下來咱們從這個Repository項目開始說。這也是動態倉儲的核心。函數
SmartSql有一個獨立的動態倉儲庫,即:SmartSql.DyRepository。若是你想使用動態倉儲,引用它就行啦。ui
引用完庫,接下來就是建立咱們的第一個倉儲接口—IArticleRepository。廢話不到,先上代碼再一一解釋。spa
1 using SmartSql.DyRepository; 2 using SmartSql.DyRepository.Annotations; 3 using SmartSqlSampleChapterTwo.Entity; 4 using System.Data; 5
6 namespace SmartSqlSampleChapterTwo.Repository 7 { 8 [SqlMap(Scope = "CustomScope")] 9 public interface IArticleRepository : IRepository<T_Article, long>
10 { 11 [Statement(CommandType = CommandType.Text, Execute = ExecuteBehavior.ExecuteScalar, Id = "Offline")] 12 int OfflineArticle([Param("Id", FieldType = typeof(long))] long articleId); 13
14 [Statement(Sql = "Update T_Article Set Status = 1 Where Id = @Id")] 15 int OnlineArticle([Param("Id")] long article); 16 } 17 }
看完代碼是否是發現和上一章的DataAccess有很大的區別,那些CURD的方法都沒有了。code
這是SmartSql內置的一些默認接口,它包括如下這些接口,這些接口基本能夠知足大部分普通業務場景了。xml
1 int Insert(TEntity entity); 2
3 int Update(TEntity entity); 4
5 [Statement(Id = "Update")] 6 int DyUpdate(object dyObj); 7
8 int Delete(object reqParams); 9
10 [Statement(Id = "Delete")] 11 int DeleteById([Param("Id")] TPrimary id); 12
13 TEntity GetEntity(object reqParams); 14
15 [Statement(Id = "GetEntity")] 16 TEntity GetById([Param("Id")] TPrimary id); 17
18 [Statement(Execute = ExecuteBehavior.ExecuteScalar)] 19 int GetRecord(object reqParams); 20
21 IList<TEntity> QueryByPage(object reqParams); 22
23 IList<TEntity> Query(object reqParams); 24
25 [Statement(Execute = ExecuteBehavior.ExecuteScalar)] 26 bool IsExist(object reqParams);
這個特性是用於指定Scope的配置。這個對應於Map中的Scope屬性。這裏我定義了「CustomScope」。那對應的Map中也將與之對應。以下圖:blog
這個特性略微有點複雜,其中包含了6個屬性,接下來咱們一個個看。教程
這個特性和SqlMap的Scope做用是同樣的。區別在於Statement的級別更高。
指定此函數所使用的Statement。依據是Id。例:
// 接口定義 [Statement(Id = "TestId")] int CustomStatementId();
<!-- Statement定義 -->
<Statement Id="TestId"> db script... </Statement>
Execute是一個ExecuteBehavior枚舉,用於指定此函數執行Sql腳本的方式。
Auto | ORM自動識別 |
Execute | 返回影響行數,主要用於執行寫操做。 |
ExecuteScalar | 返回第一行第一列的數據,主要用於返回自增主鍵和獲取結果數 |
Query | 返回List |
QuerySingle | 返回第一行數據 |
GetDataTable | 返回DataTable |
GetDataSet | 返回DataSet |
特殊場景下,能夠直接使用此屬性定義Sql腳本,而不用配置SqlMap。如IArticleRepository的OnlineArticle定義。
這個屬性是ADO.NET的CommandType枚舉。做用也徹底相同
指定數據源,能夠指定Write或Read。
在上一章節中,咱們在Startup中註冊了SmartSql,如今咱們要繼續註冊動態倉儲。代碼也很簡單,只要在AddSmart方法完成後繼續調用AddRepositoryFromAssembly便可。以下:
services.AddSmartSql(builder => { builder.UseAlias("SmartSqlSampleChapterTwo"); // 定義實例別名,在多庫場景下適用。 //.UseXmlConfig(ResourceType.File,"MyConfig.xml");
}).AddRepositoryFromAssembly(options => { // SmartSql實例的別名
options.SmartSqlAlias = "SmartSqlSampleChapterTwo"; // 倉儲接口所在的程序集全稱
options.AssemblyString = "SmartSqlSampleChapterTwo.Repository"; // 篩選器,根據接口的Type篩選須要的倉儲
options.Filter = type => type.FullName.Contains("Sample"); // Scope模板,默認是"I{Scope}Repository"
options.ScopeTemplate = "I{Scope}Repository"; });
這個方法中會拋出一個AssemblyAutoRegisterOptions,方便用戶註冊指定的倉儲。
在Sample中,咱們直接讓Controller引用了Repository,實際場景中。咱們能夠在任何須要倉儲的地方引用倉儲。代碼以下:
using Microsoft.AspNetCore.Mvc; using SmartSqlSampleChapterTwo.Entity; using SmartSqlSampleChapterTwo.Repository; using System.Collections.Generic; namespace SmartSqlSampleChapterTwo.Api.Controllers { /// <summary>
///
/// </summary>
[Route("[controller]/[action]")] public class ArticleController : Controller { private readonly IArticleRepository _articleRepository; /// <summary>
/// constructor /// </summary>
/// <param name="articleRepository"></param>
public ArticleController(IArticleRepository articleRepository) { _articleRepository = articleRepository; } /// <summary>
///
/// </summary>
/// <param name="article"></param>
/// <returns></returns>
[HttpPost] public T_Article Add([FromBody] T_Article article) { article.Id = _articleRepository.Insert(article); return article; } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet] public T_Article Get([FromQuery] long id) { return _articleRepository.GetById(id); } /// <summary>
///
/// </summary>
/// <param name="article"></param>
/// <returns></returns>
[HttpPost] public bool Update([FromBody] T_Article article) { return _articleRepository.Update(article) > 0; } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="status"></param>
/// <returns></returns>
[HttpPost] public bool UpdateStatus([FromQuery] long id, [FromQuery] int status) { return _articleRepository.DyUpdate(new { Id = id, Status = status }) > 0; } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet] public bool IsExist([FromQuery] long id) { return _articleRepository.IsExist(new { Id = id }); } /// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
[HttpGet] public IEnumerable<T_Article> Query([FromQuery] string key = "") { return _articleRepository.Query(new { Title = key }); } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet] public int Offline([FromQuery] long id) { return _articleRepository.OfflineArticle(id); } /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet] public int Online([FromQuery] long id) { return _articleRepository.OnlineArticle(id); } } }
能夠注意到的是,除了把DataAccess變成了Repository。其餘的代碼幾乎沒有改動。最後我還添加了倉儲自定義的接口的調用。
今天,咱們瞭解了動態倉儲的使用。它是一個很是方便的特性,能夠很是顯著的提高咱們寫代碼的效率,減小必定的代碼量,避免了不少「體力活」。讓咱們專一於業務!
下期預告:SmartSql中的事務,及AOP的使用