[{"data":1,"prerenderedAt":1361},["ShallowReactive",2],{"post-typeorm-transformer":3},{"id":4,"title":5,"body":6,"date":1349,"description":1350,"extension":1351,"meta":1352,"navigation":103,"path":1357,"seo":1358,"stem":1359,"__hash__":1360},"blog\u002Fblog\u002Ftypeorm-transformer.md","TypeORMのTransformer機能でマスターデータを扱う",{"type":7,"value":8,"toc":1327},"minimark",[9,13,17,25,29,34,37,332,336,522,526,532,804,807,810,861,864,938,942,946,949,997,1001,1004,1050,1054,1057,1060,1064,1067,1227,1230,1233,1301,1304,1307,1320,1323],[10,11,12],"h2",{"id":12},"課題",[14,15,16],"p",{},"データベースには数値IDで保存されているマスターデータ（都道府県、ステータスなど）を、アプリケーション層ではIDと名前を持つオブジェクトとして扱いたい場合があります。",[14,18,19,20,24],{},"TypeORMの",[21,22,23],"strong",{},"Transformer機能","を使うことで、この変換を自動化できます。",[10,26,28],{"id":27},"実装例都道府県マスター","実装例：都道府県マスター",[30,31,33],"h3",{"id":32},"_1-汎用的なmasterクラスを定義","1. 汎用的なMasterクラスを定義",[14,35,36],{},"IDと名前を持つマスターデータを管理する基底クラスを作成します。",[38,39,44],"pre",{"className":40,"code":41,"language":42,"meta":43,"style":43},"language-ts shiki shiki-themes github-light github-dark","export interface IMaster {\n  id: number\n  name: string\n}\n\nexport class Master {\n  private readonly masters: IMaster[]\n\n  constructor(masters: IMaster[]) {\n    this.masters = masters\n  }\n\n  findById(id: number): IMaster | undefined {\n    return this.masters.find((v) => v.id === Number(id))\n  }\n\n  findByName(name: string): IMaster | undefined {\n    return this.masters.find((v) => v.name === name)\n  }\n}\n","ts","",[45,46,47,67,81,92,98,105,118,137,142,161,176,182,187,218,257,262,267,295,322,327],"code",{"__ignoreMap":43},[48,49,52,56,59,63],"span",{"class":50,"line":51},"line",1,[48,53,55],{"class":54},"szBVR","export",[48,57,58],{"class":54}," interface",[48,60,62],{"class":61},"sScJk"," IMaster",[48,64,66],{"class":65},"sVt8B"," {\n",[48,68,70,74,77],{"class":50,"line":69},2,[48,71,73],{"class":72},"s4XuR","  id",[48,75,76],{"class":54},":",[48,78,80],{"class":79},"sj4cs"," number\n",[48,82,84,87,89],{"class":50,"line":83},3,[48,85,86],{"class":72},"  name",[48,88,76],{"class":54},[48,90,91],{"class":79}," string\n",[48,93,95],{"class":50,"line":94},4,[48,96,97],{"class":65},"}\n",[48,99,101],{"class":50,"line":100},5,[48,102,104],{"emptyLinePlaceholder":103},true,"\n",[48,106,108,110,113,116],{"class":50,"line":107},6,[48,109,55],{"class":54},[48,111,112],{"class":54}," class",[48,114,115],{"class":61}," Master",[48,117,66],{"class":65},[48,119,121,124,127,130,132,134],{"class":50,"line":120},7,[48,122,123],{"class":54},"  private",[48,125,126],{"class":54}," readonly",[48,128,129],{"class":72}," masters",[48,131,76],{"class":54},[48,133,62],{"class":61},[48,135,136],{"class":65},"[]\n",[48,138,140],{"class":50,"line":139},8,[48,141,104],{"emptyLinePlaceholder":103},[48,143,145,148,151,154,156,158],{"class":50,"line":144},9,[48,146,147],{"class":54},"  constructor",[48,149,150],{"class":65},"(",[48,152,153],{"class":72},"masters",[48,155,76],{"class":54},[48,157,62],{"class":61},[48,159,160],{"class":65},"[]) {\n",[48,162,164,167,170,173],{"class":50,"line":163},10,[48,165,166],{"class":79},"    this",[48,168,169],{"class":65},".masters ",[48,171,172],{"class":54},"=",[48,174,175],{"class":65}," masters\n",[48,177,179],{"class":50,"line":178},11,[48,180,181],{"class":65},"  }\n",[48,183,185],{"class":50,"line":184},12,[48,186,104],{"emptyLinePlaceholder":103},[48,188,190,193,195,198,200,203,206,208,210,213,216],{"class":50,"line":189},13,[48,191,192],{"class":61},"  findById",[48,194,150],{"class":65},[48,196,197],{"class":72},"id",[48,199,76],{"class":54},[48,201,202],{"class":79}," number",[48,204,205],{"class":65},")",[48,207,76],{"class":54},[48,209,62],{"class":61},[48,211,212],{"class":54}," |",[48,214,215],{"class":79}," undefined",[48,217,66],{"class":65},[48,219,221,224,227,230,233,236,239,242,245,248,251,254],{"class":50,"line":220},14,[48,222,223],{"class":54},"    return",[48,225,226],{"class":79}," this",[48,228,229],{"class":65},".masters.",[48,231,232],{"class":61},"find",[48,234,235],{"class":65},"((",[48,237,238],{"class":72},"v",[48,240,241],{"class":65},") ",[48,243,244],{"class":54},"=>",[48,246,247],{"class":65}," v.id ",[48,249,250],{"class":54},"===",[48,252,253],{"class":61}," Number",[48,255,256],{"class":65},"(id))\n",[48,258,260],{"class":50,"line":259},15,[48,261,181],{"class":65},[48,263,265],{"class":50,"line":264},16,[48,266,104],{"emptyLinePlaceholder":103},[48,268,270,273,275,278,280,283,285,287,289,291,293],{"class":50,"line":269},17,[48,271,272],{"class":61},"  findByName",[48,274,150],{"class":65},[48,276,277],{"class":72},"name",[48,279,76],{"class":54},[48,281,282],{"class":79}," string",[48,284,205],{"class":65},[48,286,76],{"class":54},[48,288,62],{"class":61},[48,290,212],{"class":54},[48,292,215],{"class":79},[48,294,66],{"class":65},[48,296,298,300,302,304,306,308,310,312,314,317,319],{"class":50,"line":297},18,[48,299,223],{"class":54},[48,301,226],{"class":79},[48,303,229],{"class":65},[48,305,232],{"class":61},[48,307,235],{"class":65},[48,309,238],{"class":72},[48,311,241],{"class":65},[48,313,244],{"class":54},[48,315,316],{"class":65}," v.name ",[48,318,250],{"class":54},[48,320,321],{"class":65}," name)\n",[48,323,325],{"class":50,"line":324},19,[48,326,181],{"class":65},[48,328,330],{"class":50,"line":329},20,[48,331,97],{"class":65},[30,333,335],{"id":334},"_2-都道府県マスターを実装","2. 都道府県マスターを実装",[38,337,339],{"className":40,"code":338,"language":42,"meta":43,"style":43},"import { IMaster, Master } from '.\u002Fmaster'\n\nconst PREFECTURES: IMaster[] = [\n  { id: 1, name: '北海道' },\n  { id: 2, name: '青森県' },\n  { id: 3, name: '岩手県' },\n  \u002F\u002F ...\n  { id: 47, name: '沖縄県' },\n]\n\nclass PrefectureMaster extends Master {\n  constructor() {\n    super(PREFECTURES)\n  }\n}\n\nexport const Prefecture = new PrefectureMaster()\n",[45,340,341,356,360,380,397,411,425,431,445,450,454,469,476,489,493,497,501],{"__ignoreMap":43},[48,342,343,346,349,352],{"class":50,"line":51},[48,344,345],{"class":54},"import",[48,347,348],{"class":65}," { IMaster, Master } ",[48,350,351],{"class":54},"from",[48,353,355],{"class":354},"sZZnC"," '.\u002Fmaster'\n",[48,357,358],{"class":50,"line":69},[48,359,104],{"emptyLinePlaceholder":103},[48,361,362,365,368,370,372,375,377],{"class":50,"line":83},[48,363,364],{"class":54},"const",[48,366,367],{"class":79}," PREFECTURES",[48,369,76],{"class":54},[48,371,62],{"class":61},[48,373,374],{"class":65},"[] ",[48,376,172],{"class":54},[48,378,379],{"class":65}," [\n",[48,381,382,385,388,391,394],{"class":50,"line":94},[48,383,384],{"class":65},"  { id: ",[48,386,387],{"class":79},"1",[48,389,390],{"class":65},", name: ",[48,392,393],{"class":354},"'北海道'",[48,395,396],{"class":65}," },\n",[48,398,399,401,404,406,409],{"class":50,"line":100},[48,400,384],{"class":65},[48,402,403],{"class":79},"2",[48,405,390],{"class":65},[48,407,408],{"class":354},"'青森県'",[48,410,396],{"class":65},[48,412,413,415,418,420,423],{"class":50,"line":107},[48,414,384],{"class":65},[48,416,417],{"class":79},"3",[48,419,390],{"class":65},[48,421,422],{"class":354},"'岩手県'",[48,424,396],{"class":65},[48,426,427],{"class":50,"line":120},[48,428,430],{"class":429},"sJ8bj","  \u002F\u002F ...\n",[48,432,433,435,438,440,443],{"class":50,"line":139},[48,434,384],{"class":65},[48,436,437],{"class":79},"47",[48,439,390],{"class":65},[48,441,442],{"class":354},"'沖縄県'",[48,444,396],{"class":65},[48,446,447],{"class":50,"line":144},[48,448,449],{"class":65},"]\n",[48,451,452],{"class":50,"line":163},[48,453,104],{"emptyLinePlaceholder":103},[48,455,456,459,462,465,467],{"class":50,"line":178},[48,457,458],{"class":54},"class",[48,460,461],{"class":61}," PrefectureMaster",[48,463,464],{"class":54}," extends",[48,466,115],{"class":61},[48,468,66],{"class":65},[48,470,471,473],{"class":50,"line":184},[48,472,147],{"class":54},[48,474,475],{"class":65},"() {\n",[48,477,478,481,483,486],{"class":50,"line":189},[48,479,480],{"class":79},"    super",[48,482,150],{"class":65},[48,484,485],{"class":79},"PREFECTURES",[48,487,488],{"class":65},")\n",[48,490,491],{"class":50,"line":220},[48,492,181],{"class":65},[48,494,495],{"class":50,"line":259},[48,496,97],{"class":65},[48,498,499],{"class":50,"line":264},[48,500,104],{"emptyLinePlaceholder":103},[48,502,503,505,508,511,514,517,519],{"class":50,"line":269},[48,504,55],{"class":54},[48,506,507],{"class":54}," const",[48,509,510],{"class":79}," Prefecture",[48,512,513],{"class":54}," =",[48,515,516],{"class":54}," new",[48,518,461],{"class":61},[48,520,521],{"class":65},"()\n",[30,523,525],{"id":524},"_3-entityでtransformerを使用","3. EntityでTransformerを使用",[14,527,528,531],{},[45,529,530],{},"transformer","オプションを指定することで、データベースとアプリケーション間の変換を自動化できます。",[38,533,535],{"className":40,"code":534,"language":42,"meta":43,"style":43},"import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'\nimport { Prefecture } from '.\u002Fprefecture.master'\nimport { IMaster } from '.\u002Fmaster'\n\n@Entity()\nexport class User {\n  @PrimaryGeneratedColumn()\n  id: number\n\n  @Column('varchar')\n  name: string\n\n  @Column('tinyint', {\n    unsigned: true,\n    comment: '都道府県ID',\n    transformer: {\n      \u002F\u002F DB → アプリケーション: IDからIMasterオブジェクトへ\n      from(id: number): IMaster | undefined {\n        return Prefecture.findById(id)\n      },\n      \u002F\u002F アプリケーション → DB: IMasterオブジェクトからIDへ\n      to(value: IMaster): number {\n        return value.id\n      },\n    },\n  })\n  prefecture: IMaster\n}\n",[45,536,537,549,561,572,576,586,597,607,615,619,633,641,645,659,670,680,685,690,715,729,734,740,763,771,776,782,788,799],{"__ignoreMap":43},[48,538,539,541,544,546],{"class":50,"line":51},[48,540,345],{"class":54},[48,542,543],{"class":65}," { Entity, Column, PrimaryGeneratedColumn } ",[48,545,351],{"class":54},[48,547,548],{"class":354}," 'typeorm'\n",[48,550,551,553,556,558],{"class":50,"line":69},[48,552,345],{"class":54},[48,554,555],{"class":65}," { Prefecture } ",[48,557,351],{"class":54},[48,559,560],{"class":354}," '.\u002Fprefecture.master'\n",[48,562,563,565,568,570],{"class":50,"line":83},[48,564,345],{"class":54},[48,566,567],{"class":65}," { IMaster } ",[48,569,351],{"class":54},[48,571,355],{"class":354},[48,573,574],{"class":50,"line":94},[48,575,104],{"emptyLinePlaceholder":103},[48,577,578,581,584],{"class":50,"line":100},[48,579,580],{"class":65},"@",[48,582,583],{"class":61},"Entity",[48,585,521],{"class":65},[48,587,588,590,592,595],{"class":50,"line":107},[48,589,55],{"class":54},[48,591,112],{"class":54},[48,593,594],{"class":61}," User",[48,596,66],{"class":65},[48,598,599,602,605],{"class":50,"line":120},[48,600,601],{"class":65},"  @",[48,603,604],{"class":61},"PrimaryGeneratedColumn",[48,606,521],{"class":65},[48,608,609,611,613],{"class":50,"line":139},[48,610,73],{"class":72},[48,612,76],{"class":54},[48,614,80],{"class":79},[48,616,617],{"class":50,"line":144},[48,618,104],{"emptyLinePlaceholder":103},[48,620,621,623,626,628,631],{"class":50,"line":163},[48,622,601],{"class":65},[48,624,625],{"class":61},"Column",[48,627,150],{"class":65},[48,629,630],{"class":354},"'varchar'",[48,632,488],{"class":65},[48,634,635,637,639],{"class":50,"line":178},[48,636,86],{"class":72},[48,638,76],{"class":54},[48,640,91],{"class":79},[48,642,643],{"class":50,"line":184},[48,644,104],{"emptyLinePlaceholder":103},[48,646,647,649,651,653,656],{"class":50,"line":189},[48,648,601],{"class":65},[48,650,625],{"class":61},[48,652,150],{"class":65},[48,654,655],{"class":354},"'tinyint'",[48,657,658],{"class":65},", {\n",[48,660,661,664,667],{"class":50,"line":220},[48,662,663],{"class":65},"    unsigned: ",[48,665,666],{"class":79},"true",[48,668,669],{"class":65},",\n",[48,671,672,675,678],{"class":50,"line":259},[48,673,674],{"class":65},"    comment: ",[48,676,677],{"class":354},"'都道府県ID'",[48,679,669],{"class":65},[48,681,682],{"class":50,"line":264},[48,683,684],{"class":65},"    transformer: {\n",[48,686,687],{"class":50,"line":269},[48,688,689],{"class":429},"      \u002F\u002F DB → アプリケーション: IDからIMasterオブジェクトへ\n",[48,691,692,695,697,699,701,703,705,707,709,711,713],{"class":50,"line":297},[48,693,694],{"class":61},"      from",[48,696,150],{"class":65},[48,698,197],{"class":72},[48,700,76],{"class":54},[48,702,202],{"class":79},[48,704,205],{"class":65},[48,706,76],{"class":54},[48,708,62],{"class":61},[48,710,212],{"class":54},[48,712,215],{"class":79},[48,714,66],{"class":65},[48,716,717,720,723,726],{"class":50,"line":324},[48,718,719],{"class":54},"        return",[48,721,722],{"class":65}," Prefecture.",[48,724,725],{"class":61},"findById",[48,727,728],{"class":65},"(id)\n",[48,730,731],{"class":50,"line":329},[48,732,733],{"class":65},"      },\n",[48,735,737],{"class":50,"line":736},21,[48,738,739],{"class":429},"      \u002F\u002F アプリケーション → DB: IMasterオブジェクトからIDへ\n",[48,741,743,746,748,751,753,755,757,759,761],{"class":50,"line":742},22,[48,744,745],{"class":61},"      to",[48,747,150],{"class":65},[48,749,750],{"class":72},"value",[48,752,76],{"class":54},[48,754,62],{"class":61},[48,756,205],{"class":65},[48,758,76],{"class":54},[48,760,202],{"class":79},[48,762,66],{"class":65},[48,764,766,768],{"class":50,"line":765},23,[48,767,719],{"class":54},[48,769,770],{"class":65}," value.id\n",[48,772,774],{"class":50,"line":773},24,[48,775,733],{"class":65},[48,777,779],{"class":50,"line":778},25,[48,780,781],{"class":65},"    },\n",[48,783,785],{"class":50,"line":784},26,[48,786,787],{"class":65},"  })\n",[48,789,791,794,796],{"class":50,"line":790},27,[48,792,793],{"class":72},"  prefecture",[48,795,76],{"class":54},[48,797,798],{"class":61}," IMaster\n",[48,800,802],{"class":50,"line":801},28,[48,803,97],{"class":65},[10,805,806],{"id":806},"使用例",[30,808,809],{"id":809},"データの取得",[38,811,813],{"className":40,"code":812,"language":42,"meta":43,"style":43},"const user = await userRepository.findOne({ where: { id: 1 } })\n\nconsole.log(user.prefecture)\n\u002F\u002F { id: 13, name: '東京都' }\n",[45,814,815,841,845,856],{"__ignoreMap":43},[48,816,817,819,822,824,827,830,833,836,838],{"class":50,"line":51},[48,818,364],{"class":54},[48,820,821],{"class":79}," user",[48,823,513],{"class":54},[48,825,826],{"class":54}," await",[48,828,829],{"class":65}," userRepository.",[48,831,832],{"class":61},"findOne",[48,834,835],{"class":65},"({ where: { id: ",[48,837,387],{"class":79},[48,839,840],{"class":65}," } })\n",[48,842,843],{"class":50,"line":69},[48,844,104],{"emptyLinePlaceholder":103},[48,846,847,850,853],{"class":50,"line":83},[48,848,849],{"class":65},"console.",[48,851,852],{"class":61},"log",[48,854,855],{"class":65},"(user.prefecture)\n",[48,857,858],{"class":50,"line":94},[48,859,860],{"class":429},"\u002F\u002F { id: 13, name: '東京都' }\n",[30,862,863],{"id":863},"データの保存",[38,865,867],{"className":40,"code":866,"language":42,"meta":43,"style":43},"const newUser = userRepository.create({\n  name: '山田太郎',\n  prefecture: { id: 13, name: '東京都' },\n})\n\nawait userRepository.save(newUser)\n\u002F\u002F DBには prefecture = 13 として保存される\n",[45,868,869,886,896,911,916,920,933],{"__ignoreMap":43},[48,870,871,873,876,878,880,883],{"class":50,"line":51},[48,872,364],{"class":54},[48,874,875],{"class":79}," newUser",[48,877,513],{"class":54},[48,879,829],{"class":65},[48,881,882],{"class":61},"create",[48,884,885],{"class":65},"({\n",[48,887,888,891,894],{"class":50,"line":69},[48,889,890],{"class":65},"  name: ",[48,892,893],{"class":354},"'山田太郎'",[48,895,669],{"class":65},[48,897,898,901,904,906,909],{"class":50,"line":83},[48,899,900],{"class":65},"  prefecture: { id: ",[48,902,903],{"class":79},"13",[48,905,390],{"class":65},[48,907,908],{"class":354},"'東京都'",[48,910,396],{"class":65},[48,912,913],{"class":50,"line":94},[48,914,915],{"class":65},"})\n",[48,917,918],{"class":50,"line":100},[48,919,104],{"emptyLinePlaceholder":103},[48,921,922,925,927,930],{"class":50,"line":107},[48,923,924],{"class":54},"await",[48,926,829],{"class":65},[48,928,929],{"class":61},"save",[48,931,932],{"class":65},"(newUser)\n",[48,934,935],{"class":50,"line":120},[48,936,937],{"class":429},"\u002F\u002F DBには prefecture = 13 として保存される\n",[10,939,941],{"id":940},"transformerのメリット","Transformerのメリット",[30,943,945],{"id":944},"_1-型安全性","1. 型安全性",[14,947,948],{},"IDを直接扱うのではなく、オブジェクトとして扱うことで型安全性が向上します。",[38,950,952],{"className":40,"code":951,"language":42,"meta":43,"style":43},"\u002F\u002F ❌ IDだけでは何のIDか不明\nuser.prefecture_id = 13\n\n\u002F\u002F ✅ オブジェクトなので明確\nuser.prefecture = { id: 13, name: '東京都' }\n",[45,953,954,959,969,973,978],{"__ignoreMap":43},[48,955,956],{"class":50,"line":51},[48,957,958],{"class":429},"\u002F\u002F ❌ IDだけでは何のIDか不明\n",[48,960,961,964,966],{"class":50,"line":69},[48,962,963],{"class":65},"user.prefecture_id ",[48,965,172],{"class":54},[48,967,968],{"class":79}," 13\n",[48,970,971],{"class":50,"line":83},[48,972,104],{"emptyLinePlaceholder":103},[48,974,975],{"class":50,"line":94},[48,976,977],{"class":429},"\u002F\u002F ✅ オブジェクトなので明確\n",[48,979,980,983,985,988,990,992,994],{"class":50,"line":100},[48,981,982],{"class":65},"user.prefecture ",[48,984,172],{"class":54},[48,986,987],{"class":65}," { id: ",[48,989,903],{"class":79},[48,991,390],{"class":65},[48,993,908],{"class":354},[48,995,996],{"class":65}," }\n",[30,998,1000],{"id":999},"_2-コードの可読性","2. コードの可読性",[14,1002,1003],{},"マスターデータの名前に直接アクセスできます。",[38,1005,1007],{"className":40,"code":1006,"language":42,"meta":43,"style":43},"\u002F\u002F ❌ 別途マスターを参照する必要がある\nconst prefectureName = Prefecture.findById(user.prefecture_id)?.name\n\n\u002F\u002F ✅ 直接アクセス可能\nconst prefectureName = user.prefecture.name\n",[45,1008,1009,1014,1030,1034,1039],{"__ignoreMap":43},[48,1010,1011],{"class":50,"line":51},[48,1012,1013],{"class":429},"\u002F\u002F ❌ 別途マスターを参照する必要がある\n",[48,1015,1016,1018,1021,1023,1025,1027],{"class":50,"line":69},[48,1017,364],{"class":54},[48,1019,1020],{"class":79}," prefectureName",[48,1022,513],{"class":54},[48,1024,722],{"class":65},[48,1026,725],{"class":61},[48,1028,1029],{"class":65},"(user.prefecture_id)?.name\n",[48,1031,1032],{"class":50,"line":83},[48,1033,104],{"emptyLinePlaceholder":103},[48,1035,1036],{"class":50,"line":94},[48,1037,1038],{"class":429},"\u002F\u002F ✅ 直接アクセス可能\n",[48,1040,1041,1043,1045,1047],{"class":50,"line":100},[48,1042,364],{"class":54},[48,1044,1020],{"class":79},[48,1046,513],{"class":54},[48,1048,1049],{"class":65}," user.prefecture.name\n",[30,1051,1053],{"id":1052},"_3-ビジネスロジックの簡素化","3. ビジネスロジックの簡素化",[14,1055,1056],{},"データの変換処理がEntity層で完結するため、ビジネスロジックがシンプルになります。",[10,1058,1059],{"id":1059},"注意点",[30,1061,1063],{"id":1062},"nullundefinedの扱い","Null\u002FUndefinedの扱い",[14,1065,1066],{},"データベースでNULL許可する場合は、Transformerでもそれを考慮してください。",[38,1068,1070],{"className":40,"code":1069,"language":42,"meta":43,"style":43},"@Column('tinyint', {\n  nullable: true,\n  transformer: {\n    from(id: number | null): IMaster | null {\n      return id ? Prefecture.findById(id) ?? null : null\n    },\n    to(value: IMaster | null): number | null {\n      return value?.id ?? null\n    },\n  },\n})\nprefecture: IMaster | null\n",[45,1071,1072,1084,1093,1098,1128,1157,1161,1190,1201,1205,1210,1214],{"__ignoreMap":43},[48,1073,1074,1076,1078,1080,1082],{"class":50,"line":51},[48,1075,580],{"class":65},[48,1077,625],{"class":61},[48,1079,150],{"class":65},[48,1081,655],{"class":354},[48,1083,658],{"class":65},[48,1085,1086,1089,1091],{"class":50,"line":69},[48,1087,1088],{"class":65},"  nullable: ",[48,1090,666],{"class":79},[48,1092,669],{"class":65},[48,1094,1095],{"class":50,"line":83},[48,1096,1097],{"class":65},"  transformer: {\n",[48,1099,1100,1103,1105,1107,1109,1111,1113,1116,1118,1120,1122,1124,1126],{"class":50,"line":94},[48,1101,1102],{"class":61},"    from",[48,1104,150],{"class":65},[48,1106,197],{"class":72},[48,1108,76],{"class":54},[48,1110,202],{"class":79},[48,1112,212],{"class":54},[48,1114,1115],{"class":79}," null",[48,1117,205],{"class":65},[48,1119,76],{"class":54},[48,1121,62],{"class":61},[48,1123,212],{"class":54},[48,1125,1115],{"class":79},[48,1127,66],{"class":65},[48,1129,1130,1133,1136,1139,1141,1143,1146,1149,1151,1154],{"class":50,"line":100},[48,1131,1132],{"class":54},"      return",[48,1134,1135],{"class":65}," id ",[48,1137,1138],{"class":54},"?",[48,1140,722],{"class":65},[48,1142,725],{"class":61},[48,1144,1145],{"class":65},"(id) ",[48,1147,1148],{"class":54},"??",[48,1150,1115],{"class":79},[48,1152,1153],{"class":54}," :",[48,1155,1156],{"class":79}," null\n",[48,1158,1159],{"class":50,"line":107},[48,1160,781],{"class":65},[48,1162,1163,1166,1168,1170,1172,1174,1176,1178,1180,1182,1184,1186,1188],{"class":50,"line":120},[48,1164,1165],{"class":61},"    to",[48,1167,150],{"class":65},[48,1169,750],{"class":72},[48,1171,76],{"class":54},[48,1173,62],{"class":61},[48,1175,212],{"class":54},[48,1177,1115],{"class":79},[48,1179,205],{"class":65},[48,1181,76],{"class":54},[48,1183,202],{"class":79},[48,1185,212],{"class":54},[48,1187,1115],{"class":79},[48,1189,66],{"class":65},[48,1191,1192,1194,1197,1199],{"class":50,"line":139},[48,1193,1132],{"class":54},[48,1195,1196],{"class":65}," value?.id ",[48,1198,1148],{"class":54},[48,1200,1156],{"class":79},[48,1202,1203],{"class":50,"line":144},[48,1204,781],{"class":65},[48,1206,1207],{"class":50,"line":163},[48,1208,1209],{"class":65},"  },\n",[48,1211,1212],{"class":50,"line":178},[48,1213,915],{"class":65},[48,1215,1216,1219,1222,1225],{"class":50,"line":184},[48,1217,1218],{"class":61},"prefecture",[48,1220,1221],{"class":65},": IMaster ",[48,1223,1224],{"class":54},"|",[48,1226,1156],{"class":79},[30,1228,1229],{"id":1229},"クエリビルダーでの使用",[14,1231,1232],{},"クエリビルダーを使う場合は、変換が自動で行われないため注意が必要です。",[38,1234,1236],{"className":40,"code":1235,"language":42,"meta":43,"style":43},"\u002F\u002F IDで検索する必要がある\nconst users = await userRepository\n  .createQueryBuilder('user')\n  .where('user.prefecture = :prefectureId', { prefectureId: 13 })\n  .getMany()\n",[45,1237,1238,1243,1257,1272,1292],{"__ignoreMap":43},[48,1239,1240],{"class":50,"line":51},[48,1241,1242],{"class":429},"\u002F\u002F IDで検索する必要がある\n",[48,1244,1245,1247,1250,1252,1254],{"class":50,"line":69},[48,1246,364],{"class":54},[48,1248,1249],{"class":79}," users",[48,1251,513],{"class":54},[48,1253,826],{"class":54},[48,1255,1256],{"class":65}," userRepository\n",[48,1258,1259,1262,1265,1267,1270],{"class":50,"line":83},[48,1260,1261],{"class":65},"  .",[48,1263,1264],{"class":61},"createQueryBuilder",[48,1266,150],{"class":65},[48,1268,1269],{"class":354},"'user'",[48,1271,488],{"class":65},[48,1273,1274,1276,1279,1281,1284,1287,1289],{"class":50,"line":94},[48,1275,1261],{"class":65},[48,1277,1278],{"class":61},"where",[48,1280,150],{"class":65},[48,1282,1283],{"class":354},"'user.prefecture = :prefectureId'",[48,1285,1286],{"class":65},", { prefectureId: ",[48,1288,903],{"class":79},[48,1290,1291],{"class":65}," })\n",[48,1293,1294,1296,1299],{"class":50,"line":100},[48,1295,1261],{"class":65},[48,1297,1298],{"class":61},"getMany",[48,1300,521],{"class":65},[10,1302,1303],{"id":1303},"まとめ",[14,1305,1306],{},"TypeORMのTransformer機能を使うことで、次のメリットがあります。",[1308,1309,1310,1314,1317],"ul",{},[1311,1312,1313],"li",{},"データベースとアプリケーション間のデータ変換を自動化",[1311,1315,1316],{},"型安全性とコードの可読性が向上",[1311,1318,1319],{},"マスターデータの扱いがシンプルに",[14,1321,1322],{},"マスターデータを多く扱うアプリケーションで特に有効な機能です。",[1324,1325,1326],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":43,"searchDepth":69,"depth":69,"links":1328},[1329,1330,1335,1339,1344,1348],{"id":12,"depth":69,"text":12},{"id":27,"depth":69,"text":28,"children":1331},[1332,1333,1334],{"id":32,"depth":83,"text":33},{"id":334,"depth":83,"text":335},{"id":524,"depth":83,"text":525},{"id":806,"depth":69,"text":806,"children":1336},[1337,1338],{"id":809,"depth":83,"text":809},{"id":863,"depth":83,"text":863},{"id":940,"depth":69,"text":941,"children":1340},[1341,1342,1343],{"id":944,"depth":83,"text":945},{"id":999,"depth":83,"text":1000},{"id":1052,"depth":83,"text":1053},{"id":1059,"depth":69,"text":1059,"children":1345},[1346,1347],{"id":1062,"depth":83,"text":1063},{"id":1229,"depth":83,"text":1229},{"id":1303,"depth":69,"text":1303},"2021-11-28","TypeORMのTransformer機能を使って、データベースの数値IDとアプリケーションのマスターオブジェクトを相互変換する実装パターンを紹介します。","md",{"tags":1353},[1354,1355,1356],"typescript","typeorm","database","\u002Fblog\u002Ftypeorm-transformer",{"title":5,"description":1350},"blog\u002Ftypeorm-transformer","vNzBjT0VN3k3JScjaVJ-20JE2FMZacMOg3dir-pZH00",1773664054365]