為什么想要使用 smartsql ? 從 MyBatis 過來的,更多的場景,適合手寫 SQL ,而不是使用 EF 這樣的完全體 ORM。
而 SQL 語句又希望寫在 xml 中,而不是代碼中。
文檔:
介紹 | SmartSql
首先吐槽一句,文檔寫得相當不清楚。可以參考 SmartSql 源碼中的 sample 來理解如何使用,以下基本是最簡可用配置,加一些踩坑說明。
1 SmartSqlMapConfig.xml
<SmartSqlMapConfig xmlns="http://SmartSql.net/schemas/SmartSqlMapConfig.xsd">
<Settings IgnoreParameterCase="false" ParameterPrefix="$" IsCacheEnabled="true" EnablePropertyChangedTrack="true"/>
<Database>
<DbProvider Name="MySql"/>
<Write Name="WriteDB" ConnectionString="${ConnectionString}"/>
<Read Name="ReadDb-1" ConnectionString="${ConnectionString}" Weight="100"/>
</Database>
<SmartSqlMaps>
<SmartSqlMap Path="Mappers" Type="Directory"></SmartSqlMap>
</SmartSqlMaps>
</SmartSqlMapConfig>
坑1 SQL 語句中的前綴
寫的 SQL 大概是這個樣子:
SELECT * FROM t_user WHERE c_id= @id
這里的 @id
是需要被替換的參數,那前綴是 @,?,#,: 中的哪一個呢?文檔沒有說,源碼 sample 中用的是 @,於是,我也用 @ ,結果,死活生成不了正確的 SQL。
看源碼:
死活生成不了正確的 SQL 的解釋是:默認情況下,Sqlite 使用的是 @ ,而 MySql 使用的是 ? . 而我配的是 $,所有,用 @ 當然不行啦。
可是,一開始鬼知道。
可以修改配置嗎?可以的,在 SmartSqlMapConfig.xml 中,ParameterPrefix
就是干這個的。
還可以單獨給每個數據源進行配置:
<Database>
<DbProvider Name="SQLite" ParameterPrefix="#"/>
<Write Name="WriteDB" ConnectionString="${ConnectionString}"/>
<Read Name="ReadDb" ConnectionString="${ConnectionString}" Weight="100"/>
</Database>
對應的 SQL 就是:
SELECT * FROM T_User WHERE Id = #id
這是我遇到的最大的坑。
要學 MyBatis 就好好學嘛,只有 #{id} 和 @{id} 兩種(功能上有區別),多簡單直觀。
坑2 SmartSqlMaps 的定義
<SmartSqlMaps>
<SmartSqlMap Path="Mappers" Type="Directory"></SmartSqlMap>
</SmartSqlMaps>
這里定義了 SQL 語句對應的 XML 在 Mappers 這個文件夾中,但是,這個文件夾是需要拷貝輸出到輸出目錄的。也沒見文檔哪里提了。
你需要在 csproj 文件中加這么一段:
<ItemGroup>
<None Update="SmartSqlMapConfig.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Mappers\*.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
NUGET 包
在 net core 中使用 smartsql 需要安裝哪些 NUGET 包?
文檔的入門章節,讓你安裝的是 SmartSql.Schema
,其它的呢?自己摸索。
如果使用 MySql(asp.net core 下),大概是這些:
<ItemGroup>
<PackageReference Include="MySql.Data" Version="8.0.21" />
<PackageReference Include="SmartSql" Version="4.1.56" />
<PackageReference Include="SmartSql.DIExtension" Version="4.1.56" />
<PackageReference Include="SmartSql.DyRepository" Version="4.1.56" />
<PackageReference Include="SmartSql.InvokeSync" Version="4.1.56" />
<PackageReference Include="SmartSql.Schema" Version="4.1.30" />
</ItemGroup>
Startup 中的配置
services.AddSmartSql((sp, builder) =>
{
// 使用配置讀取鏈接字符串(而不是將鏈接字符串寫在了 SmartSqlMapConfig.xml 中)
builder.UseProperties(Configuration);
})
.AddRepositoryFromAssembly(o =>
{
// 掃描 Repository
o.AssemblyString = "SmartSqlDemo";
o.Filter = (type) => string.Equals(type.Namespace, "SmartSqlDemo.SmartSqlRepositories", System.StringComparison.Ordinal);
})
// 添加 async 支持
.AddInvokeSync(options => { })
;
其它需要注意的問題
1 連接字符串
mysql 連接字符串,需要設置 AllowUserVariables=True;
2 Repository 接口的命名
默認情況下,使用 I{Scope}Repository 的方式,也可以自己配。
其它技巧
如果想要查看 smartsql 生成的 SQL 語句,將日志輸出級別調整為 Debug
更多關於前綴的問題,可以看這篇詳細分析:
dotnet 關於 SmartSql 的 SQL 語句的屬性替換前綴說明