你必須知道的 SmartSql !

介紹

SmartSql = MyBatis + Cache(Memory | Redis) + R/W Splitting +Dynamic Repository + Diagnostics ......git


簡潔、高效、高性能、擴展性、監控、漸進式開發!github

她是如何工做的?

SmartSql 借鑑了 MyBatis 的思想,使用 XML 來管理 SQL ,而且提供了若干個篩選器標籤來消除代碼層面的各類 if/else 的判斷分支。算法

SmartSql將管理你的 SQL ,而且經過篩選標籤來維護原本你在代碼層面的各類條件判斷,使你的代碼更加優美。sql

爲何選擇 SmartSql ?

DotNet 體系下大都是 Linq 系的 ORM,Linq 很好,消除了開發人員對 SQL 的依賴。 但卻忽視了一點,SQL 自己並不複雜,並且在複雜查詢場景當中開發人員很難經過編寫Linq來生成良好性能的SQL,相信使用過EF的同窗必定有這樣的體驗:「我想好了Sql怎麼寫,而後再來寫Linq,完了可能還要再查看一下Linq輸出的Sql是什麼樣的「。這是很是糟糕的體驗。要想對Sql作絕對的優化,那麼開發者必須對Sql有絕對的控制權。另外Sql自己很簡單,爲什麼要增長一層翻譯器呢?chrome

SmartSql 從正式開源已歷經倆年多的時間,在生產環境通過若干個微服務驗證。 同時也有一部分企業正在使用 SmartSql (若是您也在使用 SmartSql 歡迎提交issue)Who is using SmartSql。 目前已加入 NCC。 將來(Roadmap-2019) SmartSql 也會持續加入一些新的特性來幫助開發者提高效率。歡迎提交 Issue github.com/dotnetcore/…docker

那麼爲何不是 Dapper,或者 DbHelper ?

Dapper 確實很好,而且又很好的性能,可是會讓給你的代碼裏邊充斥着 SQL 和各類判斷分支,這些將會使代碼維護難以閱讀和維護。另外 Dapper 只提供了DataReader 到 Entity 的反序列化功能。而 SmartSql 提供了大量的特性來提高開發者的效率。shell

特性概覽

SmartSql

動態倉儲

動態代理倉儲(SmartSql.DyRepository)組件是 SmartSql 很是獨特的功能,它能簡化 SmartSql 的使用。對業務代碼幾乎沒有侵入。能夠說使用 ISqlMapper 是原始方法,而 DyRepository 自動幫你實現這些方法。數據庫

DyRepository 的表現是隻須要定義倉儲接口,經過簡單配置就能自動實現這些接口並註冊到 IoC 容器中,使用時注入即刻獲取實現。原理是經過接口和接口方法的命名規則來獲取 SmartSql 的 xml 文件中的 Scope 和 SqlId ,用接口方法的參數做爲 Request ,經過 xml 中的 sql 自動判斷是查詢仍是執行操做,最後實現對 ISqlMapper 的調用。瀏覽器

0. 定義倉儲接口

public interface IUserRepository : IRepository<User, long>
    {
    }
複製代碼

1. 注入依賴

services.AddSmartSql()
                .AddRepositoryFromAssembly(options => { options.AssemblyString = "SmartSql.Starter.Repository"; });
複製代碼

2. 使用

public class UserService
    {
        IUserRepository userRepository;

        public UserService(IActivityRepository userRepository) {
            this.userRepository = userRepository;
        }
    }
複製代碼

SmartSql 最佳實踐 -> SmartCode

SmartCode

經過 SmartCode 開發人員僅需配置好數據庫鏈接便可生成解決方案所需的一切,包括但不限於:緩存

  • 解決方案工程
  • 幫你 restore 一下
 ReStore:
 Type: Process
 Parameters: 
 FileName: powershell
 WorkingDirectory: '{{Project.Output.Path}}'
 Args: dotnet restore
複製代碼
  • Docker
    • 構建 Docker 鏡像 & 運行實例
 BuildDocker:
 Type: Process
 Parameters:
 FileName: powershell
 WorkingDirectory: '{{Project.Output.Path}}'
 Args: docker build -t {{Project.Parameters.DockerImage}}:v1.0.0 .

 RunDocker:
 Type: Process
 Parameters:
 FileName: powershell
 WorkingDirectory: '{{Project.Output.Path}}'
 Args: docker run --name {{Project.Parameters.DockerImage}} --rm -d -p 8008:80 {{Project.Parameters.DockerImage}}:v1.0.0 .
複製代碼
  • 順便開啓個瀏覽器
 RunChrome:
 Type: Process
 Parameters:
 FileName: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
 CreateNoWindow: false
 Args: http://localhost:8008/swagger
複製代碼

Docker

SmartCode
SmartCode
SmartCode
SmartCode

SmartCode 生成的目錄結構

SmartCode-directory-structure

讀寫分離

SmartSql 讀寫分離特別簡便,僅需提供好配置便可:

<Database>
    <DbProvider Name="PostgreSql"/>
    <Write Name="WriteDB" ConnectionString="${Master}"/>
    <Read Name="ReadDb-1" ConnectionString="${Slave-0}" Weight="100"/>
    <Read Name="ReadDb-2" ConnectionString="${Slave-1}" Weight="100"/>
  </Database>
複製代碼

緩存

  • Lru 最近最少使用算法
  • Fifo 先進先出算法
  • RedisCacheProvider
  • 其餘繼承自ICacheProvider緩存類型都可
<Caches>
    <Cache Id="LruCache" Type="Lru">
      <Property Name="CacheSize" Value="10"/>
      <FlushOnExecute Statement="AllPrimitive.Insert"/>
      <FlushInterval Hours="1" Minutes="0" Seconds="0"/>
    </Cache>
    <Cache Id="FifoCache" Type="Fifo">
      <Property Name="CacheSize" Value="10"/>
    </Cache>
    <Cache Id="RedisCache" Type="${RedisCacheProvider}">
      <Property Name="ConnectionString" Value="${Redis}" />
      <FlushInterval Seconds="60"/>
    </Cache>
  </Caches>
   <Statement Id="QueryByLruCache" Cache="LruCache">
      SELECT Top 6 T.* From T_User T;
    </Statement>
複製代碼

類型處理器

SmartSql 內部實現了 DotNet 主要類型的類型處理器,而且提供了部分類型兼容的類型轉換處理器,同時還提供了比較經常使用的 JsonTypeHanlder 。

<TypeHandler PropertyType="SmartSql.Test.Entities.UserInfo,SmartSql.Test" Type="${JsonTypeHandler`}">
      <Properties>
        <Property Name="DateFormat" Value="yyyy-MM-dd mm:ss"/>
        <Property Name="NamingStrategy" Value="Camel"/>
      </Properties>
    </TypeHandler>
複製代碼

CUD 代碼生成

SmartSql 同時提供了 CUD 擴展函數幫助開發者生成好 CUD-SQL ,方便開發者直接使用,無需編寫任何配置。

public static TEntity GetById<TEntity, TPrimaryKey>(this ISqlMapper);
public static TPrimaryKey Insert<TEntity, TPrimaryKey>(this ISqlMapper sqlMapper, TEntity entity);
public static int DyUpdate<TEntity>(this ISqlMapper sqlMapper, object entity);
public static int Update<TEntity>(this ISqlMapper sqlMapper, TEntity entity);
public static int DeleteById<TEntity, TPrimaryKey>(this ISqlMapper sqlMapper, TPrimaryKey id);
public static int DeleteMany<TEntity, TPrimaryKey>(this ISqlMapper sqlMapper, IEnumerable<TPrimaryKey> ids);
複製代碼

Id 生成器

SnowflakeId

<IdGenerators>
    <IdGenerator Name="SnowflakeId" Type="SnowflakeId">
      <Properties>
        <Property Name="WorkerIdBits" Value="10"/>
        <Property Name="WorkerId" Value="888"/>
        <Property Name="Sequence" Value="1"/>
      </Properties>
    </IdGenerator>
</IdGenerators>
複製代碼
<Statement Id="Insert">
      <IdGenerator Name="SnowflakeId" Id="Id"/>
      INSERT INTO T_UseIdGenEntity
      (
      Id,
      Name
      )
      VALUES
      (
      @Id,
      @Name
      );
      Select @Id;
    </Statement>
複製代碼
var id = SqlMapper.ExecuteScalar<long>(new RequestContext
            {
                Scope = nameof(UseIdGenEntity),
                SqlId = "Insert",
                Request = new UseIdGenEntity()
                {
                    Name = "SmartSql"
                }
            });
複製代碼

DbSequence

<IdGenerators>
    <IdGenerator Name="DbSequence" Type="DbSequence">
      <Properties>
        <Property Name="Step" Value="10"/>
        <Property Name="SequenceSql" Value="Select Next Value For IdSequence;"/>
      </Properties>
    </IdGenerator>
</IdGenerators>

複製代碼
<Statement Id="InsertByDbSequence">
      <IdGenerator Name="DbSequence" Id="Id"/>
      INSERT INTO T_UseIdGenEntity
      (
      Id,
      Name
      )
      VALUES
      (
      @Id,
      @Name
      );
      Select @Id;
    </Statement>
複製代碼
var id = SqlMapper.ExecuteScalar<long>(new RequestContext
            {
                Scope = nameof(UseIdGenEntity),
                SqlId = "InsertByDbSequence",
                Request = new UseIdGenEntity()
                {
                    Name = "SmartSql"
                }
            });
複製代碼

AOP 事務

[Transaction]
        public virtual long AddWithTran(User user) {
            return _userRepository.Insert(user);
        }
複製代碼

事務嵌套

當出現事務嵌套時,子函數的事務特性註解將再也不開啓,轉而使用上級調用函數的事務

[Transaction]
        public virtual long AddWithTranWrap(User user) {
            return AddWithTran(user);
        }
複製代碼

BulkInsert

using (var dbSession= SqlMapper.SessionStore.Open())
            {
                var data = SqlMapper.GetDataTable(new RequestContext
                {
                    Scope = nameof(AllPrimitive),
                    SqlId = "Query",
                    Request = new { Taken = 100 }
                });
                data.TableName = "T_AllPrimitive";
                IBulkInsert bulkInsert = new BulkInsert(dbSession);
                bulkInsert.Table = data;
                bulkInsert.Insert();
            }
複製代碼

Skywalking 監控

SmartSql 目前支持 Skywalking 監控,經過安裝 SkyAPM-dotnet 代理來啓用。如下是部分截圖。

監控執行命令

Query

查看是否緩存,以及返回的記錄數

Query-Detail

查看執行的SQL語句

Query-Statement

事務

Transaction

異常

Error

異常堆棧跟蹤

Error-Detail

示例項目

SmartSql.Sample.AspNetCore

技術交流

點擊連接加入QQ羣【SmartSql 官方交流羣】:604762592

瞭解更多,請移步官方文檔

smartsql.net/

相關文章
相關標籤/搜索