1. 程式人生 > >Dapper操作MySQL資料庫獲取JSON資料中文亂碼

Dapper操作MySQL資料庫獲取JSON資料中文亂碼

前言

在專案中利用Dapper將JSON資料儲存到MySQL資料庫,結果發現JSON資料中的中文亂碼,特此記錄,希望對儲存JSON的童鞋能有所幫助,文中若有錯誤之處,還望批評指正。

Dapper獲取JSON資料亂碼(MySQL)

為了引出最終問題出在什麼地方,我們重頭開始進行講解,首先我們給出如下測試實體以及在資料庫中的表,如下:

    public class Test
    {
        public int Id { get; set; }
        public string Data { get; set; }
    }

為了資料操作方便,我們通過包【Dapper.SimpleCRUD】來操作,插入資料和查詢資料如下:

static void Main(string[] args)
{
    SimpleCRUD.SetDialect(SimpleCRUD.Dialect.MySQL);
    DefaultTypeMap.MatchNamesWithUnderscores = true;

    using (var conn = new MySqlConnection(@".....;charset=utf8mb4;SslMode=none;"))

    {
        var id = conn.Insert(new Test()
        {
            Data = JsonConvert.SerializeObject(new
            {
                name = "汪鵬"
            })
         });

        var result = conn.Get<Test>(id);
    }

    Console.ReadKey();
}

如上一切正常,接下來我們將儲存JSON資料的列型別修改為json,然後再來進行如上操作,結果會發現獲取資料中文將亂碼:

 

剛開始我猜想難道用的包【Dapper.SimpleCRUD】在對映時出了問題,於是我用Dapper進行如下查詢,依然會出現如上中文亂碼:

var result = conn.QueryFirstOrDefault<Test>("select * from Test where Id = @id", new { id });

 所以由上基本可以得出結論:針對MySQL中的型別json,若json資料中存在中文,則利用Dapper查詢時將出現亂碼。那麼如何解決這個問題呢?於是乎,在新增資料時,我將中文進行URL編碼,再查詢時進行解碼即可,如下:

var id = conn.Insert(new Test()
{
    Data = JsonConvert.SerializeObject(new
    {
        name = HttpUtility.UrlEncode("汪鵬")
    })
 });

當然,上述解決方案以實際專案業務而去解決,我們專案需要獲取到JSON資料中的中文然後通過URL傳輸,免去請求介面再去獲取所儲存的名稱。到此我們瞭解了Dapper針對json資料型別將導致查詢中文亂碼的問題,但是其根本原因是什麼呢?上述連線MySQL的驅動,是使用Oracle官方所提供的驅動且為最新版本,如下:

我們知道通過EF Core操作MySQL資料庫,若是利用官方包有一堆問題存在,所以大多都是採用的包【Pomelo.EntityFrameworkCore.MySql】,因為裡面包含【MySqlConnector】,換句話說也就存在MySQL的驅動連線,所以這裡我們嘗試利用該包替換上述【MySql.Data】包,結果發現中文不再亂碼。

總結

綜上所述,我們需要注意的是若利用官方驅動包【MySql.Data】,當配置MySQL中的列型別為json時,若json資料中存在中文,則利用Dapper查詢時將會出現中文亂碼,需要進行轉換,上述在資料庫連線字串中我們設定為utf8mb4,所以理論上應該和編碼沒有任何關係。