資料庫分表

資料庫架構設計 架構演變 讀寫分離 當遇到資料庫瓶頸時,最簡單的做法是將資料庫做主從架構 主資料庫只有做寫入並同步資料到其他從資料庫,被同步的資料庫可以是n個只做讀取 垂直分庫 資料還是持續增長後,就到了要做垂直分庫的架構了,垂直分庫的意思可以想像成將同一個資料表內的資料欄位做整理,分成多個資料庫,也就可以將不同資料庫放在不同機器上。 資料庫分成使用者資料庫、訂單資料庫、商品資料庫 水平分庫 資料量再更大量,最後的解決方案就是水平分庫,會將相同的資料表分成多個表 table01、table02、table03 Sharding中介軟體 要做到水平分庫會建議使用已經發展成熟的Sharding中介軟體 Sharding架構 有區分成兩種 Porxy架構 應用集成架構

June 4, 2023

Pub

快速介紹flutter安裝的函式庫 intl 轉成指定地區的日期格式 flutter pub add intl uuid 建立guid flutter pub add uuid transparent_image 當圖還沒有載入時可以有透明背景圖使用 flutter pub add transparent_image riverpod 是一個狀態管理的工具,當開始寫flutter就會遇到跟現在流行的框架vue/react一樣的問題,當我要傳遞資料時要一直往子層傳參數,才能將資料傳進去,這時riverpod就是來解決這個問題的 另一個社群討論度高的是Getx。 flutter pub add riverpod 要在需要的區塊上加上ProviderScope,下列範例就是所有區塊都要可以使用 void main() { runApp(const ProviderScope( child: MyApp(), )); } 新增一個檔案並建立供應方 import 'package:flutter_riverpod/flutter_riverpod.dart'; final demoProvider = Provider((ref) { return false; }); = & ConsumerWidget StatelessWidget改成ConsumerWidget StatefulWidget改成ConsumerStatefulWidget 建立接收方 //在要使用資料的地方使用下列 //當資料不會改變時可以使用read來取代watch,但官方建議一律使用watch,以免當資料異動時,沒有修改到 final demo = ref.watch(demoProvider); //接下來即可使用demo來做後續事情 http 進行restful api,透過這個套件可以發送請求到api並接收回傳 flutter pub add http image_picker 使用系統得相機功能,在ios中記得查看文件檔,將key放入文件所說明的plist檔案中 flutter pub add image_picker...

May 28, 2023

Widget

佈局的屬性 Column 由上至下的排序 Row 由左至右的排序 Expanded 只能使用在繼承Flex以下的Widget,常使用在Cloumn或row的子項 因為有些widget不會限制長寬,要有expanded來將最大值限制在手機區塊內 ListView 使用ListView是可以有滾動效果 可以透過builder提升效能 使用方法為 ListView.builder(item: list.length, itemBuilder: (ctx,index){list[index].title}) Spacer 可以在任何row,colume使用 佔用剩餘所有空間的意思 TextField 輸入框 要記得關閉 DropdownButton 下拉式選單 Dismissable key參數必要,才能確定要滑動刪除哪筆資料 也可以分為向左滑動與向右滑動,執行不同功能 滑動刪除效果 Snackbar 會在螢幕下面調出一個訊息框 在Scaffold階層底下可以使用 ScaffoldMessenger.of(context).showSnackBar( const SnackBar( duration: Duration(seconds: 3), content: Text('Expense deleted'), ), ); InkWell 可以讓沒有事件的元件增加點擊事件之類的功能 與GestureDetector的差別在於 GestureDetector提供更多的點擊事件,InkWell提供點擊特效 兩者差異出處 Stack 類似Column與Row,但是可以讓所有子元件重疊在一起 SwitchListTile 有大標題與子標題的開關 Drawer 側邊欄,可以在裡面放Column就可以實現側邊欄的菜單 WillPopScope 當用戶離開用任何方式離開當下頁面就會觸發,不管是實體按鈕或是虛擬按鈕 onWillPop:true 允許返回false不允許返回 Form 有額外的驗證功能,並顯示在畫面 在form裡面要輸入框時要用TextFormField取代TextField 只要在Form裏面,要使用的組件基本上都會有form關鍵字 Dismissible 新增滑動移除的功能,需要增加key值才能知道要動作的是哪一個項目 後續慢慢補上

May 28, 2023

First

Ha Today is a good day

May 19, 2023

dotnet6 Hangfire範例

目的 在windows系統上想執行排程有兩個選擇 使用windows工作排程器執行exe檔 透過Hangfire進行排程管理 此次教學說明如何使用Hangfire執行排程 建立新專案 選擇ASP.NET Core Web API專案範本,並執行下一步 設定新的專案 命名你的專案名稱,並選擇專案要存放的位置。 其他資訊 直接進行下一步 NuGet加入套件 Hangfire Hangfire.InMemory 編輯Program.cs檔 using Hangfire; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); //註冊hangfire並且使用記憶體保存排程, //預設所下載的HangFire套件可以使用sqlserver,可透過config.UseSqlServerStorage();,但需要設定 builder.Services.AddHangfire(config => { config.UseInMemoryStorage(); }); //註冊hangfire要使用的伺服器,伺服器就是上面所寫的使用記憶體當伺服器 builder.Services.AddHangfireServer(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); //使用hangfire內建的儀表板 app.UseHangfireDashboard(); app....

October 11, 2022

dotnet6 HttpClient單元測試範例

目的 面試的時候被問到要如何做包含外部api的單元測試問題,稍微查一下其實很簡單,怎麼當下答不出來呢? 主要有兩種方式,一種為.net core 2.1以後有提供IHttpClientFactory的介面可以使用。 建立新專案 選擇ASP.NET Core Web API專案範本,並執行下一步 設定新的專案 命名你的專案名稱,並選擇專案要存放的位置。 其他資訊 直接進行下一步 建立資料夾 編輯Program.cs檔案 註冊AddHttpClient。 builder.Services.AddHttpClient(); 新增一個類別檔 加入前 加入後 建構子注入 將註冊的httpclient透過建構子注入 readonly IHttpClientFactory _httpClientFactory; public CallAPIServices(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } 加入前 加入後 新增方法 新增一個會去發外部請求的方法,模擬當有包含第三方api時如何測試 public async Task<string> Get() { var client = _httpClientFactory.CreateClient(); var response = await client.GetAsync("https://example.com"); if (response.IsSuccessStatusCode) { var responseString = await response.Content.ReadAsStringAsync(); return responseString; } return ""; } 新增測試專案 對方案點選右鍵>加入>新增專案 設定新的專案 替測試專案命名,建議命名規則以.Tests做結尾 其他資訊 專案架構需要與要測試的專案相同 加入參考 將要測試的專案加入測試專案...

October 10, 2022

dotnet6 Moq範例

目的 進行單元測試時,可以隔絕依賴的項目。 建立新專案 選擇ASP.NET Core Web API專案範本,並執行下一步 設定新的專案 命名你的專案名稱,並選擇專案要存放的位置。 其他資訊 直接進行下一步 建立新的類別庫 進行命名時通常會與要測試的專案同名並加上結尾.Tests,以此範例就會變成MoqExample.Tests NuGet加入套件 針對xUnitExample.Tests加入相關套件 xunit xunit.runner.visualstudio Microsoft.NET.Test.Sdk coverlet.collector Moq 針對MoqExample.Tests類別庫加入參考 引用要測試的專案,才能將測試與實際專案切分開來 新增WeatherForecastControllerTests.cs類別檔 刪除預設的類別檔(Class1.cs),並在MoqExample.Tests專案新增對應資料夾,與類別檔並加結尾Tests。 編輯WeatherForecastControllerTests.cs類別檔 測試都會分三個階段 Arrange:準備階段,包含初始化相關資料 Act:執行測試方法後所取得的結果 Assert:驗證Act取得的結果是否符合預期結果 這次要測試的是controller,有注入Ilogger,如何將Ilogger隔開的關鍵就是使用Moq這個套件 using Microsoft.Extensions.Logging; using Moq; using MoqExample.Controllers; using Xunit; namespace MoqExample.Tests.Controllers { public class WeatherForecastControllerTests { [Fact] public void Get() { //Arrange //透過mock將外界的介面包起來 var MockLogger = new Mock<ILogger<WeatherForecastController>>(); //當成物件傳入controller,代替實際的介面 var Controllers = new WeatherForecastController(MockLogger.Object); //Act //執行要測試的函式 var Results = Controllers.Get(); //Assert //確認結果不為null Assert....

October 9, 2022

dotnet6 NLog進階範例

目的 在寫nlog.config檔案時覺得怎麼有點複雜,我只是需要簡單的設定檔就好了,最後決定透過appsetting來做設定 將log文件採用非同步寫入,可大幅提升效能 建立新專案 選擇ASP.NET Core Web API專案範本,並執行下一步 設定新的專案 命名你的專案名稱,並選擇專案要存放的位置。 其他資訊 直接進行下一步 4.NuGet加入套件 NLog NLog.Web.AspNetCore 編輯Program.cs檔 using NLog; using NLog.Web; //初始化NLog var logger = LogManager.Setup() //載入Configuration並且讀取appsetting來使用 .LoadConfigurationFromAppSettings() .GetCurrentClassLogger(); try { logger.Debug("init main"); var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Logging.ClearProviders(); builder.Host.UseNLog(); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); //以下省略 編輯appsetting.json 設定NLog,包含 throwConfigExceptions:設定檔錯誤時會跳exception 使用非同步方式寫入檔案 targets:設定輸出的格式,例如txt檔案或是Console顯示 rules:什麼情況要做什麼動作,例如log名稱為Microsoft.AspNetCore最小等級是warn時寫到Console ILogger NLog Level 0 Trace Trace Level 1 Debug Debug Level 2 Information Info Level 3 Warning Warn Level 4 Error Error Level 5 Critical Fatal Level 6 None NLog沒有 { "NLog": { "throwConfigExceptions": true, "targets": { "async": true, "logfile": { "type": "File", "fileName": "c:/temp/nlog-${shortdate}....

October 8, 2022

dotnet6 xUnit範例

目的 單元測試 建立新專案 選擇ASP.NET Core Web API專案範本,並執行下一步 設定新的專案 命名你的專案名稱,並選擇專案要存放的位置。 其他資訊 直接進行下一步 建立新的類別庫 進行命名時通常會與要測試的專案同名並加上結尾.Tests,以此範例就會變成xUnitExample.Tests NuGet加入套件 針對xUnitExample.Tests加入相關套件 xunit xunit.runner.visualstudio Microsoft.NET.Test.Sdk coverlet.collector 新增Calculator.cs類別檔 在xUnitExample專案新增Calculator.cs類別檔 新增一個簡單的加法函式 public static class Calculator { public static double Add(int a, int b) { return a + b; } } 針對xUnitExample.Tests類別庫加入參考 引用要測試的專案,才能將測試與實際專案切分開來 新增CalculatorTests.cs類別檔 刪除預設的類別檔(Class1.cs),建立對應的資料夾以及類別檔案,並在結尾加上Tests 編輯CalculatorTests.cs類別檔 測試都會分三個階段 Arrange:準備階段,包含初始化相關資料 Act:執行測試方法後所取得的結果 Assert:驗證Act取得的結果是否符合預期結果 public class CalculatorTests { //告訴編譯器要執行的測試方法 [Fact] public void Add_() { //Arrange double Expected = 20; //Act var Actual = Calculator.Add(5, 15); //Assert Assert....

October 8, 2022

dotnet6 NLog範例

目的 在webapi專案下使用NLog套件 建立新專案 選擇ASP.NET Core Web API專案範本,並執行下一步 設定新的專案 命名你的專案名稱,並選擇專案要存放的位置。 其他資訊 直接進行下一步 NuGet加入套件 NLog NLog.Web.AspNetCore 新增nlog.config檔案 在根目錄新增nlog.config檔案 nlog.config寫入程式 在nlog.config寫入官方範例 <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="Info" internalLogFile="c:\temp\internal-nlog-AspNetCore.txt"> <!-- enable asp.net core layout renderers --> <extensions> <add assembly="NLog.Web.AspNetCore"/> </extensions> <!-- the targets to write to --> <targets> <!-- File Target for all log messages with basic details --> <target xsi:type="File" name="allfile" fileName="c:\temp\nlog-AspNetCore-all-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" /> <!-- File Target for own log messages with extra web details using some ASP....

October 8, 2022