欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解MySqlBulkLoader的使用

 更新時(shí)間:2022年07月14日 10:53:35   作者:搬磚滴  
這篇文章主要介紹了MySqlBulkLoader的使用?,本文分兩部分來(lái)寫(xiě),第一部分寫(xiě)一下MySqlBulkLoader的使用,第二部分記錄使用過(guò)程中出現(xiàn)的問(wèn)題,需要的朋友可以參考下

mysql數(shù)據(jù)庫(kù):最近要寫(xiě)一個(gè)服務(wù),跨庫(kù)數(shù)據(jù)同步,目前數(shù)據(jù)量大約一萬(wàn),以后會(huì)越來(lái)越多,考慮到擴(kuò)展性,數(shù)據(jù)的插入操作就采用了MySqlBulkLoader。本文分兩部分來(lái)寫(xiě),第一部分寫(xiě)一下MySqlBulkLoader的使用,第二部分記錄使用過(guò)程中出現(xiàn)的問(wèn)題。

一、MySqlBulkLoader的使用

我們先來(lái)定義個(gè)數(shù)據(jù)表student,表結(jié)構(gòu)如下:

創(chuàng)建一個(gè)core控制臺(tái)項(xiàng)目,相關(guān)代碼如下:

入口代碼:

using System;
using System.Collections.Generic;
namespace MySqlBulkLoaderDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //裝載30個(gè)數(shù)據(jù)
            List<Student> stuList = new List<Student>();
            for (int i = 0; i < 30; i++)
            {
                stuList.Add(
                new Student
                {
                    Guid = Guid.NewGuid().ToString(),
                    Name = "QXH",
                    Age = new Random().Next(1, 30)
                });
            }
            //調(diào)用MySqlBulkLoader,往student表中插入stuList
            int insertCount = MySqlBulkLoaderHelper.BulkInsert<Student>(stuList, "student");
            Console.WriteLine($"成功插入{insertCount}條數(shù)據(jù)");
            Console.ReadKey();
        }
    }
}

定義一個(gè)Student映射類(lèi):

using System;
using System.Collections.Generic;
using System.Text;

namespace MySqlBulkLoaderDemo
{
    public class Student
    {
        public string Guid { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

定義一個(gè)MySqlBulkLoaderHelper類(lèi),用于存放相關(guān)方法:

using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;

namespace MySqlBulkLoaderDemo
{
    public class MySqlBulkLoaderHelper
    {
        const string ConnectionString = "server=localhost;port=3306;user=root;password=123456;database=mysql;SslMode = none;AllowLoadLocalInfile=true";
        public static int BulkInsert<T>(List<T> entities, string tableName)
        {
            DataTable dt = entities.ToDataTable();
            using (MySqlConnection conn = new MySqlConnection())
            {
                conn.ConnectionString = ConnectionString;
                if (conn.State != ConnectionState.Open)
                {
                    conn.Open();
                }

                if (tableName.IsNullOrEmpty())
                {
                    var tableAttribute = typeof(T).GetCustomAttributes(typeof(TableAttribute), true).FirstOrDefault();
                    if (tableAttribute != null)
                        tableName = ((TableAttribute)tableAttribute).Name;
                    else
                        tableName = typeof(T).Name;
                }

                int insertCount = 0;
                string tmpPath = Path.Combine(Path.GetTempPath(), DateTime.Now.Ticks.ToString() + "_" + Guid.NewGuid().ToString() + ".tmp");
                string csv = dt.ToCsvStr();
                File.WriteAllText(tmpPath, csv, Encoding.UTF8);

                using (MySqlTransaction tran = conn.BeginTransaction())
                {
                    MySqlBulkLoader bulk = new MySqlBulkLoader(conn)
                    {
                        FieldTerminator = ",",
                        FieldQuotationCharacter = '"',
                        EscapeCharacter = '"',
                        LineTerminator = "\r\n",
                        FileName = tmpPath,
                        Local = true,
                        NumberOfLinesToSkip = 0,
                        TableName = tableName,
                        CharacterSet = "utf8"
                    };
                    try
                    {
                        bulk.Columns.AddRange(dt.Columns.Cast<DataColumn>().Select(colum => colum.ColumnName).ToList());
                        insertCount = bulk.Load();
                        tran.Commit();
                    }
                    catch (MySqlException ex)
                    {
                        if (tran != null)
                            tran.Rollback();

                        throw ex;
                    }
                }
                File.Delete(tmpPath);
                return insertCount;
            }

        }
    }
}

定義一個(gè)幫助類(lèi)ExtentionHelper,主要是擴(kuò)展方法:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace MySqlBulkLoaderDemo
{
    public static class ExtentionHelper
    {
        /// <summary>
        /// 將對(duì)象序列化成Json字符串
        /// </summary>
        /// <param name="obj">需要序列化的對(duì)象</param>
        /// <returns></returns>
        public static string ToJson(this object obj)
        {
            return JsonConvert.SerializeObject(obj);
        }
        /// <summary>
        /// 將Json字符串轉(zhuǎn)為DataTable
        /// </summary>
        /// <param name="jsonStr">Json字符串</param>
        /// <returns></returns>
        public static DataTable ToDataTable(this string jsonStr)
        {
            return jsonStr == null ? null : JsonConvert.DeserializeObject<DataTable>(jsonStr);
        }
        /// <summary>
        /// 將IEnumerable'T'轉(zhuǎn)為對(duì)應(yīng)的DataTable
        /// </summary>
        /// <typeparam name="T">數(shù)據(jù)模型</typeparam>
        /// <param name="iEnumberable">數(shù)據(jù)源</param>
        /// <returns>DataTable</returns>
        public static DataTable ToDataTable<T>(this IEnumerable<T> iEnumberable)
        {
            return iEnumberable.ToJson().ToDataTable();
        }
        /// <summary>
        /// 判斷是否為Null或者空
        /// </summary>
        /// <param name="obj">對(duì)象</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this object obj)
        {
            if (obj == null)
                return true;
            else
            {
                string objStr = obj.ToString();
                return string.IsNullOrEmpty(objStr);
            }
        }

        /// <summary>
        ///將DataTable轉(zhuǎn)換為標(biāo)準(zhǔn)的CSV字符串
        /// </summary>
        /// <param name="dt">數(shù)據(jù)表</param>
        /// <returns>返回標(biāo)準(zhǔn)的CSV</returns>
        public static string ToCsvStr(this DataTable dt)
        {
            //以半角逗號(hào)(即,)作分隔符,列為空也要表達(dá)其存在。
            //列內(nèi)容如存在半角逗號(hào)(即,)則用半角引號(hào)(即"")將該字段值包含起來(lái)。
            //列內(nèi)容如存在半角引號(hào)(即")則應(yīng)替換成半角雙引號(hào)("")轉(zhuǎn)義,并用半角引號(hào)(即"")將該字段值包含起來(lái)。
            StringBuilder sb = new StringBuilder();
            DataColumn colum;
            foreach (DataRow row in dt.Rows)
            {
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    colum = dt.Columns[i];
                    if (i != 0) sb.Append(",");
                    if (colum.DataType == typeof(string) && row[colum].ToString().Contains(","))
                    {
                        sb.Append("\"" + row[colum].ToString().Replace("\"", "\"\"") + "\"");
                    }
                    else sb.Append(row[colum].ToString());
                }
                sb.AppendLine();
            }

            return sb.ToString();
        }
    }
}

完整項(xiàng)目:MySqlBulkLoaderDemo

運(yùn)行結(jié)果如下:

二、MySqlBulkLoader使用過(guò)程中出現(xiàn)的問(wèn)題

上邊已經(jīng)完整了介紹了MySqlBulkLoader的使用,但是在使用過(guò)程中出現(xiàn)了很多問(wèn)題,主要集中在兩方面,第一個(gè)方面是Mysql數(shù)據(jù)庫(kù)不支持加載本地文件數(shù)據(jù);第二個(gè)方面是我的數(shù)據(jù)庫(kù)在阿里云服務(wù)器上,而代碼在本地,換句話說(shuō)數(shù)據(jù)庫(kù)和項(xiàng)目是分別放在不同服務(wù)器上的。

1、Mysql數(shù)據(jù)庫(kù)不支持加載本地文件數(shù)據(jù)

(1)MySQLBulkLoader原理?

我們結(jié)合SQLBulkCopy來(lái)說(shuō),用過(guò)SqlServer數(shù)據(jù)庫(kù)的都熟悉SQLBulkCopy,很方便,可以直接將datatable中的數(shù)據(jù)批量導(dǎo)入到數(shù)據(jù)庫(kù)。與SQLBulkCopy不同,MySQLBulkLoader也稱(chēng)為L(zhǎng)OAD DATA INFILE,他要從文件讀取數(shù)據(jù),所以我們需要將我們的數(shù)據(jù)集(如上邊的List<Student>)保存到文件,然后再?gòu)奈募锩孀x取。而對(duì)于Mysql來(lái)說(shuō),為了數(shù)據(jù)庫(kù)的安全,本地導(dǎo)入文件的配置沒(méi)有開(kāi)啟,所以使用MySQLBulkLoader批量導(dǎo)入數(shù)據(jù)庫(kù),就需要mysql數(shù)據(jù)庫(kù)支持本地導(dǎo)入文件。否則會(huì)出現(xiàn)以下錯(cuò)誤:

The used command is not allowed with this MySQL version

(2)解決方案

mysql數(shù)據(jù)庫(kù)開(kāi)啟允許本地導(dǎo)入數(shù)據(jù)的配置,命令如下:

SET GLOBAL local_infile=1;//1表示開(kāi)啟,0表示關(guān)閉

查看該配置的狀態(tài)命令如下:

SHOW VARIABLES LIKE '%local%';

在項(xiàng)目里面的數(shù)據(jù)庫(kù)連接字符串做設(shè)置

數(shù)據(jù)庫(kù)連接字符串要加上”AllowLoadLocalInfile=true“,如下:

const string ConnectionString = "server=localhost;port=3306;user=root;password=123456;database=mysql;SslMode = none;AllowLoadLocalInfile=true";

2、數(shù)據(jù)庫(kù)和項(xiàng)目是分別放在不同服務(wù)器上

(1)問(wèn)題描述

數(shù)據(jù)庫(kù)和項(xiàng)目是分別放在不同服務(wù)器上,會(huì)造成以下問(wèn)題:

System.NotSupportedException
HResult=0x80131515
Message=To use MySqlBulkLoader.Local=true, set AllowLoadLocalInfile=true in the connection string. See https://fl.vu/mysql-load-data

(2)原因

因?yàn)轫?xiàng)目中將數(shù)據(jù)集生成的文件保存在了項(xiàng)目所在的服務(wù)器,另一個(gè)服務(wù)器上的數(shù)據(jù)庫(kù)在插入數(shù)據(jù)操作時(shí),找不到數(shù)據(jù)集文件,導(dǎo)致的錯(cuò)誤

(3)解決方法

方法很簡(jiǎn)單,因?yàn)閿?shù)據(jù)庫(kù)并不在項(xiàng)目所在的服務(wù)器,所以MySqlBulkLoader中要設(shè)置Local = true讀取本地文件,進(jìn)行導(dǎo)入。具體代碼如下:

(4)總結(jié)

如果你的項(xiàng)目和數(shù)據(jù)庫(kù)在一臺(tái)服務(wù)器上,那么就不會(huì)出現(xiàn)該問(wèn)題。

相關(guān)文章

  • 詳解MySQL到SelectDB的實(shí)時(shí)同步策略

    詳解MySQL到SelectDB的實(shí)時(shí)同步策略

    MySQL?到?SelectDB?的實(shí)時(shí)數(shù)據(jù)同步技術(shù),通過(guò)?NineData?的數(shù)據(jù)復(fù)制控制臺(tái),僅需輕點(diǎn)鼠標(biāo),即可輕松完成?MySQL?到?SelectDB?的同步任務(wù)配置,這篇文章主要介紹了MySQL到SelectDB的實(shí)時(shí)同步策略,需要的朋友可以參考下
    2023-09-09
  • MySQL安裝與配置:手工配置MySQL(windows環(huán)境)過(guò)程

    MySQL安裝與配置:手工配置MySQL(windows環(huán)境)過(guò)程

    這篇文章主要介紹了MySQL安裝與配置:手工配置MySQL(windows環(huán)境)過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 詳解MySQL幻讀及如何消除

    詳解MySQL幻讀及如何消除

    這篇文章主要介紹了詳解MySQL 幻讀及解決方法,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-03-03
  • 超詳細(xì)匯總21個(gè)值得收藏的mysql優(yōu)化實(shí)踐

    超詳細(xì)匯總21個(gè)值得收藏的mysql優(yōu)化實(shí)踐

    這篇文章主要分享的是超詳細(xì)匯總21個(gè)值得收藏的mysql優(yōu)化實(shí)踐,對(duì)正在學(xué)習(xí)的同學(xué)有一定的參考價(jià)值,需要的同學(xué)可以參考一下
    2022-01-01
  • 超全MySQL學(xué)習(xí)筆記

    超全MySQL學(xué)習(xí)筆記

    本文詳細(xì)介紹了MySQL索引優(yōu)化、鎖和事物等學(xué)習(xí)記錄,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • MySQL主從延遲現(xiàn)象及原理分析詳解

    MySQL主從延遲現(xiàn)象及原理分析詳解

    今天小編就為大家分享一篇關(guān)于MySQL主從延遲現(xiàn)象及原理分析詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-02-02
  • 詳解mysql數(shù)據(jù)庫(kù)中文亂碼問(wèn)題

    詳解mysql數(shù)據(jù)庫(kù)中文亂碼問(wèn)題

    這篇文章主要介紹了詳解mysql數(shù)據(jù)庫(kù)中文亂碼問(wèn)題的相關(guān)資料,需要的朋友可以參考下
    2017-10-10
  • 在C#和MySQL中存取中文字符時(shí)避免亂碼的方法

    在C#和MySQL中存取中文字符時(shí)避免亂碼的方法

    這篇文章主要介紹了在C#和MySQL中存取中文字符時(shí)避免亂碼的方法,主要還是老辦法先轉(zhuǎn)換成Unicode編碼,需要的朋友可以參考下
    2015-05-05
  • 解析如何加快mysql編譯的速度

    解析如何加快mysql編譯的速度

    本篇文章是對(duì)如何加快mysql編譯的速度進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • 數(shù)據(jù)庫(kù)管理中19個(gè)MySQL優(yōu)化方法

    數(shù)據(jù)庫(kù)管理中19個(gè)MySQL優(yōu)化方法

    小編給大家總結(jié)了19條非常實(shí)用的MySQL數(shù)據(jù)庫(kù)優(yōu)化方法,這是每個(gè)服務(wù)器管理人員都必須知道的,一起學(xué)習(xí)下。
    2017-11-11

最新評(píng)論