SmartSql使用教程(2)——使用動態代理實現CURD

1、引言

  接着上一篇的教程,本章咱們繼續講SmartSql。今天的主題是動態倉儲。git

  老規矩,先上一個項目結構github

  從第二章開始。咱們將原來的單一項目作了一個分離。方便以後的更新。ide

  在這個結構中。本來上一章的DataAccess沒有了。取而代之的是Repository。這個就是動態倉儲的項目。接下來咱們從這個Repository項目開始說。這也是動態倉儲的核心。函數

2、Repository項目

1. Nuget依賴

  SmartSql有一個獨立的動態倉儲庫,即:SmartSql.DyRepository。若是你想使用動態倉儲,引用它就行啦。ui

2. 第一個倉儲接口

  引用完庫,接下來就是建立咱們的第一個倉儲接口—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 }
IArticleRepository

2.1 默認接口 IRepository

  看完代碼是否是發現和上一章的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);

2.2 SqlMap特性

  這個特性是用於指定Scope的配置。這個對應於Map中的Scope屬性。這裏我定義了「CustomScope」。那對應的Map中也將與之對應。以下圖:blog

  

2.3 Statement特性

  這個特性略微有點複雜,其中包含了6個屬性,接下來咱們一個個看。教程

2.3.1 Scope

  這個特性和SqlMap的Scope做用是同樣的。區別在於Statement的級別更高。

2.3.2 Id

  指定此函數所使用的Statement。依據是Id。例:

// 接口定義 [Statement(Id = "TestId")] int CustomStatementId();
<!-- Statement定義 -->
<Statement Id="TestId"> db script... </Statement>

2.3.3 Execute

   Execute是一個ExecuteBehavior枚舉,用於指定此函數執行Sql腳本的方式。

ExecuteBehavior
Auto ORM自動識別
Execute 返回影響行數,主要用於執行寫操做。
ExecuteScalar 返回第一行第一列的數據,主要用於返回自增主鍵和獲取結果數
Query 返回List
QuerySingle 返回第一行數據
GetDataTable 返回DataTable
GetDataSet 返回DataSet

 

  

 

 

 

 

 

 

 

 

 

2.3.4 Sql

  特殊場景下,能夠直接使用此屬性定義Sql腳本,而不用配置SqlMap。如IArticleRepository的OnlineArticle定義。

2.3.5 CommandType

  這個屬性是ADO.NET的CommandType枚舉。做用也徹底相同

2.3.6 SourceChoice

  指定數據源,能夠指定Write或Read。

3. Startup

  在上一章節中,咱們在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,方便用戶註冊指定的倉儲。

4. Controller的變化

  在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); } } }
ArticleController

  能夠注意到的是,除了把DataAccess變成了Repository。其餘的代碼幾乎沒有改動。最後我還添加了倉儲自定義的接口的調用。

5. 結語

  今天,咱們瞭解了動態倉儲的使用。它是一個很是方便的特性,能夠很是顯著的提高咱們寫代碼的效率,減小必定的代碼量,避免了不少「體力活」。讓咱們專一於業務!

示例代碼連接在這裏

 

下期預告:SmartSql中的事務,及AOP的使用

相關文章
相關標籤/搜索