天天看點

你必須知道的 SmartSql !介紹

介紹

SmartSql = MyBatis + Cache(Memory | Redis) + R/W Splitting +Dynamic Repository + Diagnostics ......
簡潔、高效、高性能、擴充性、監控、漸進式開發!

她是如何工作的?

SmartSql 借鑒了 MyBatis 的思想,使用 XML 來管理 SQL ,并且提供了若幹個篩選器标簽來消除代碼層面的各種 if/else 的判斷分支。

SmartSql将管理你的 SQL ,并且通過篩選标簽來維護本來你在代碼層面的各種條件判斷,使你的代碼更加優美。

為什麼選擇 SmartSql ?

DotNet 體系下大都是 Linq 系的 ORM,Linq 很好,消除了開發人員對 SQL 的依賴。

但卻忽視了一點,SQL 本身并不複雜,而且在複雜查詢場景當中開發人員很難通過編寫Linq來生成良好性能的SQL,相信使用過EF的同學一定有這樣的體驗:“我想好了Sql怎麼寫,然後再來寫Linq,完了可能還要再檢視一下Linq輸出的Sql是什麼樣的“。這是非常糟糕的體驗。要想對Sql做絕對的優化,那麼開發者必須對Sql有絕對的控制權。另外Sql本身很簡單,為何要增加一層翻譯器呢?

SmartSql 從正式開源已曆經倆年多的時間,在生産環境經過若幹個微服務驗證。

同時也有一部分企業正在使用 SmartSql (如果您也在使用 SmartSql 歡迎送出issue)

Who is using SmartSql

目前已加入

NCC 未來( Roadmap-2019 ) SmartSql 也會持續加入一些新的特性來幫助開發者提升效率。歡迎送出 Issue https://github.com/dotnetcore/SmartSql/issues

那麼為什麼不是 Dapper,或者 DbHelper ?

Dapper 确實很好,并且又很好的性能,但是會讓給你的代碼裡邊充斥着 SQL 和各種判斷分支,這些将會使代碼維護難以閱讀和維護。另外 Dapper 隻提供了DataReader 到 Entity 的反序列化功能。而 SmartSql 提供了大量的特性來提升開發者的效率。

特性概覽

你必須知道的 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

你必須知道的 SmartSql !介紹

通過

開發人員僅需配置好資料庫連接配接即可生成解決方案所需的一切,包括但不限于:

  • 解決方案工程
  • 幫你 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           

你必須知道的 SmartSql !介紹
你必須知道的 SmartSql !介紹
你必須知道的 SmartSql !介紹
你必須知道的 SmartSql !介紹

SmartCode 生成的目錄結構

你必須知道的 SmartSql !介紹

讀寫分離

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

代理來啟用。以下是部分截圖。

監控執行指令

你必須知道的 SmartSql !介紹

檢視是否緩存,以及傳回的記錄數

你必須知道的 SmartSql !介紹

檢視執行的SQL語句

你必須知道的 SmartSql !介紹

事務

你必須知道的 SmartSql !介紹

異常

你必須知道的 SmartSql !介紹

異常堆棧跟蹤

你必須知道的 SmartSql !介紹

示例項目

SmartSql.Sample.AspNetCore

技術交流

點選連結加入QQ群【SmartSql 官方交流群】:

604762592

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

https://smartsql.net/