{"id":10326,"date":"2026-06-18T10:29:12","date_gmt":"2026-06-18T01:29:12","guid":{"rendered":"https:\/\/www.auctionpro.co.kr\/?p=10326"},"modified":"2026-06-19T18:31:11","modified_gmt":"2026-06-19T09:31:11","slug":"%ed%95%ad%ea%b3%b5%ec%82%ac-%ec%a0%95%eb%b3%b4-%ec%ba%90%ec%8b%b1-%ec%83%98%ed%94%8c","status":"publish","type":"post","link":"https:\/\/www.auctionpro.co.kr\/?p=10326","title":{"rendered":"\ub370\uc774\ud0c0 \uc815\ubcf4 \uce90\uc2f1 \uc0d8\ud50c"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.auctionpro.co.kr\/wp-content\/uploads\/2026\/06\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"584\" height=\"580\" src=\"https:\/\/www.auctionpro.co.kr\/wp-content\/uploads\/2026\/06\/image.png\" alt=\"\" class=\"wp-image-10329\" srcset=\"https:\/\/www.auctionpro.co.kr\/wp-content\/uploads\/2026\/06\/image.png 584w, https:\/\/www.auctionpro.co.kr\/wp-content\/uploads\/2026\/06\/image-300x298.png 300w, https:\/\/www.auctionpro.co.kr\/wp-content\/uploads\/2026\/06\/image-150x150.png 150w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\uad6c\uc870 \uc124\uba85<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>AirlineCode<\/strong> (\ubaa8\ub378) \u2014 <code>Code<\/code>, <code>NameKr<\/code>, <code>NameEn<\/code>, <code>Country<\/code> 4\uac1c\uc758 \uc18d\uc131\ub9cc \uac00\uc9c4 \ub2e8\uc21c \ub370\uc774\ud130 \ud074\ub798\uc2a4<\/li>\n\n\n\n<li><strong>AirlineCodeCacheService<\/strong> (\ud575\uc2ec \uc11c\ube44\uc2a4) \u2014 <code>IMemoryCache<\/code>\uc640 MySQL \ucee4\ub125\uc158 \ubb38\uc790\uc5f4\uc744 \ud544\ub4dc\ub85c \uac00\uc9c0\uba70, <code>GetAirlineCodesAsync<\/code>, <code>GetAirlineByCodeAsync<\/code>, <code>RefreshCacheAsync<\/code> \uba54\uc11c\ub4dc\ub85c <code>AirlineCode<\/code> \ub9ac\uc2a4\ud2b8\ub97c \uc0dd\uc131\u00b7\ubc18\ud658<\/li>\n\n\n\n<li><strong>AirlineController<\/strong> (API \uacc4\uce35) \u2014 \uc11c\ube44\uc2a4\ub97c \uc8fc\uc785\ubc1b\uc544(<code>\u25c7<\/code> \ub9c8\ub984\ubaa8 = \uc9d1\ud569 \uad00\uacc4) HTTP \uc5d4\ub4dc\ud3ec\uc778\ud2b8\ub85c \ub178\ucd9c<\/li>\n\n\n\n<li>\uc810\uc120 \ud654\uc0b4\ud45c\ub294 \uc11c\ube44\uc2a4\uac00 <code>AirlineCode<\/code> \uac1d\uccb4\ub4e4\uc744 \uc0dd\uc131\/\ubc18\ud658\ud558\ub294 \ud750\ub984\uc744, \uc6b0\uce21\uc758 <code>IMemoryCache<\/code>\u00b7<code>MySqlConnection<\/code>\uc740 \uc678\ubd80 \uc758\uc874\uc131\uc744 \ub098\ud0c0\ub0c5\ub2c8\ub2e4<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">1. \ud544\uc694\ud55c \ud328\ud0a4\uc9c0 \uc124\uce58<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">bash<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dotnet add package MySqlConnector\ndotnet add package Microsoft.Extensions.Caching.Memory<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><code>MySqlConnector<\/code>\ub294 \ube44\ub3d9\uae30 \ucc98\ub9ac\uac00 \ube60\ub974\uace0 \uc548\uc815\uc801\uc774\ub77c <code>MySql.Data<\/code>\ubcf4\ub2e4 \ucd94\ucc9c\ub429\ub2c8\ub2e4.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">2. \ubaa8\ub378 \ud074\ub798\uc2a4<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">csharp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class AirlineCode\n{\n    public string Code { get; set; }       \/\/ \ud56d\uacf5\uc0ac \ucf54\ub4dc (\uc608: KE, OZ)\n    public string NameKr { get; set; }      \/\/ \ud56d\uacf5\uc0ac\uba85 (\ud55c\uae00)\n    public string NameEn { get; set; }      \/\/ \ud56d\uacf5\uc0ac\uba85 (\uc601\ubb38)\n    public string Country { get; set; }     \/\/ \uad6d\uac00\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. \uce90\uc2dc \uc11c\ube44\uc2a4 \ud074\ub798\uc2a4 (MySQL + \ube44\ub3d9\uae30)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">csharp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using Microsoft.Extensions.Caching.Memory;\nusing MySqlConnector;\n\npublic class AirlineCodeCacheService\n{\n    private readonly IMemoryCache _cache;\n    private readonly string _connectionString;\n    private const string CacheKey = \"AirlineCodeList\";\n\n    \/\/ \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \uc694\uccad\uc774 DB\ub97c \ub3d9\uc2dc\uc5d0 \ub54c\ub9ac\ub294 \uac83(\uce90\uc2dc \uc2a4\ud0ec\ud53c\ub4dc) \ubc29\uc9c0\uc6a9\n    private static readonly SemaphoreSlim _lock = new(1, 1);\n\n    public AirlineCodeCacheService(IMemoryCache cache, string connectionString)\n    {\n        _cache = cache;\n        _connectionString = connectionString;\n    }\n\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ \ud56d\uacf5\uc0ac \ucf54\ub4dc \uc804\uccb4 \ubaa9\ub85d \uc870\ud68c (\uce90\uc2dc \uc6b0\uc120)\n    \/\/\/ &lt;\/summary&gt;\n    public async Task&lt;List&lt;AirlineCode&gt;&gt; GetAirlineCodesAsync()\n    {\n        if (_cache.TryGetValue(CacheKey, out List&lt;AirlineCode&gt; cachedList))\n        {\n            return cachedList;\n        }\n\n        await _lock.WaitAsync();\n        try\n        {\n            \/\/ \ub77d \ud68d\ub4dd \ud6c4 \ub2e4\uc2dc \ud55c\ubc88 \uccb4\ud06c (\ub2e4\ub978 \uc2a4\ub808\ub4dc\uac00 \uc774\ubbf8 \ucc44\uc6cc\ub1a8\uc744 \uc218\ub3c4 \uc788\uc74c)\n            if (_cache.TryGetValue(CacheKey, out cachedList))\n            {\n                return cachedList;\n            }\n\n            var list = await LoadFromDatabaseAsync();\n\n            var cacheOptions = new MemoryCacheEntryOptions()\n                .SetAbsoluteExpiration(TimeSpan.FromHours(6))\n                .SetSlidingExpiration(TimeSpan.FromMinutes(30))\n                .SetPriority(CacheItemPriority.Normal);\n\n            _cache.Set(CacheKey, list, cacheOptions);\n\n            return list;\n        }\n        finally\n        {\n            _lock.Release();\n        }\n    }\n\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ \ud2b9\uc815 \ucf54\ub4dc\ub85c \ud56d\uacf5\uc0ac \uc815\ubcf4 \uc870\ud68c\n    \/\/\/ &lt;\/summary&gt;\n    public async Task&lt;AirlineCode&gt; GetAirlineByCodeAsync(string code)\n    {\n        var list = await GetAirlineCodesAsync();\n        return list.FirstOrDefault(x =&gt; x.Code.Equals(code, StringComparison.OrdinalIgnoreCase));\n    }\n\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ \uce90\uc2dc \uac15\uc81c \uac31\uc2e0 (\ub370\uc774\ud130 \ubcc0\uacbd \uc2dc \ud638\ucd9c)\n    \/\/\/ &lt;\/summary&gt;\n    public async Task RefreshCacheAsync()\n    {\n        _cache.Remove(CacheKey);\n        await GetAirlineCodesAsync();\n    }\n\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ MySQL\uc5d0\uc11c \uc2e4\uc81c \ub370\uc774\ud130 \ub85c\ub4dc\n    \/\/\/ &lt;\/summary&gt;\n    private async Task&lt;List&lt;AirlineCode&gt;&gt; LoadFromDatabaseAsync()\n    {\n        var result = new List&lt;AirlineCode&gt;();\n\n        using var conn = new MySqlConnection(_connectionString);\n        await conn.OpenAsync();\n\n        using var cmd = new MySqlCommand(\n            \"SELECT CODE, NAME_KR, NAME_EN, COUNTRY FROM TB_AIRLINE_CODE\", conn);\n\n        using var reader = await cmd.ExecuteReaderAsync();\n        while (await reader.ReadAsync())\n        {\n            result.Add(new AirlineCode\n            {\n                Code = reader&#91;\"CODE\"].ToString(),\n                NameKr = reader&#91;\"NAME_KR\"].ToString(),\n                NameEn = reader&#91;\"NAME_EN\"].ToString(),\n                Country = reader&#91;\"COUNTRY\"].ToString()\n            });\n        }\n\n        return result;\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. Program.cs \ub4f1\ub85d<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">csharp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var builder = WebApplication.CreateBuilder(args);\n\n\/\/ MemoryCache \ub4f1\ub85d\nbuilder.Services.AddMemoryCache();\n\n\/\/ appsettings.json\uc758 ConnectionStrings:DefaultConnection \uc0ac\uc6a9\nvar connectionString = builder.Configuration.GetConnectionString(\"DefaultConnection\");\n\nbuilder.Services.AddSingleton(sp =&gt;\n{\n    var cache = sp.GetRequiredService&lt;IMemoryCache&gt;();\n    return new AirlineCodeCacheService(cache, connectionString);\n});\n\nvar app = builder.Build();<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">5. appsettings.json<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">json<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=localhost;Port=3306;Database=mydb;User=root;Password=yourpassword;\"\n  }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">6. \ucee8\ud2b8\ub864\ub7ec \uc0ac\uc6a9 \uc608\uc2dc<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">csharp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;ApiController]\n&#91;Route(\"api\/&#91;controller]\")]\npublic class AirlineController : ControllerBase\n{\n    private readonly AirlineCodeCacheService _airlineCacheService;\n\n    public AirlineController(AirlineCodeCacheService airlineCacheService)\n    {\n        _airlineCacheService = airlineCacheService;\n    }\n\n    &#91;HttpGet]\n    public async Task&lt;IActionResult&gt; GetAll()\n    {\n        var list = await _airlineCacheService.GetAirlineCodesAsync();\n        return Ok(list);\n    }\n\n    &#91;HttpGet(\"{code}\")]\n    public async Task&lt;IActionResult&gt; GetByCode(string code)\n    {\n        var airline = await _airlineCacheService.GetAirlineByCodeAsync(code);\n        if (airline == null) return NotFound();\n        return Ok(airline);\n    }\n\n    &#91;HttpPost(\"refresh\")]\n    public async Task&lt;IActionResult&gt; Refresh()\n    {\n        await _airlineCacheService.RefreshCacheAsync();\n        return Ok(\"\uce90\uc2dc\uac00 \uac31\uc2e0\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\");\n    }\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">\ubcc0\uacbd\/\ucd94\uac00\ub41c \ud575\uc2ec \uc0ac\ud56d<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\ud56d\ubaa9<\/th><th>\uc124\uba85<\/th><\/tr><\/thead><tbody><tr><td><code>MySqlConnector<\/code><\/td><td>MySQL \uc804\uc6a9 \ube44\ub3d9\uae30 \ub4dc\ub77c\uc774\ubc84 \uc0ac\uc6a9<\/td><\/tr><tr><td><code>SemaphoreSlim<\/code><\/td><td>\uce90\uc2dc \ub9cc\ub8cc \uc21c\uac04 \ub3d9\uc2dc \ub2e4\ubc1c DB \uc870\ud68c(\uc2a4\ud0ec\ud53c\ub4dc) \ubc29\uc9c0<\/td><\/tr><tr><td>\uc804\ubd80 <code>async\/await<\/code><\/td><td>I\/O \ubc14\uc6b4\ub4dc \uc791\uc5c5\uc774\ubbc0\ub85c \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud574 \uc2a4\ub808\ub4dc \ube14\ub85c\ud0b9 \ubc29\uc9c0<\/td><\/tr><\/tbody><\/table><\/figure>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>\uad6c\uc870 \uc124\uba85 1. \ud544\uc694\ud55c \ud328\ud0a4\uc9c0 \uc124\uce58 bash MySqlConnector\ub294 \ube44\ub3d9\uae30 \ucc98\ub9ac\uac00 \ube60\ub974\uace0 \uc548\uc815\uc801\uc774\ub77c MySql.Data\ubcf4\ub2e4 \ucd94\ucc9c\ub429\ub2c8\ub2e4. 2. \ubaa8\ub378 \ud074\ub798\uc2a4 csharp 3. \uce90\uc2dc \uc11c\ube44\uc2a4 \ud074\ub798\uc2a4 (MySQL + \ube44\ub3d9\uae30) <a class=\"mh-excerpt-more\" href=\"https:\/\/www.auctionpro.co.kr\/?p=10326\" title=\"\ub370\uc774\ud0c0 \uc815\ubcf4 \uce90\uc2f1 \uc0d8\ud50c\">[&#8230;]<\/a><\/p>\n<\/div>","protected":false},"author":6,"featured_media":10332,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3,237],"tags":[],"class_list":["post-10326","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-auctonpro-is","category-memory-cache"],"jetpack_featured_media_url":"https:\/\/www.auctionpro.co.kr\/wp-content\/uploads\/2026\/06\/pexels-photo-32278990.jpeg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/10326","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10326"}],"version-history":[{"count":0,"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/10326\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=\/wp\/v2\/media\/10332"}],"wp:attachment":[{"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10326"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10326"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.auctionpro.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10326"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}