[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdatabase":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdatabase":3555,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdatabase":3581},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":13,"pinned":14,"draft":14,"body":15,"seo":3551,"stem":3552,"id":3553,"extension":3554},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdatabase","数据库集成（以 TypeORM 为例）","Nest 通过 @nestjs\u002Ftypeorm 等包集成 ORM；生产环境用 migration，慎用 synchronize。亦可选用 Prisma、MikroORM 等（见 官方 Database）。","技能小册",[12],"nestjs","2023-05-26",false,{"type":16,"value":17,"toc":3538},"minimark",[18,22,48,57,65,68,103,110,130,142,150,157,483,489,547,553,566,853,859,863,877,1086,1091,1118,1122,1135,1139,1146,1338,1342,1349,1813,1817,1820,1902,1907,2152,2159,2240,2244,2251,2660,2676,2680,2687,2690,2889,2892,2982,2989,2992,3126,3133,3137,3144,3253,3256,3374,3384,3387,3475,3478,3482,3485,3534],[19,20,8],"h1",{"id":21},"数据库集成以-typeorm-为例",[23,24,25,26,30,31,35,36,39,40,47],"p",{},"Nest 通过 ",[27,28,29],"code",{},"@nestjs\u002Ftypeorm"," 等包集成 ORM；生产环境用 ",[32,33,34],"strong",{},"migration","，慎用 ",[27,37,38],{},"synchronize","。亦可选用 Prisma、MikroORM 等（见 ",[41,42,46],"a",{"href":43,"rel":44},"https:\u002F\u002Fdocs.nestjs.com\u002Ftechniques\u002Fdatabase",[45],"nofollow","官方 Database","）。",[23,49,50,51,56],{},"下文以 ",[32,52,53,55],{},[27,54,29],{}," + TypeORM"," 为例（支持 MySQL、PostgreSQL、SQLite 等）。",[58,59,61,62,64],"h3",{"id":60},"一nestjstypeorm-模块","一、",[27,63,29],{}," 模块",[23,66,67],{},"安装依赖：",[69,70,75],"pre",{"className":71,"code":72,"language":73,"meta":74,"style":74},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","npm install @nestjs\u002Ftypeorm typeorm mysql2   # 以 MySQL 为例\n","bash","",[27,76,77],{"__ignoreMap":74},[78,79,82,86,90,93,96,99],"span",{"class":80,"line":81},"line",1,[78,83,85],{"class":84},"sbgvK","npm",[78,87,89],{"class":88},"s_sjI"," install",[78,91,92],{"class":88}," @nestjs\u002Ftypeorm",[78,94,95],{"class":88}," typeorm",[78,97,98],{"class":88}," mysql2",[78,100,102],{"class":101},"sutJx","   # 以 MySQL 为例\n",[23,104,105,106,109],{},"该模块导出了 ",[27,107,108],{},"TypeOrmModule","，它提供了：",[111,112,113,124],"ul",{},[114,115,116,119,120,123],"li",{},[27,117,118],{},"forRoot()"," \u002F ",[27,121,122],{},"forRootAsync()","：配置数据库连接（应用级别配置）。",[114,125,126,129],{},[27,127,128],{},"forFeature()","：在特定模块中注册实体仓库（Repository），以便注入使用。",[58,131,133,134,137,138,141],{"id":132},"二配置typeormmoduleforroot-与-forrootasync","二、配置（",[27,135,136],{},"TypeOrmModule.forRoot()"," 与 ",[27,139,140],{},"forRootAsync","）",[143,144,146,147,141],"h4",{"id":145},"_1-同步配置forroot","1. 同步配置（",[27,148,149],{},"forRoot",[23,151,152,153,156],{},"直接在根模块（如 ",[27,154,155],{},"AppModule","）中调用，传入配置对象。",[69,158,162],{"className":159,"code":160,"language":161,"meta":74,"style":74},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","import { Module } from \"@nestjs\u002Fcommon\";\nimport { TypeOrmModule } from \"@nestjs\u002Ftypeorm\";\nimport { User } from \".\u002Fusers\u002Fuser.entity\";\n\n@Module({\n  imports: [\n    TypeOrmModule.forRoot({\n      type: \"mysql\",\n      host: \"localhost\",\n      port: 3306,\n      username: \"root\",\n      password: \"password\",\n      database: \"test\",\n      entities: [User], \u002F\u002F 自动加载实体\n      synchronize: true, \u002F\u002F 生产环境应设为 false，使用 migration\n      logging: true,\n    }),\n  ],\n})\nexport class AppModule {}\n","ts",[27,163,164,197,219,242,249,265,278,293,311,328,342,359,376,393,410,427,439,450,458,467],{"__ignoreMap":74},[78,165,166,170,174,178,181,184,188,191,194],{"class":80,"line":81},[78,167,169],{"class":168},"sVHd0","import",[78,171,173],{"class":172},"sP7_E"," {",[78,175,177],{"class":176},"su5hD"," Module",[78,179,180],{"class":172}," }",[78,182,183],{"class":168}," from",[78,185,187],{"class":186},"sjJ54"," \"",[78,189,190],{"class":88},"@nestjs\u002Fcommon",[78,192,193],{"class":186},"\"",[78,195,196],{"class":172},";\n",[78,198,200,202,204,207,209,211,213,215,217],{"class":80,"line":199},2,[78,201,169],{"class":168},[78,203,173],{"class":172},[78,205,206],{"class":176}," TypeOrmModule",[78,208,180],{"class":172},[78,210,183],{"class":168},[78,212,187],{"class":186},[78,214,29],{"class":88},[78,216,193],{"class":186},[78,218,196],{"class":172},[78,220,222,224,226,229,231,233,235,238,240],{"class":80,"line":221},3,[78,223,169],{"class":168},[78,225,173],{"class":172},[78,227,228],{"class":176}," User",[78,230,180],{"class":172},[78,232,183],{"class":168},[78,234,187],{"class":186},[78,236,237],{"class":88},".\u002Fusers\u002Fuser.entity",[78,239,193],{"class":186},[78,241,196],{"class":172},[78,243,245],{"class":80,"line":244},4,[78,246,248],{"emptyLinePlaceholder":247},true,"\n",[78,250,252,255,259,262],{"class":80,"line":251},5,[78,253,254],{"class":172},"@",[78,256,258],{"class":257},"sGLFI","Module",[78,260,261],{"class":176},"(",[78,263,264],{"class":172},"{\n",[78,266,268,272,275],{"class":80,"line":267},6,[78,269,271],{"class":270},"skxfh","  imports",[78,273,274],{"class":172},":",[78,276,277],{"class":176}," [\n",[78,279,281,284,287,289,291],{"class":80,"line":280},7,[78,282,283],{"class":176},"    TypeOrmModule",[78,285,286],{"class":172},".",[78,288,149],{"class":257},[78,290,261],{"class":176},[78,292,264],{"class":172},[78,294,296,299,301,303,306,308],{"class":80,"line":295},8,[78,297,298],{"class":270},"      type",[78,300,274],{"class":172},[78,302,187],{"class":186},[78,304,305],{"class":88},"mysql",[78,307,193],{"class":186},[78,309,310],{"class":172},",\n",[78,312,314,317,319,321,324,326],{"class":80,"line":313},9,[78,315,316],{"class":270},"      host",[78,318,274],{"class":172},[78,320,187],{"class":186},[78,322,323],{"class":88},"localhost",[78,325,193],{"class":186},[78,327,310],{"class":172},[78,329,331,334,336,340],{"class":80,"line":330},10,[78,332,333],{"class":270},"      port",[78,335,274],{"class":172},[78,337,339],{"class":338},"srdBf"," 3306",[78,341,310],{"class":172},[78,343,345,348,350,352,355,357],{"class":80,"line":344},11,[78,346,347],{"class":270},"      username",[78,349,274],{"class":172},[78,351,187],{"class":186},[78,353,354],{"class":88},"root",[78,356,193],{"class":186},[78,358,310],{"class":172},[78,360,362,365,367,369,372,374],{"class":80,"line":361},12,[78,363,364],{"class":270},"      password",[78,366,274],{"class":172},[78,368,187],{"class":186},[78,370,371],{"class":88},"password",[78,373,193],{"class":186},[78,375,310],{"class":172},[78,377,379,382,384,386,389,391],{"class":80,"line":378},13,[78,380,381],{"class":270},"      database",[78,383,274],{"class":172},[78,385,187],{"class":186},[78,387,388],{"class":88},"test",[78,390,193],{"class":186},[78,392,310],{"class":172},[78,394,396,399,401,404,407],{"class":80,"line":395},14,[78,397,398],{"class":270},"      entities",[78,400,274],{"class":172},[78,402,403],{"class":176}," [User]",[78,405,406],{"class":172},",",[78,408,409],{"class":101}," \u002F\u002F 自动加载实体\n",[78,411,413,416,418,422,424],{"class":80,"line":412},15,[78,414,415],{"class":270},"      synchronize",[78,417,274],{"class":172},[78,419,421],{"class":420},"syTEX"," true",[78,423,406],{"class":172},[78,425,426],{"class":101}," \u002F\u002F 生产环境应设为 false，使用 migration\n",[78,428,430,433,435,437],{"class":80,"line":429},16,[78,431,432],{"class":270},"      logging",[78,434,274],{"class":172},[78,436,421],{"class":420},[78,438,310],{"class":172},[78,440,442,445,448],{"class":80,"line":441},17,[78,443,444],{"class":172},"    }",[78,446,447],{"class":176},")",[78,449,310],{"class":172},[78,451,453,456],{"class":80,"line":452},18,[78,454,455],{"class":176},"  ]",[78,457,310],{"class":172},[78,459,461,464],{"class":80,"line":460},19,[78,462,463],{"class":172},"}",[78,465,466],{"class":176},")\n",[78,468,470,473,477,480],{"class":80,"line":469},20,[78,471,472],{"class":168},"export",[78,474,476],{"class":475},"sbsja"," class",[78,478,479],{"class":84}," AppModule",[78,481,482],{"class":172}," {}\n",[23,484,485,488],{},[32,486,487],{},"关键配置项","：",[111,490,491,506,523,533,541],{},[114,492,493,496,497,499,500,499,503,505],{},[27,494,495],{},"type","：数据库类型（",[27,498,305],{},"、",[27,501,502],{},"postgres",[27,504,4],{}," 等）。",[114,507,508,499,511,499,514,499,517,499,519,522],{},[27,509,510],{},"host",[27,512,513],{},"port",[27,515,516],{},"username",[27,518,371],{},[27,520,521],{},"database","：连接参数。",[114,524,525,528,529,532],{},[27,526,527],{},"entities","：实体类列表（或使用 ",[27,530,531],{},"autoLoadEntities: true"," 自动加载）。",[114,534,535,537,538,47],{},[27,536,38],{},"：自动同步实体结构到数据库（",[32,539,540],{},"仅开发\u002F测试环境",[114,542,543,546],{},[27,544,545],{},"logging","：打印 SQL 日志。",[143,548,550,551,141],{"id":549},"_2-异步配置forrootasync","2. 异步配置（",[27,552,140],{},[23,554,555,556,499,559,499,562,565],{},"适合从环境变量或配置服务动态加载配置。支持 ",[27,557,558],{},"useFactory",[27,560,561],{},"useClass",[27,563,564],{},"useExisting","。",[69,567,569],{"className":159,"code":568,"language":161,"meta":74,"style":74},"TypeOrmModule.forRootAsync({\n  imports: [ConfigModule],\n  useFactory: (configService: ConfigService) => ({\n    type: \"mysql\",\n    host: configService.get(\"DB_HOST\"),\n    port: +configService.get(\"DB_PORT\"),\n    username: configService.get(\"DB_USER\"),\n    password: configService.get(\"DB_PASSWORD\"),\n    database: configService.get(\"DB_NAME\"),\n    entities: [User], \u002F\u002F 或 autoLoadEntities: true\n    synchronize: configService.get(\"NODE_ENV\") !== \"production\",\n  }),\n  inject: [ConfigService],\n});\n",[27,570,571,583,594,623,638,666,695,721,747,773,787,824,833,845],{"__ignoreMap":74},[78,572,573,575,577,579,581],{"class":80,"line":81},[78,574,108],{"class":176},[78,576,286],{"class":172},[78,578,140],{"class":257},[78,580,261],{"class":176},[78,582,264],{"class":172},[78,584,585,587,589,592],{"class":80,"line":199},[78,586,271],{"class":270},[78,588,274],{"class":172},[78,590,591],{"class":176}," [ConfigModule]",[78,593,310],{"class":172},[78,595,596,599,601,604,608,611,614,616,619,621],{"class":80,"line":221},[78,597,598],{"class":257},"  useFactory",[78,600,274],{"class":172},[78,602,603],{"class":172}," (",[78,605,607],{"class":606},"s99_P","configService",[78,609,274],{"class":610},"smGrS",[78,612,613],{"class":84}," ConfigService",[78,615,447],{"class":172},[78,617,618],{"class":475}," =>",[78,620,603],{"class":176},[78,622,264],{"class":172},[78,624,625,628,630,632,634,636],{"class":80,"line":244},[78,626,627],{"class":270},"    type",[78,629,274],{"class":172},[78,631,187],{"class":186},[78,633,305],{"class":88},[78,635,193],{"class":186},[78,637,310],{"class":172},[78,639,640,643,645,648,650,653,655,657,660,662,664],{"class":80,"line":251},[78,641,642],{"class":270},"    host",[78,644,274],{"class":172},[78,646,647],{"class":176}," configService",[78,649,286],{"class":172},[78,651,652],{"class":257},"get",[78,654,261],{"class":176},[78,656,193],{"class":186},[78,658,659],{"class":88},"DB_HOST",[78,661,193],{"class":186},[78,663,447],{"class":176},[78,665,310],{"class":172},[78,667,668,671,673,676,678,680,682,684,686,689,691,693],{"class":80,"line":267},[78,669,670],{"class":270},"    port",[78,672,274],{"class":172},[78,674,675],{"class":610}," +",[78,677,607],{"class":176},[78,679,286],{"class":172},[78,681,652],{"class":257},[78,683,261],{"class":176},[78,685,193],{"class":186},[78,687,688],{"class":88},"DB_PORT",[78,690,193],{"class":186},[78,692,447],{"class":176},[78,694,310],{"class":172},[78,696,697,700,702,704,706,708,710,712,715,717,719],{"class":80,"line":280},[78,698,699],{"class":270},"    username",[78,701,274],{"class":172},[78,703,647],{"class":176},[78,705,286],{"class":172},[78,707,652],{"class":257},[78,709,261],{"class":176},[78,711,193],{"class":186},[78,713,714],{"class":88},"DB_USER",[78,716,193],{"class":186},[78,718,447],{"class":176},[78,720,310],{"class":172},[78,722,723,726,728,730,732,734,736,738,741,743,745],{"class":80,"line":295},[78,724,725],{"class":270},"    password",[78,727,274],{"class":172},[78,729,647],{"class":176},[78,731,286],{"class":172},[78,733,652],{"class":257},[78,735,261],{"class":176},[78,737,193],{"class":186},[78,739,740],{"class":88},"DB_PASSWORD",[78,742,193],{"class":186},[78,744,447],{"class":176},[78,746,310],{"class":172},[78,748,749,752,754,756,758,760,762,764,767,769,771],{"class":80,"line":313},[78,750,751],{"class":270},"    database",[78,753,274],{"class":172},[78,755,647],{"class":176},[78,757,286],{"class":172},[78,759,652],{"class":257},[78,761,261],{"class":176},[78,763,193],{"class":186},[78,765,766],{"class":88},"DB_NAME",[78,768,193],{"class":186},[78,770,447],{"class":176},[78,772,310],{"class":172},[78,774,775,778,780,782,784],{"class":80,"line":330},[78,776,777],{"class":270},"    entities",[78,779,274],{"class":172},[78,781,403],{"class":176},[78,783,406],{"class":172},[78,785,786],{"class":101}," \u002F\u002F 或 autoLoadEntities: true\n",[78,788,789,792,794,796,798,800,802,804,807,809,812,815,817,820,822],{"class":80,"line":344},[78,790,791],{"class":270},"    synchronize",[78,793,274],{"class":172},[78,795,647],{"class":176},[78,797,286],{"class":172},[78,799,652],{"class":257},[78,801,261],{"class":176},[78,803,193],{"class":186},[78,805,806],{"class":88},"NODE_ENV",[78,808,193],{"class":186},[78,810,811],{"class":176},") ",[78,813,814],{"class":610},"!==",[78,816,187],{"class":186},[78,818,819],{"class":88},"production",[78,821,193],{"class":186},[78,823,310],{"class":172},[78,825,826,829,831],{"class":80,"line":361},[78,827,828],{"class":172},"  }",[78,830,447],{"class":176},[78,832,310],{"class":172},[78,834,835,838,840,843],{"class":80,"line":378},[78,836,837],{"class":270},"  inject",[78,839,274],{"class":172},[78,841,842],{"class":176}," [ConfigService]",[78,844,310],{"class":172},[78,846,847,849,851],{"class":80,"line":395},[78,848,463],{"class":172},[78,850,447],{"class":176},[78,852,196],{"class":172},[23,854,855,856,858],{},"也可以使用 ",[27,857,561],{}," 指定一个自定义配置工厂类。",[58,860,862],{"id":861},"三实体entity","三、实体（Entity）",[23,864,865,866,869,870,499,873,876],{},"实体是映射到数据库表的一个类。使用 ",[27,867,868],{},"@Entity()"," 装饰器声明，字段用 ",[27,871,872],{},"@Column()",[27,874,875],{},"@PrimaryGeneratedColumn()"," 等修饰。",[69,878,880],{"className":159,"code":879,"language":161,"meta":74,"style":74},"\u002F\u002F user.entity.ts\nimport { Entity, Column, PrimaryGeneratedColumn } from \"typeorm\";\n\n@Entity()\nexport class User {\n  @PrimaryGeneratedColumn()\n  id: number;\n\n  @Column({ length: 100 })\n  name: string;\n\n  @Column({ unique: true })\n  email: string;\n\n  @Column({ default: true })\n  isActive: boolean;\n}\n",[27,881,882,887,919,923,933,944,954,968,972,996,1008,1012,1033,1044,1048,1069,1081],{"__ignoreMap":74},[78,883,884],{"class":80,"line":81},[78,885,886],{"class":101},"\u002F\u002F user.entity.ts\n",[78,888,889,891,893,896,898,901,903,906,908,910,912,915,917],{"class":80,"line":199},[78,890,169],{"class":168},[78,892,173],{"class":172},[78,894,895],{"class":176}," Entity",[78,897,406],{"class":172},[78,899,900],{"class":176}," Column",[78,902,406],{"class":172},[78,904,905],{"class":176}," PrimaryGeneratedColumn",[78,907,180],{"class":172},[78,909,183],{"class":168},[78,911,187],{"class":186},[78,913,914],{"class":88},"typeorm",[78,916,193],{"class":186},[78,918,196],{"class":172},[78,920,921],{"class":80,"line":221},[78,922,248],{"emptyLinePlaceholder":247},[78,924,925,927,930],{"class":80,"line":244},[78,926,254],{"class":172},[78,928,929],{"class":257},"Entity",[78,931,932],{"class":176},"()\n",[78,934,935,937,939,941],{"class":80,"line":251},[78,936,472],{"class":168},[78,938,476],{"class":475},[78,940,228],{"class":84},[78,942,943],{"class":172}," {\n",[78,945,946,949,952],{"class":80,"line":267},[78,947,948],{"class":172},"  @",[78,950,951],{"class":257},"PrimaryGeneratedColumn",[78,953,932],{"class":176},[78,955,956,960,962,966],{"class":80,"line":280},[78,957,959],{"class":958},"sucvu","  id",[78,961,274],{"class":610},[78,963,965],{"class":964},"sZMiF"," number",[78,967,196],{"class":172},[78,969,970],{"class":80,"line":295},[78,971,248],{"emptyLinePlaceholder":247},[78,973,974,976,979,981,984,987,989,992,994],{"class":80,"line":313},[78,975,948],{"class":172},[78,977,978],{"class":257},"Column",[78,980,261],{"class":176},[78,982,983],{"class":172},"{",[78,985,986],{"class":270}," length",[78,988,274],{"class":172},[78,990,991],{"class":338}," 100",[78,993,180],{"class":172},[78,995,466],{"class":176},[78,997,998,1001,1003,1006],{"class":80,"line":330},[78,999,1000],{"class":958},"  name",[78,1002,274],{"class":610},[78,1004,1005],{"class":964}," string",[78,1007,196],{"class":172},[78,1009,1010],{"class":80,"line":344},[78,1011,248],{"emptyLinePlaceholder":247},[78,1013,1014,1016,1018,1020,1022,1025,1027,1029,1031],{"class":80,"line":361},[78,1015,948],{"class":172},[78,1017,978],{"class":257},[78,1019,261],{"class":176},[78,1021,983],{"class":172},[78,1023,1024],{"class":270}," unique",[78,1026,274],{"class":172},[78,1028,421],{"class":420},[78,1030,180],{"class":172},[78,1032,466],{"class":176},[78,1034,1035,1038,1040,1042],{"class":80,"line":378},[78,1036,1037],{"class":958},"  email",[78,1039,274],{"class":610},[78,1041,1005],{"class":964},[78,1043,196],{"class":172},[78,1045,1046],{"class":80,"line":395},[78,1047,248],{"emptyLinePlaceholder":247},[78,1049,1050,1052,1054,1056,1058,1061,1063,1065,1067],{"class":80,"line":412},[78,1051,948],{"class":172},[78,1053,978],{"class":257},[78,1055,261],{"class":176},[78,1057,983],{"class":172},[78,1059,1060],{"class":270}," default",[78,1062,274],{"class":172},[78,1064,421],{"class":420},[78,1066,180],{"class":172},[78,1068,466],{"class":176},[78,1070,1071,1074,1076,1079],{"class":80,"line":429},[78,1072,1073],{"class":958},"  isActive",[78,1075,274],{"class":610},[78,1077,1078],{"class":964}," boolean",[78,1080,196],{"class":172},[78,1082,1083],{"class":80,"line":441},[78,1084,1085],{"class":172},"}\n",[23,1087,1088,488],{},[32,1089,1090],{},"常用装饰器",[111,1092,1093,1098,1103,1112],{},[114,1094,1095,1097],{},[27,1096,875],{},"：自增主键。",[114,1099,1100,1102],{},[27,1101,872],{},"：普通列，可传选项（长度、默认值、唯一等）。",[114,1104,1105,119,1108,1111],{},[27,1106,1107],{},"@CreateDateColumn()",[27,1109,1110],{},"@UpdateDateColumn()","：自动填充时间戳。",[114,1113,1114,1117],{},[27,1115,1116],{},"@Index()","：为字段创建索引。",[58,1119,1121],{"id":1120},"四repository-模式","四、Repository 模式",[23,1123,1124,1125,499,1128,499,1131,1134],{},"Repository 是操作数据库的核心接口，提供 ",[27,1126,1127],{},"find",[27,1129,1130],{},"save",[27,1132,1133],{},"delete"," 等方法。",[143,1136,1138],{"id":1137},"_1-注册-repository","1. 注册 Repository",[23,1140,1141,1142,1145],{},"在模块中使用 ",[27,1143,1144],{},"TypeOrmModule.forFeature()"," 注册实体，这样 NestJS 的 DI 容器就会提供对应的 Repository。",[69,1147,1149],{"className":159,"code":1148,"language":161,"meta":74,"style":74},"\u002F\u002F users.module.ts\nimport { Module } from \"@nestjs\u002Fcommon\";\nimport { TypeOrmModule } from \"@nestjs\u002Ftypeorm\";\nimport { User } from \".\u002Fuser.entity\";\nimport { UsersService } from \".\u002Fusers.service\";\nimport { UsersController } from \".\u002Fusers.controller\";\n\n@Module({\n  imports: [TypeOrmModule.forFeature([User])], \u002F\u002F 注册 User 仓库\n  providers: [UsersService],\n  controllers: [UsersController],\n})\nexport class UsersModule {}\n",[27,1150,1151,1156,1176,1196,1217,1239,1261,1265,1275,1297,1309,1321,1327],{"__ignoreMap":74},[78,1152,1153],{"class":80,"line":81},[78,1154,1155],{"class":101},"\u002F\u002F users.module.ts\n",[78,1157,1158,1160,1162,1164,1166,1168,1170,1172,1174],{"class":80,"line":199},[78,1159,169],{"class":168},[78,1161,173],{"class":172},[78,1163,177],{"class":176},[78,1165,180],{"class":172},[78,1167,183],{"class":168},[78,1169,187],{"class":186},[78,1171,190],{"class":88},[78,1173,193],{"class":186},[78,1175,196],{"class":172},[78,1177,1178,1180,1182,1184,1186,1188,1190,1192,1194],{"class":80,"line":221},[78,1179,169],{"class":168},[78,1181,173],{"class":172},[78,1183,206],{"class":176},[78,1185,180],{"class":172},[78,1187,183],{"class":168},[78,1189,187],{"class":186},[78,1191,29],{"class":88},[78,1193,193],{"class":186},[78,1195,196],{"class":172},[78,1197,1198,1200,1202,1204,1206,1208,1210,1213,1215],{"class":80,"line":244},[78,1199,169],{"class":168},[78,1201,173],{"class":172},[78,1203,228],{"class":176},[78,1205,180],{"class":172},[78,1207,183],{"class":168},[78,1209,187],{"class":186},[78,1211,1212],{"class":88},".\u002Fuser.entity",[78,1214,193],{"class":186},[78,1216,196],{"class":172},[78,1218,1219,1221,1223,1226,1228,1230,1232,1235,1237],{"class":80,"line":251},[78,1220,169],{"class":168},[78,1222,173],{"class":172},[78,1224,1225],{"class":176}," UsersService",[78,1227,180],{"class":172},[78,1229,183],{"class":168},[78,1231,187],{"class":186},[78,1233,1234],{"class":88},".\u002Fusers.service",[78,1236,193],{"class":186},[78,1238,196],{"class":172},[78,1240,1241,1243,1245,1248,1250,1252,1254,1257,1259],{"class":80,"line":267},[78,1242,169],{"class":168},[78,1244,173],{"class":172},[78,1246,1247],{"class":176}," UsersController",[78,1249,180],{"class":172},[78,1251,183],{"class":168},[78,1253,187],{"class":186},[78,1255,1256],{"class":88},".\u002Fusers.controller",[78,1258,193],{"class":186},[78,1260,196],{"class":172},[78,1262,1263],{"class":80,"line":280},[78,1264,248],{"emptyLinePlaceholder":247},[78,1266,1267,1269,1271,1273],{"class":80,"line":295},[78,1268,254],{"class":172},[78,1270,258],{"class":257},[78,1272,261],{"class":176},[78,1274,264],{"class":172},[78,1276,1277,1279,1281,1284,1286,1289,1292,1294],{"class":80,"line":313},[78,1278,271],{"class":270},[78,1280,274],{"class":172},[78,1282,1283],{"class":176}," [TypeOrmModule",[78,1285,286],{"class":172},[78,1287,1288],{"class":257},"forFeature",[78,1290,1291],{"class":176},"([User])]",[78,1293,406],{"class":172},[78,1295,1296],{"class":101}," \u002F\u002F 注册 User 仓库\n",[78,1298,1299,1302,1304,1307],{"class":80,"line":330},[78,1300,1301],{"class":270},"  providers",[78,1303,274],{"class":172},[78,1305,1306],{"class":176}," [UsersService]",[78,1308,310],{"class":172},[78,1310,1311,1314,1316,1319],{"class":80,"line":344},[78,1312,1313],{"class":270},"  controllers",[78,1315,274],{"class":172},[78,1317,1318],{"class":176}," [UsersController]",[78,1320,310],{"class":172},[78,1322,1323,1325],{"class":80,"line":361},[78,1324,463],{"class":172},[78,1326,466],{"class":176},[78,1328,1329,1331,1333,1336],{"class":80,"line":378},[78,1330,472],{"class":168},[78,1332,476],{"class":475},[78,1334,1335],{"class":84}," UsersModule",[78,1337,482],{"class":172},[143,1339,1341],{"id":1340},"_2-注入-repository","2. 注入 Repository",[23,1343,1344,1345,1348],{},"在 Service 中通过 ",[27,1346,1347],{},"@InjectRepository()"," 注入特定实体的 Repository。",[69,1350,1352],{"className":159,"code":1351,"language":161,"meta":74,"style":74},"\u002F\u002F users.service.ts\nimport { Injectable } from \"@nestjs\u002Fcommon\";\nimport { InjectRepository } from \"@nestjs\u002Ftypeorm\";\nimport { Repository } from \"typeorm\";\nimport { User } from \".\u002Fuser.entity\";\n\n@Injectable()\nexport class UsersService {\n  constructor(\n    @InjectRepository(User)\n    private usersRepository: Repository\u003CUser>,\n  ) {}\n\n  findAll(): Promise\u003CUser[]> {\n    return this.usersRepository.find();\n  }\n\n  findOne(id: number): Promise\u003CUser | null> {\n    return this.usersRepository.findOneBy({ id });\n  }\n\n  async create(userData: Partial\u003CUser>): Promise\u003CUser> {\n    const newUser = this.usersRepository.create(userData);\n    return this.usersRepository.save(newUser);\n  }\n\n  async remove(id: number): Promise\u003Cvoid> {\n    await this.usersRepository.delete(id);\n  }\n}\n",[27,1353,1354,1359,1380,1401,1422,1442,1446,1455,1465,1473,1484,1505,1512,1516,1542,1564,1569,1573,1607,1635,1639,1644,1682,1714,1738,1743,1748,1779,1803,1808],{"__ignoreMap":74},[78,1355,1356],{"class":80,"line":81},[78,1357,1358],{"class":101},"\u002F\u002F users.service.ts\n",[78,1360,1361,1363,1365,1368,1370,1372,1374,1376,1378],{"class":80,"line":199},[78,1362,169],{"class":168},[78,1364,173],{"class":172},[78,1366,1367],{"class":176}," Injectable",[78,1369,180],{"class":172},[78,1371,183],{"class":168},[78,1373,187],{"class":186},[78,1375,190],{"class":88},[78,1377,193],{"class":186},[78,1379,196],{"class":172},[78,1381,1382,1384,1386,1389,1391,1393,1395,1397,1399],{"class":80,"line":221},[78,1383,169],{"class":168},[78,1385,173],{"class":172},[78,1387,1388],{"class":176}," InjectRepository",[78,1390,180],{"class":172},[78,1392,183],{"class":168},[78,1394,187],{"class":186},[78,1396,29],{"class":88},[78,1398,193],{"class":186},[78,1400,196],{"class":172},[78,1402,1403,1405,1407,1410,1412,1414,1416,1418,1420],{"class":80,"line":244},[78,1404,169],{"class":168},[78,1406,173],{"class":172},[78,1408,1409],{"class":176}," Repository",[78,1411,180],{"class":172},[78,1413,183],{"class":168},[78,1415,187],{"class":186},[78,1417,914],{"class":88},[78,1419,193],{"class":186},[78,1421,196],{"class":172},[78,1423,1424,1426,1428,1430,1432,1434,1436,1438,1440],{"class":80,"line":251},[78,1425,169],{"class":168},[78,1427,173],{"class":172},[78,1429,228],{"class":176},[78,1431,180],{"class":172},[78,1433,183],{"class":168},[78,1435,187],{"class":186},[78,1437,1212],{"class":88},[78,1439,193],{"class":186},[78,1441,196],{"class":172},[78,1443,1444],{"class":80,"line":267},[78,1445,248],{"emptyLinePlaceholder":247},[78,1447,1448,1450,1453],{"class":80,"line":280},[78,1449,254],{"class":172},[78,1451,1452],{"class":257},"Injectable",[78,1454,932],{"class":176},[78,1456,1457,1459,1461,1463],{"class":80,"line":295},[78,1458,472],{"class":168},[78,1460,476],{"class":475},[78,1462,1225],{"class":84},[78,1464,943],{"class":172},[78,1466,1467,1470],{"class":80,"line":313},[78,1468,1469],{"class":475},"  constructor",[78,1471,1472],{"class":172},"(\n",[78,1474,1475,1478,1481],{"class":80,"line":330},[78,1476,1477],{"class":172},"    @",[78,1479,1480],{"class":257},"InjectRepository",[78,1482,1483],{"class":176},"(User)\n",[78,1485,1486,1489,1492,1494,1496,1499,1502],{"class":80,"line":344},[78,1487,1488],{"class":475},"    private",[78,1490,1491],{"class":606}," usersRepository",[78,1493,274],{"class":610},[78,1495,1409],{"class":84},[78,1497,1498],{"class":172},"\u003C",[78,1500,1501],{"class":84},"User",[78,1503,1504],{"class":172},">,\n",[78,1506,1507,1510],{"class":80,"line":361},[78,1508,1509],{"class":172},"  )",[78,1511,482],{"class":172},[78,1513,1514],{"class":80,"line":378},[78,1515,248],{"emptyLinePlaceholder":247},[78,1517,1518,1522,1525,1527,1530,1532,1534,1537,1540],{"class":80,"line":395},[78,1519,1521],{"class":1520},"sVXei","  findAll",[78,1523,1524],{"class":172},"()",[78,1526,274],{"class":610},[78,1528,1529],{"class":84}," Promise",[78,1531,1498],{"class":172},[78,1533,1501],{"class":84},[78,1535,1536],{"class":176},"[]",[78,1538,1539],{"class":172},">",[78,1541,943],{"class":172},[78,1543,1544,1547,1551,1553,1556,1558,1560,1562],{"class":80,"line":412},[78,1545,1546],{"class":168},"    return",[78,1548,1550],{"class":1549},"s39Yj"," this",[78,1552,286],{"class":172},[78,1554,1555],{"class":176},"usersRepository",[78,1557,286],{"class":172},[78,1559,1127],{"class":257},[78,1561,1524],{"class":270},[78,1563,196],{"class":172},[78,1565,1566],{"class":80,"line":429},[78,1567,1568],{"class":172},"  }\n",[78,1570,1571],{"class":80,"line":441},[78,1572,248],{"emptyLinePlaceholder":247},[78,1574,1575,1578,1580,1583,1585,1587,1589,1591,1593,1595,1597,1600,1603,1605],{"class":80,"line":452},[78,1576,1577],{"class":1520},"  findOne",[78,1579,261],{"class":172},[78,1581,1582],{"class":606},"id",[78,1584,274],{"class":610},[78,1586,965],{"class":964},[78,1588,447],{"class":172},[78,1590,274],{"class":610},[78,1592,1529],{"class":84},[78,1594,1498],{"class":172},[78,1596,1501],{"class":84},[78,1598,1599],{"class":610}," |",[78,1601,1602],{"class":964}," null",[78,1604,1539],{"class":172},[78,1606,943],{"class":172},[78,1608,1609,1611,1613,1615,1617,1619,1622,1624,1626,1629,1631,1633],{"class":80,"line":460},[78,1610,1546],{"class":168},[78,1612,1550],{"class":1549},[78,1614,286],{"class":172},[78,1616,1555],{"class":176},[78,1618,286],{"class":172},[78,1620,1621],{"class":257},"findOneBy",[78,1623,261],{"class":270},[78,1625,983],{"class":172},[78,1627,1628],{"class":176}," id",[78,1630,180],{"class":172},[78,1632,447],{"class":270},[78,1634,196],{"class":172},[78,1636,1637],{"class":80,"line":469},[78,1638,1568],{"class":172},[78,1640,1642],{"class":80,"line":1641},21,[78,1643,248],{"emptyLinePlaceholder":247},[78,1645,1647,1650,1653,1655,1658,1660,1663,1665,1667,1670,1672,1674,1676,1678,1680],{"class":80,"line":1646},22,[78,1648,1649],{"class":475},"  async",[78,1651,1652],{"class":1520}," create",[78,1654,261],{"class":172},[78,1656,1657],{"class":606},"userData",[78,1659,274],{"class":610},[78,1661,1662],{"class":84}," Partial",[78,1664,1498],{"class":172},[78,1666,1501],{"class":84},[78,1668,1669],{"class":172},">)",[78,1671,274],{"class":610},[78,1673,1529],{"class":84},[78,1675,1498],{"class":172},[78,1677,1501],{"class":84},[78,1679,1539],{"class":172},[78,1681,943],{"class":172},[78,1683,1685,1688,1692,1695,1697,1699,1701,1703,1706,1708,1710,1712],{"class":80,"line":1684},23,[78,1686,1687],{"class":475},"    const",[78,1689,1691],{"class":1690},"s_hVV"," newUser",[78,1693,1694],{"class":610}," =",[78,1696,1550],{"class":1549},[78,1698,286],{"class":172},[78,1700,1555],{"class":176},[78,1702,286],{"class":172},[78,1704,1705],{"class":257},"create",[78,1707,261],{"class":270},[78,1709,1657],{"class":176},[78,1711,447],{"class":270},[78,1713,196],{"class":172},[78,1715,1717,1719,1721,1723,1725,1727,1729,1731,1734,1736],{"class":80,"line":1716},24,[78,1718,1546],{"class":168},[78,1720,1550],{"class":1549},[78,1722,286],{"class":172},[78,1724,1555],{"class":176},[78,1726,286],{"class":172},[78,1728,1130],{"class":257},[78,1730,261],{"class":270},[78,1732,1733],{"class":176},"newUser",[78,1735,447],{"class":270},[78,1737,196],{"class":172},[78,1739,1741],{"class":80,"line":1740},25,[78,1742,1568],{"class":172},[78,1744,1746],{"class":80,"line":1745},26,[78,1747,248],{"emptyLinePlaceholder":247},[78,1749,1751,1753,1756,1758,1760,1762,1764,1766,1768,1770,1772,1775,1777],{"class":80,"line":1750},27,[78,1752,1649],{"class":475},[78,1754,1755],{"class":1520}," remove",[78,1757,261],{"class":172},[78,1759,1582],{"class":606},[78,1761,274],{"class":610},[78,1763,965],{"class":964},[78,1765,447],{"class":172},[78,1767,274],{"class":610},[78,1769,1529],{"class":84},[78,1771,1498],{"class":172},[78,1773,1774],{"class":964},"void",[78,1776,1539],{"class":172},[78,1778,943],{"class":172},[78,1780,1782,1785,1787,1789,1791,1793,1795,1797,1799,1801],{"class":80,"line":1781},28,[78,1783,1784],{"class":168},"    await",[78,1786,1550],{"class":1549},[78,1788,286],{"class":172},[78,1790,1555],{"class":176},[78,1792,286],{"class":172},[78,1794,1133],{"class":257},[78,1796,261],{"class":270},[78,1798,1582],{"class":176},[78,1800,447],{"class":270},[78,1802,196],{"class":172},[78,1804,1806],{"class":80,"line":1805},29,[78,1807,1568],{"class":172},[78,1809,1811],{"class":80,"line":1810},30,[78,1812,1085],{"class":172},[58,1814,1816],{"id":1815},"五关系relationships","五、关系（Relationships）",[23,1818,1819],{},"TypeORM 支持常见的关系映射，通过装饰器声明。",[1821,1822,1823,1839],"table",{},[1824,1825,1826],"thead",{},[1827,1828,1829,1833,1836],"tr",{},[1830,1831,1832],"th",{},"关系",[1830,1834,1835],{},"装饰器",[1830,1837,1838],{},"示例",[1840,1841,1842,1865,1882],"tbody",{},[1827,1843,1844,1848,1857],{},[1845,1846,1847],"td",{},"一对多",[1845,1849,1850,1853,1854],{},[27,1851,1852],{},"@OneToMany"," + ",[27,1855,1856],{},"@ManyToOne",[1845,1858,1859,1861,1862],{},[27,1860,1501],{}," ↔ ",[27,1863,1864],{},"Post",[1827,1866,1867,1870,1875],{},[1845,1868,1869],{},"一对一",[1845,1871,1872],{},[27,1873,1874],{},"@OneToOne",[1845,1876,1877,1861,1879],{},[27,1878,1501],{},[27,1880,1881],{},"Profile",[1827,1883,1884,1887,1895],{},[1845,1885,1886],{},"多对多",[1845,1888,1889,1853,1892],{},[27,1890,1891],{},"@ManyToMany",[27,1893,1894],{},"@JoinTable",[1845,1896,1897,1861,1899],{},[27,1898,1501],{},[27,1900,1901],{},"Role",[23,1903,1904],{},[32,1905,1906],{},"示例：User 与 Post 的一对多关系",[69,1908,1910],{"className":159,"code":1909,"language":161,"meta":74,"style":74},"\u002F\u002F user.entity.ts\nimport { OneToMany } from \"typeorm\";\nimport { Post } from \".\u002Fpost.entity\";\n\n@Entity()\nexport class User {\n  @PrimaryGeneratedColumn()\n  id: number;\n\n  @OneToMany(() => Post, (post) => post.user)\n  posts: Post[];\n}\n\n\u002F\u002F post.entity.ts\n@Entity()\nexport class Post {\n  @PrimaryGeneratedColumn()\n  id: number;\n\n  @ManyToOne(() => User, (user) => user.posts)\n  user: User;\n}\n",[27,1911,1912,1916,1937,1959,1963,1971,1981,1989,1999,2003,2037,2050,2054,2058,2063,2071,2081,2089,2099,2103,2137,2148],{"__ignoreMap":74},[78,1913,1914],{"class":80,"line":81},[78,1915,886],{"class":101},[78,1917,1918,1920,1922,1925,1927,1929,1931,1933,1935],{"class":80,"line":199},[78,1919,169],{"class":168},[78,1921,173],{"class":172},[78,1923,1924],{"class":176}," OneToMany",[78,1926,180],{"class":172},[78,1928,183],{"class":168},[78,1930,187],{"class":186},[78,1932,914],{"class":88},[78,1934,193],{"class":186},[78,1936,196],{"class":172},[78,1938,1939,1941,1943,1946,1948,1950,1952,1955,1957],{"class":80,"line":221},[78,1940,169],{"class":168},[78,1942,173],{"class":172},[78,1944,1945],{"class":176}," Post",[78,1947,180],{"class":172},[78,1949,183],{"class":168},[78,1951,187],{"class":186},[78,1953,1954],{"class":88},".\u002Fpost.entity",[78,1956,193],{"class":186},[78,1958,196],{"class":172},[78,1960,1961],{"class":80,"line":244},[78,1962,248],{"emptyLinePlaceholder":247},[78,1964,1965,1967,1969],{"class":80,"line":251},[78,1966,254],{"class":172},[78,1968,929],{"class":257},[78,1970,932],{"class":176},[78,1972,1973,1975,1977,1979],{"class":80,"line":267},[78,1974,472],{"class":168},[78,1976,476],{"class":475},[78,1978,228],{"class":84},[78,1980,943],{"class":172},[78,1982,1983,1985,1987],{"class":80,"line":280},[78,1984,948],{"class":172},[78,1986,951],{"class":257},[78,1988,932],{"class":176},[78,1990,1991,1993,1995,1997],{"class":80,"line":295},[78,1992,959],{"class":958},[78,1994,274],{"class":610},[78,1996,965],{"class":964},[78,1998,196],{"class":172},[78,2000,2001],{"class":80,"line":313},[78,2002,248],{"emptyLinePlaceholder":247},[78,2004,2005,2007,2010,2012,2014,2016,2018,2020,2022,2025,2027,2029,2032,2034],{"class":80,"line":330},[78,2006,948],{"class":172},[78,2008,2009],{"class":257},"OneToMany",[78,2011,261],{"class":176},[78,2013,1524],{"class":172},[78,2015,618],{"class":475},[78,2017,1945],{"class":176},[78,2019,406],{"class":172},[78,2021,603],{"class":172},[78,2023,2024],{"class":606},"post",[78,2026,447],{"class":172},[78,2028,618],{"class":475},[78,2030,2031],{"class":176}," post",[78,2033,286],{"class":172},[78,2035,2036],{"class":176},"user)\n",[78,2038,2039,2042,2044,2046,2048],{"class":80,"line":344},[78,2040,2041],{"class":958},"  posts",[78,2043,274],{"class":610},[78,2045,1945],{"class":84},[78,2047,1536],{"class":176},[78,2049,196],{"class":172},[78,2051,2052],{"class":80,"line":361},[78,2053,1085],{"class":172},[78,2055,2056],{"class":80,"line":378},[78,2057,248],{"emptyLinePlaceholder":247},[78,2059,2060],{"class":80,"line":395},[78,2061,2062],{"class":101},"\u002F\u002F post.entity.ts\n",[78,2064,2065,2067,2069],{"class":80,"line":412},[78,2066,254],{"class":172},[78,2068,929],{"class":257},[78,2070,932],{"class":176},[78,2072,2073,2075,2077,2079],{"class":80,"line":429},[78,2074,472],{"class":168},[78,2076,476],{"class":475},[78,2078,1945],{"class":84},[78,2080,943],{"class":172},[78,2082,2083,2085,2087],{"class":80,"line":441},[78,2084,948],{"class":172},[78,2086,951],{"class":257},[78,2088,932],{"class":176},[78,2090,2091,2093,2095,2097],{"class":80,"line":452},[78,2092,959],{"class":958},[78,2094,274],{"class":610},[78,2096,965],{"class":964},[78,2098,196],{"class":172},[78,2100,2101],{"class":80,"line":460},[78,2102,248],{"emptyLinePlaceholder":247},[78,2104,2105,2107,2110,2112,2114,2116,2118,2120,2122,2125,2127,2129,2132,2134],{"class":80,"line":469},[78,2106,948],{"class":172},[78,2108,2109],{"class":257},"ManyToOne",[78,2111,261],{"class":176},[78,2113,1524],{"class":172},[78,2115,618],{"class":475},[78,2117,228],{"class":176},[78,2119,406],{"class":172},[78,2121,603],{"class":172},[78,2123,2124],{"class":606},"user",[78,2126,447],{"class":172},[78,2128,618],{"class":475},[78,2130,2131],{"class":176}," user",[78,2133,286],{"class":172},[78,2135,2136],{"class":176},"posts)\n",[78,2138,2139,2142,2144,2146],{"class":80,"line":1641},[78,2140,2141],{"class":958},"  user",[78,2143,274],{"class":610},[78,2145,228],{"class":84},[78,2147,196],{"class":172},[78,2149,2150],{"class":80,"line":1646},[78,2151,1085],{"class":172},[23,2153,2154,2155,2158],{},"查询时使用 ",[27,2156,2157],{},"relations"," 选项加载关联：",[69,2160,2162],{"className":159,"code":2161,"language":161,"meta":74,"style":74},"const user = await this.usersRepository.findOne({\n  where: { id: 1 },\n  relations: [\"posts\"],\n});\n",[27,2163,2164,2191,2210,2232],{"__ignoreMap":74},[78,2165,2166,2169,2171,2173,2176,2178,2180,2182,2184,2187,2189],{"class":80,"line":81},[78,2167,2168],{"class":475},"const",[78,2170,2131],{"class":1690},[78,2172,1694],{"class":610},[78,2174,2175],{"class":168}," await",[78,2177,1550],{"class":1549},[78,2179,286],{"class":172},[78,2181,1555],{"class":176},[78,2183,286],{"class":172},[78,2185,2186],{"class":257},"findOne",[78,2188,261],{"class":176},[78,2190,264],{"class":172},[78,2192,2193,2196,2198,2200,2202,2204,2207],{"class":80,"line":199},[78,2194,2195],{"class":270},"  where",[78,2197,274],{"class":172},[78,2199,173],{"class":172},[78,2201,1628],{"class":270},[78,2203,274],{"class":172},[78,2205,2206],{"class":338}," 1",[78,2208,2209],{"class":172}," },\n",[78,2211,2212,2215,2217,2220,2222,2225,2227,2230],{"class":80,"line":221},[78,2213,2214],{"class":270},"  relations",[78,2216,274],{"class":172},[78,2218,2219],{"class":176}," [",[78,2221,193],{"class":186},[78,2223,2224],{"class":88},"posts",[78,2226,193],{"class":186},[78,2228,2229],{"class":176},"]",[78,2231,310],{"class":172},[78,2233,2234,2236,2238],{"class":80,"line":244},[78,2235,463],{"class":172},[78,2237,447],{"class":176},[78,2239,196],{"class":172},[58,2241,2243],{"id":2242},"六事务transaction","六、事务（Transaction）",[23,2245,2246,2247,2250],{},"TypeORM 提供多种事务方式，NestJS 推荐使用 ",[27,2248,2249],{},"QueryRunner"," 进行显式事务控制。",[69,2252,2254],{"className":159,"code":2253,"language":161,"meta":74,"style":74},"import { Injectable } from \"@nestjs\u002Fcommon\";\nimport { InjectDataSource } from \"@nestjs\u002Ftypeorm\";\nimport { DataSource } from \"typeorm\";\n\n@Injectable()\nexport class OrderService {\n  constructor(@InjectDataSource() private dataSource: DataSource) {}\n\n  async createOrderWithItems() {\n    const queryRunner = this.dataSource.createQueryRunner();\n    await queryRunner.connect();\n    await queryRunner.startTransaction();\n\n    try {\n      \u002F\u002F 使用 queryRunner.manager 进行数据库操作\n      const order = await queryRunner.manager.save(Order, { userId: 1 });\n      const item = await queryRunner.manager.save(OrderItem, { orderId: order.id });\n\n      await queryRunner.commitTransaction();\n      return { order, item };\n    } catch (err) {\n      await queryRunner.rollbackTransaction();\n      throw err;\n    } finally {\n      await queryRunner.release();\n    }\n  }\n}\n",[27,2255,2256,2276,2297,2318,2322,2330,2341,2368,2372,2383,2408,2423,2438,2442,2449,2454,2499,2546,2550,2566,2582,2598,2613,2623,2632,2647,2652,2656],{"__ignoreMap":74},[78,2257,2258,2260,2262,2264,2266,2268,2270,2272,2274],{"class":80,"line":81},[78,2259,169],{"class":168},[78,2261,173],{"class":172},[78,2263,1367],{"class":176},[78,2265,180],{"class":172},[78,2267,183],{"class":168},[78,2269,187],{"class":186},[78,2271,190],{"class":88},[78,2273,193],{"class":186},[78,2275,196],{"class":172},[78,2277,2278,2280,2282,2285,2287,2289,2291,2293,2295],{"class":80,"line":199},[78,2279,169],{"class":168},[78,2281,173],{"class":172},[78,2283,2284],{"class":176}," InjectDataSource",[78,2286,180],{"class":172},[78,2288,183],{"class":168},[78,2290,187],{"class":186},[78,2292,29],{"class":88},[78,2294,193],{"class":186},[78,2296,196],{"class":172},[78,2298,2299,2301,2303,2306,2308,2310,2312,2314,2316],{"class":80,"line":221},[78,2300,169],{"class":168},[78,2302,173],{"class":172},[78,2304,2305],{"class":176}," DataSource",[78,2307,180],{"class":172},[78,2309,183],{"class":168},[78,2311,187],{"class":186},[78,2313,914],{"class":88},[78,2315,193],{"class":186},[78,2317,196],{"class":172},[78,2319,2320],{"class":80,"line":244},[78,2321,248],{"emptyLinePlaceholder":247},[78,2323,2324,2326,2328],{"class":80,"line":251},[78,2325,254],{"class":172},[78,2327,1452],{"class":257},[78,2329,932],{"class":176},[78,2331,2332,2334,2336,2339],{"class":80,"line":267},[78,2333,472],{"class":168},[78,2335,476],{"class":475},[78,2337,2338],{"class":84}," OrderService",[78,2340,943],{"class":172},[78,2342,2343,2345,2348,2351,2354,2357,2360,2362,2364,2366],{"class":80,"line":280},[78,2344,1469],{"class":475},[78,2346,2347],{"class":172},"(@",[78,2349,2350],{"class":257},"InjectDataSource",[78,2352,2353],{"class":176},"() ",[78,2355,2356],{"class":475},"private",[78,2358,2359],{"class":606}," dataSource",[78,2361,274],{"class":610},[78,2363,2305],{"class":84},[78,2365,447],{"class":172},[78,2367,482],{"class":172},[78,2369,2370],{"class":80,"line":295},[78,2371,248],{"emptyLinePlaceholder":247},[78,2373,2374,2376,2379,2381],{"class":80,"line":313},[78,2375,1649],{"class":475},[78,2377,2378],{"class":1520}," createOrderWithItems",[78,2380,1524],{"class":172},[78,2382,943],{"class":172},[78,2384,2385,2387,2390,2392,2394,2396,2399,2401,2404,2406],{"class":80,"line":330},[78,2386,1687],{"class":475},[78,2388,2389],{"class":1690}," queryRunner",[78,2391,1694],{"class":610},[78,2393,1550],{"class":1549},[78,2395,286],{"class":172},[78,2397,2398],{"class":176},"dataSource",[78,2400,286],{"class":172},[78,2402,2403],{"class":257},"createQueryRunner",[78,2405,1524],{"class":270},[78,2407,196],{"class":172},[78,2409,2410,2412,2414,2416,2419,2421],{"class":80,"line":344},[78,2411,1784],{"class":168},[78,2413,2389],{"class":176},[78,2415,286],{"class":172},[78,2417,2418],{"class":257},"connect",[78,2420,1524],{"class":270},[78,2422,196],{"class":172},[78,2424,2425,2427,2429,2431,2434,2436],{"class":80,"line":361},[78,2426,1784],{"class":168},[78,2428,2389],{"class":176},[78,2430,286],{"class":172},[78,2432,2433],{"class":257},"startTransaction",[78,2435,1524],{"class":270},[78,2437,196],{"class":172},[78,2439,2440],{"class":80,"line":378},[78,2441,248],{"emptyLinePlaceholder":247},[78,2443,2444,2447],{"class":80,"line":395},[78,2445,2446],{"class":168},"    try",[78,2448,943],{"class":172},[78,2450,2451],{"class":80,"line":412},[78,2452,2453],{"class":101},"      \u002F\u002F 使用 queryRunner.manager 进行数据库操作\n",[78,2455,2456,2459,2462,2464,2466,2468,2470,2473,2475,2477,2479,2482,2484,2486,2489,2491,2493,2495,2497],{"class":80,"line":429},[78,2457,2458],{"class":475},"      const",[78,2460,2461],{"class":1690}," order",[78,2463,1694],{"class":610},[78,2465,2175],{"class":168},[78,2467,2389],{"class":176},[78,2469,286],{"class":172},[78,2471,2472],{"class":176},"manager",[78,2474,286],{"class":172},[78,2476,1130],{"class":257},[78,2478,261],{"class":270},[78,2480,2481],{"class":176},"Order",[78,2483,406],{"class":172},[78,2485,173],{"class":172},[78,2487,2488],{"class":270}," userId",[78,2490,274],{"class":172},[78,2492,2206],{"class":338},[78,2494,180],{"class":172},[78,2496,447],{"class":270},[78,2498,196],{"class":172},[78,2500,2501,2503,2506,2508,2510,2512,2514,2516,2518,2520,2522,2525,2527,2529,2532,2534,2536,2538,2540,2542,2544],{"class":80,"line":441},[78,2502,2458],{"class":475},[78,2504,2505],{"class":1690}," item",[78,2507,1694],{"class":610},[78,2509,2175],{"class":168},[78,2511,2389],{"class":176},[78,2513,286],{"class":172},[78,2515,2472],{"class":176},[78,2517,286],{"class":172},[78,2519,1130],{"class":257},[78,2521,261],{"class":270},[78,2523,2524],{"class":176},"OrderItem",[78,2526,406],{"class":172},[78,2528,173],{"class":172},[78,2530,2531],{"class":270}," orderId",[78,2533,274],{"class":172},[78,2535,2461],{"class":176},[78,2537,286],{"class":172},[78,2539,1582],{"class":176},[78,2541,180],{"class":172},[78,2543,447],{"class":270},[78,2545,196],{"class":172},[78,2547,2548],{"class":80,"line":452},[78,2549,248],{"emptyLinePlaceholder":247},[78,2551,2552,2555,2557,2559,2562,2564],{"class":80,"line":460},[78,2553,2554],{"class":168},"      await",[78,2556,2389],{"class":176},[78,2558,286],{"class":172},[78,2560,2561],{"class":257},"commitTransaction",[78,2563,1524],{"class":270},[78,2565,196],{"class":172},[78,2567,2568,2571,2573,2575,2577,2579],{"class":80,"line":469},[78,2569,2570],{"class":168},"      return",[78,2572,173],{"class":172},[78,2574,2461],{"class":176},[78,2576,406],{"class":172},[78,2578,2505],{"class":176},[78,2580,2581],{"class":172}," };\n",[78,2583,2584,2586,2589,2591,2594,2596],{"class":80,"line":1641},[78,2585,444],{"class":172},[78,2587,2588],{"class":168}," catch",[78,2590,603],{"class":270},[78,2592,2593],{"class":176},"err",[78,2595,811],{"class":270},[78,2597,264],{"class":172},[78,2599,2600,2602,2604,2606,2609,2611],{"class":80,"line":1646},[78,2601,2554],{"class":168},[78,2603,2389],{"class":176},[78,2605,286],{"class":172},[78,2607,2608],{"class":257},"rollbackTransaction",[78,2610,1524],{"class":270},[78,2612,196],{"class":172},[78,2614,2615,2618,2621],{"class":80,"line":1684},[78,2616,2617],{"class":168},"      throw",[78,2619,2620],{"class":176}," err",[78,2622,196],{"class":172},[78,2624,2625,2627,2630],{"class":80,"line":1716},[78,2626,444],{"class":172},[78,2628,2629],{"class":168}," finally",[78,2631,943],{"class":172},[78,2633,2634,2636,2638,2640,2643,2645],{"class":80,"line":1740},[78,2635,2554],{"class":168},[78,2637,2389],{"class":176},[78,2639,286],{"class":172},[78,2641,2642],{"class":257},"release",[78,2644,1524],{"class":270},[78,2646,196],{"class":172},[78,2648,2649],{"class":80,"line":1745},[78,2650,2651],{"class":172},"    }\n",[78,2653,2654],{"class":80,"line":1750},[78,2655,1568],{"class":172},[78,2657,2658],{"class":80,"line":1781},[78,2659,1085],{"class":172},[23,2661,2662,488,2665,2668,2669,2672,2673,2675],{},[32,2663,2664],{},"注意",[27,2666,2667],{},"@Transaction"," 和 ",[27,2670,2671],{},"@TransactionManager"," 装饰器已过时，推荐使用 ",[27,2674,2249],{}," 方式。",[58,2677,2679],{"id":2678},"七其他-orm-odm","七、其他 ORM \u002F ODM",[143,2681,2683,2684,447],{"id":2682},"_1-sequelize-nestjssequelize","1. Sequelize (",[27,2685,2686],{},"@nestjs\u002Fsequelize",[23,2688,2689],{},"Sequelize 是另一个流行的 Node.js ORM，支持 PostgreSQL、MySQL 等。",[69,2691,2693],{"className":159,"code":2692,"language":161,"meta":74,"style":74},"import { SequelizeModule } from \"@nestjs\u002Fsequelize\";\n\n@Module({\n  imports: [\n    SequelizeModule.forRoot({\n      dialect: \"mysql\",\n      host: \"localhost\",\n      port: 3306,\n      username: \"root\",\n      password: \"password\",\n      database: \"test\",\n      models: [User],\n    }),\n    SequelizeModule.forFeature([User]), \u002F\u002F 注册模型\n  ],\n})\nexport class AppModule {}\n",[27,2694,2695,2716,2720,2730,2738,2751,2766,2780,2790,2804,2818,2832,2843,2851,2867,2873,2879],{"__ignoreMap":74},[78,2696,2697,2699,2701,2704,2706,2708,2710,2712,2714],{"class":80,"line":81},[78,2698,169],{"class":168},[78,2700,173],{"class":172},[78,2702,2703],{"class":176}," SequelizeModule",[78,2705,180],{"class":172},[78,2707,183],{"class":168},[78,2709,187],{"class":186},[78,2711,2686],{"class":88},[78,2713,193],{"class":186},[78,2715,196],{"class":172},[78,2717,2718],{"class":80,"line":199},[78,2719,248],{"emptyLinePlaceholder":247},[78,2721,2722,2724,2726,2728],{"class":80,"line":221},[78,2723,254],{"class":172},[78,2725,258],{"class":257},[78,2727,261],{"class":176},[78,2729,264],{"class":172},[78,2731,2732,2734,2736],{"class":80,"line":244},[78,2733,271],{"class":270},[78,2735,274],{"class":172},[78,2737,277],{"class":176},[78,2739,2740,2743,2745,2747,2749],{"class":80,"line":251},[78,2741,2742],{"class":176},"    SequelizeModule",[78,2744,286],{"class":172},[78,2746,149],{"class":257},[78,2748,261],{"class":176},[78,2750,264],{"class":172},[78,2752,2753,2756,2758,2760,2762,2764],{"class":80,"line":267},[78,2754,2755],{"class":270},"      dialect",[78,2757,274],{"class":172},[78,2759,187],{"class":186},[78,2761,305],{"class":88},[78,2763,193],{"class":186},[78,2765,310],{"class":172},[78,2767,2768,2770,2772,2774,2776,2778],{"class":80,"line":280},[78,2769,316],{"class":270},[78,2771,274],{"class":172},[78,2773,187],{"class":186},[78,2775,323],{"class":88},[78,2777,193],{"class":186},[78,2779,310],{"class":172},[78,2781,2782,2784,2786,2788],{"class":80,"line":295},[78,2783,333],{"class":270},[78,2785,274],{"class":172},[78,2787,339],{"class":338},[78,2789,310],{"class":172},[78,2791,2792,2794,2796,2798,2800,2802],{"class":80,"line":313},[78,2793,347],{"class":270},[78,2795,274],{"class":172},[78,2797,187],{"class":186},[78,2799,354],{"class":88},[78,2801,193],{"class":186},[78,2803,310],{"class":172},[78,2805,2806,2808,2810,2812,2814,2816],{"class":80,"line":330},[78,2807,364],{"class":270},[78,2809,274],{"class":172},[78,2811,187],{"class":186},[78,2813,371],{"class":88},[78,2815,193],{"class":186},[78,2817,310],{"class":172},[78,2819,2820,2822,2824,2826,2828,2830],{"class":80,"line":344},[78,2821,381],{"class":270},[78,2823,274],{"class":172},[78,2825,187],{"class":186},[78,2827,388],{"class":88},[78,2829,193],{"class":186},[78,2831,310],{"class":172},[78,2833,2834,2837,2839,2841],{"class":80,"line":361},[78,2835,2836],{"class":270},"      models",[78,2838,274],{"class":172},[78,2840,403],{"class":176},[78,2842,310],{"class":172},[78,2844,2845,2847,2849],{"class":80,"line":378},[78,2846,444],{"class":172},[78,2848,447],{"class":176},[78,2850,310],{"class":172},[78,2852,2853,2855,2857,2859,2862,2864],{"class":80,"line":395},[78,2854,2742],{"class":176},[78,2856,286],{"class":172},[78,2858,1288],{"class":257},[78,2860,2861],{"class":176},"([User])",[78,2863,406],{"class":172},[78,2865,2866],{"class":101}," \u002F\u002F 注册模型\n",[78,2868,2869,2871],{"class":80,"line":412},[78,2870,455],{"class":176},[78,2872,310],{"class":172},[78,2874,2875,2877],{"class":80,"line":429},[78,2876,463],{"class":172},[78,2878,466],{"class":176},[78,2880,2881,2883,2885,2887],{"class":80,"line":441},[78,2882,472],{"class":168},[78,2884,476],{"class":475},[78,2886,479],{"class":84},[78,2888,482],{"class":172},[23,2890,2891],{},"在 Service 中注入模型：",[69,2893,2895],{"className":159,"code":2894,"language":161,"meta":74,"style":74},"@Injectable()\nexport class UsersService {\n  constructor(@InjectModel(User) private userModel: typeof User) {}\n  async findAll() {\n    return this.userModel.findAll();\n  }\n}\n",[27,2896,2897,2905,2915,2943,2954,2974,2978],{"__ignoreMap":74},[78,2898,2899,2901,2903],{"class":80,"line":81},[78,2900,254],{"class":172},[78,2902,1452],{"class":257},[78,2904,932],{"class":176},[78,2906,2907,2909,2911,2913],{"class":80,"line":199},[78,2908,472],{"class":168},[78,2910,476],{"class":475},[78,2912,1225],{"class":84},[78,2914,943],{"class":172},[78,2916,2917,2919,2921,2924,2927,2929,2932,2934,2937,2939,2941],{"class":80,"line":221},[78,2918,1469],{"class":475},[78,2920,2347],{"class":172},[78,2922,2923],{"class":257},"InjectModel",[78,2925,2926],{"class":176},"(User) ",[78,2928,2356],{"class":475},[78,2930,2931],{"class":606}," userModel",[78,2933,274],{"class":610},[78,2935,2936],{"class":610}," typeof",[78,2938,228],{"class":176},[78,2940,447],{"class":172},[78,2942,482],{"class":172},[78,2944,2945,2947,2950,2952],{"class":80,"line":244},[78,2946,1649],{"class":475},[78,2948,2949],{"class":1520}," findAll",[78,2951,1524],{"class":172},[78,2953,943],{"class":172},[78,2955,2956,2958,2960,2962,2965,2967,2970,2972],{"class":80,"line":251},[78,2957,1546],{"class":168},[78,2959,1550],{"class":1549},[78,2961,286],{"class":172},[78,2963,2964],{"class":176},"userModel",[78,2966,286],{"class":172},[78,2968,2969],{"class":257},"findAll",[78,2971,1524],{"class":270},[78,2973,196],{"class":172},[78,2975,2976],{"class":80,"line":267},[78,2977,1568],{"class":172},[78,2979,2980],{"class":80,"line":280},[78,2981,1085],{"class":172},[143,2983,2985,2986,447],{"id":2984},"_2-mongoose-nestjsmongoose","2. Mongoose (",[27,2987,2988],{},"@nestjs\u002Fmongoose",[23,2990,2991],{},"用于 MongoDB 数据库，基于 Mongoose ODM。",[69,2993,2995],{"className":159,"code":2994,"language":161,"meta":74,"style":74},"import { MongooseModule } from \"@nestjs\u002Fmongoose\";\n\n@Module({\n  imports: [\n    MongooseModule.forRoot(\"mongodb:\u002F\u002Flocalhost:27017\u002Fnest\"),\n    MongooseModule.forFeature([{ name: \"Cat\", schema: CatSchema }]),\n  ],\n})\nexport class AppModule {}\n",[27,2996,2997,3018,3022,3032,3040,3062,3104,3110,3116],{"__ignoreMap":74},[78,2998,2999,3001,3003,3006,3008,3010,3012,3014,3016],{"class":80,"line":81},[78,3000,169],{"class":168},[78,3002,173],{"class":172},[78,3004,3005],{"class":176}," MongooseModule",[78,3007,180],{"class":172},[78,3009,183],{"class":168},[78,3011,187],{"class":186},[78,3013,2988],{"class":88},[78,3015,193],{"class":186},[78,3017,196],{"class":172},[78,3019,3020],{"class":80,"line":199},[78,3021,248],{"emptyLinePlaceholder":247},[78,3023,3024,3026,3028,3030],{"class":80,"line":221},[78,3025,254],{"class":172},[78,3027,258],{"class":257},[78,3029,261],{"class":176},[78,3031,264],{"class":172},[78,3033,3034,3036,3038],{"class":80,"line":244},[78,3035,271],{"class":270},[78,3037,274],{"class":172},[78,3039,277],{"class":176},[78,3041,3042,3045,3047,3049,3051,3053,3056,3058,3060],{"class":80,"line":251},[78,3043,3044],{"class":176},"    MongooseModule",[78,3046,286],{"class":172},[78,3048,149],{"class":257},[78,3050,261],{"class":176},[78,3052,193],{"class":186},[78,3054,3055],{"class":88},"mongodb:\u002F\u002Flocalhost:27017\u002Fnest",[78,3057,193],{"class":186},[78,3059,447],{"class":176},[78,3061,310],{"class":172},[78,3063,3064,3066,3068,3070,3073,3075,3078,3080,3082,3085,3087,3089,3092,3094,3097,3099,3102],{"class":80,"line":267},[78,3065,3044],{"class":176},[78,3067,286],{"class":172},[78,3069,1288],{"class":257},[78,3071,3072],{"class":176},"([",[78,3074,983],{"class":172},[78,3076,3077],{"class":270}," name",[78,3079,274],{"class":172},[78,3081,187],{"class":186},[78,3083,3084],{"class":88},"Cat",[78,3086,193],{"class":186},[78,3088,406],{"class":172},[78,3090,3091],{"class":270}," schema",[78,3093,274],{"class":172},[78,3095,3096],{"class":176}," CatSchema ",[78,3098,463],{"class":172},[78,3100,3101],{"class":176},"])",[78,3103,310],{"class":172},[78,3105,3106,3108],{"class":80,"line":280},[78,3107,455],{"class":176},[78,3109,310],{"class":172},[78,3111,3112,3114],{"class":80,"line":295},[78,3113,463],{"class":172},[78,3115,466],{"class":176},[78,3117,3118,3120,3122,3124],{"class":80,"line":313},[78,3119,472],{"class":168},[78,3121,476],{"class":475},[78,3123,479],{"class":84},[78,3125,482],{"class":172},[23,3127,3128,3129,3132],{},"Service 中使用 ",[27,3130,3131],{},"@InjectModel()"," 注入 Model。",[143,3134,3136],{"id":3135},"_3-prisma手动集成","3. Prisma（手动集成）",[23,3138,3139,3140,3143],{},"Prisma 是新一代 TypeScript ORM，需要手动安装 ",[27,3141,3142],{},"@prisma\u002Fclient"," 并生成客户端。",[69,3145,3147],{"className":159,"code":3146,"language":161,"meta":74,"style":74},"\u002F\u002F 1. 安装并初始化\nnpm install @prisma\u002Fclient\nnpx prisma init\n\n\u002F\u002F 2. 定义 schema（prisma\u002Fschema.prisma）\nmodel User {\n  id    Int    @id @default(autoincrement())\n  email String @unique\n  name  String\n}\n\n\u002F\u002F 3. 生成客户端\nnpx prisma generate\n",[27,3148,3149,3154,3170,3175,3179,3184,3191,3216,3228,3235,3239,3243,3248],{"__ignoreMap":74},[78,3150,3151],{"class":80,"line":81},[78,3152,3153],{"class":101},"\u002F\u002F 1. 安装并初始化\n",[78,3155,3156,3159,3161,3164,3167],{"class":80,"line":199},[78,3157,3158],{"class":176},"npm install ",[78,3160,254],{"class":172},[78,3162,3163],{"class":176},"prisma",[78,3165,3166],{"class":610},"\u002F",[78,3168,3169],{"class":176},"client\n",[78,3171,3172],{"class":80,"line":221},[78,3173,3174],{"class":176},"npx prisma init\n",[78,3176,3177],{"class":80,"line":244},[78,3178,248],{"emptyLinePlaceholder":247},[78,3180,3181],{"class":80,"line":251},[78,3182,3183],{"class":101},"\u002F\u002F 2. 定义 schema（prisma\u002Fschema.prisma）\n",[78,3185,3186,3189],{"class":80,"line":267},[78,3187,3188],{"class":176},"model User ",[78,3190,264],{"class":172},[78,3192,3193,3195,3198,3200,3202,3205,3208,3210,3213],{"class":80,"line":280},[78,3194,959],{"class":176},[78,3196,3197],{"class":176},"    Int",[78,3199,1477],{"class":172},[78,3201,1582],{"class":176},[78,3203,3204],{"class":172}," @",[78,3206,3207],{"class":257},"default",[78,3209,261],{"class":270},[78,3211,3212],{"class":257},"autoincrement",[78,3214,3215],{"class":270},"())\n",[78,3217,3218,3220,3223,3225],{"class":80,"line":295},[78,3219,1037],{"class":176},[78,3221,3222],{"class":176}," String",[78,3224,3204],{"class":172},[78,3226,3227],{"class":176},"unique\n",[78,3229,3230,3232],{"class":80,"line":313},[78,3231,1000],{"class":176},[78,3233,3234],{"class":176},"  String\n",[78,3236,3237],{"class":80,"line":330},[78,3238,1085],{"class":172},[78,3240,3241],{"class":80,"line":344},[78,3242,248],{"emptyLinePlaceholder":247},[78,3244,3245],{"class":80,"line":361},[78,3246,3247],{"class":101},"\u002F\u002F 3. 生成客户端\n",[78,3249,3250],{"class":80,"line":378},[78,3251,3252],{"class":176},"npx prisma generate\n",[23,3254,3255],{},"在 NestJS 中创建 Prisma 服务：",[69,3257,3259],{"className":159,"code":3258,"language":161,"meta":74,"style":74},"import { Injectable, OnModuleInit } from \"@nestjs\u002Fcommon\";\nimport { PrismaClient } from \"@prisma\u002Fclient\";\n\n@Injectable()\nexport class PrismaService extends PrismaClient implements OnModuleInit {\n  async onModuleInit() {\n    await this.$connect();\n  }\n}\n",[27,3260,3261,3286,3307,3311,3319,3340,3351,3366,3370],{"__ignoreMap":74},[78,3262,3263,3265,3267,3269,3271,3274,3276,3278,3280,3282,3284],{"class":80,"line":81},[78,3264,169],{"class":168},[78,3266,173],{"class":172},[78,3268,1367],{"class":176},[78,3270,406],{"class":172},[78,3272,3273],{"class":176}," OnModuleInit",[78,3275,180],{"class":172},[78,3277,183],{"class":168},[78,3279,187],{"class":186},[78,3281,190],{"class":88},[78,3283,193],{"class":186},[78,3285,196],{"class":172},[78,3287,3288,3290,3292,3295,3297,3299,3301,3303,3305],{"class":80,"line":199},[78,3289,169],{"class":168},[78,3291,173],{"class":172},[78,3293,3294],{"class":176}," PrismaClient",[78,3296,180],{"class":172},[78,3298,183],{"class":168},[78,3300,187],{"class":186},[78,3302,3142],{"class":88},[78,3304,193],{"class":186},[78,3306,196],{"class":172},[78,3308,3309],{"class":80,"line":221},[78,3310,248],{"emptyLinePlaceholder":247},[78,3312,3313,3315,3317],{"class":80,"line":244},[78,3314,254],{"class":172},[78,3316,1452],{"class":257},[78,3318,932],{"class":176},[78,3320,3321,3323,3325,3328,3331,3333,3336,3338],{"class":80,"line":251},[78,3322,472],{"class":168},[78,3324,476],{"class":475},[78,3326,3327],{"class":84}," PrismaService",[78,3329,3330],{"class":475}," extends",[78,3332,3294],{"class":84},[78,3334,3335],{"class":475}," implements",[78,3337,3273],{"class":84},[78,3339,943],{"class":172},[78,3341,3342,3344,3347,3349],{"class":80,"line":267},[78,3343,1649],{"class":475},[78,3345,3346],{"class":1520}," onModuleInit",[78,3348,1524],{"class":172},[78,3350,943],{"class":172},[78,3352,3353,3355,3357,3359,3362,3364],{"class":80,"line":280},[78,3354,1784],{"class":168},[78,3356,1550],{"class":1549},[78,3358,286],{"class":172},[78,3360,3361],{"class":257},"$connect",[78,3363,1524],{"class":270},[78,3365,196],{"class":172},[78,3367,3368],{"class":80,"line":295},[78,3369,1568],{"class":172},[78,3371,3372],{"class":80,"line":313},[78,3373,1085],{"class":172},[23,3375,3376,3377,3380,3381,47],{},"然后在其他服务中注入 ",[27,3378,3379],{},"PrismaService","，调用其生成的方法（如 ",[27,3382,3383],{},"prisma.user.findMany()",[58,3385,3386],{"id":3386},"总结",[1821,3388,3389,3399],{},[1824,3390,3391],{},[1827,3392,3393,3396],{},[1830,3394,3395],{},"功能",[1830,3397,3398],{},"TypeORM 方式",[1840,3400,3401,3413,3423,3433,3445,3455,3465],{},[1827,3402,3403,3406],{},[1845,3404,3405],{},"模块配置",[1845,3407,3408,119,3411],{},[27,3409,3410],{},"TypeOrmModule.forRoot",[27,3412,140],{},[1827,3414,3415,3418],{},[1845,3416,3417],{},"注册仓库",[1845,3419,3420],{},[27,3421,3422],{},"TypeOrmModule.forFeature",[1827,3424,3425,3428],{},[1845,3426,3427],{},"注入仓库",[1845,3429,3430],{},[27,3431,3432],{},"@InjectRepository(Entity)",[1827,3434,3435,3438],{},[1845,3436,3437],{},"实体定义",[1845,3439,3440,499,3442,3444],{},[27,3441,868],{},[27,3443,872],{}," 等",[1827,3446,3447,3449],{},[1845,3448,1832],{},[1845,3450,3451,499,3453,3444],{},[27,3452,1852],{},[27,3454,1856],{},[1827,3456,3457,3460],{},[1845,3458,3459],{},"事务",[1845,3461,3462,3464],{},[27,3463,2249],{}," 显式控制",[1827,3466,3467,3470],{},[1845,3468,3469],{},"异步配置",[1845,3471,3472,3474],{},[27,3473,558],{}," + 注入配置服务",[23,3476,3477],{},"选择 ORM 时，关系型数据库优先 TypeORM 或 Sequelize，MongoDB 使用 Mongoose，追求类型安全和简洁可考虑 Prisma。NestJS 的数据库集成非常灵活，可根据项目需求选择合适的技术栈。",[3479,3480,3481],"h2",{"id":3481},"参考文献",[23,3483,3484],{},"以下链接在编写时均可正常访问：",[1821,3486,3487,3497],{},[1824,3488,3489],{},[1827,3490,3491,3494],{},[1830,3492,3493],{},"资料",[1830,3495,3496],{},"说明",[1840,3498,3499,3511,3522],{},[1827,3500,3501,3508],{},[1845,3502,3503],{},[41,3504,3507],{"href":3505,"rel":3506},"https:\u002F\u002Fdocs.nestjs.com\u002F",[45],"NestJS 文档",[1845,3509,3510],{},"官方",[1827,3512,3513,3519],{},[1845,3514,3515],{},[41,3516,3518],{"href":43,"rel":3517},[45],"Database",[1845,3520,3521],{},"本章主题",[1827,3523,3524,3531],{},[1845,3525,3526],{},[41,3527,3530],{"href":3528,"rel":3529},"https:\u002F\u002Fdocs.nestjs.com\u002Ffaq\u002Frequest-lifecycle",[45],"Request lifecycle",[1845,3532,3533],{},"执行顺序",[3535,3536,3537],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sucvu, html code.shiki .sucvu{--shiki-light:#E53935;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":74,"searchDepth":199,"depth":199,"links":3539},[3540,3542,3544,3545,3546,3547,3548,3549,3550],{"id":60,"depth":221,"text":3541},"一、@nestjs\u002Ftypeorm 模块",{"id":132,"depth":221,"text":3543},"二、配置（TypeOrmModule.forRoot() 与 forRootAsync）",{"id":861,"depth":221,"text":862},{"id":1120,"depth":221,"text":1121},{"id":1815,"depth":221,"text":1816},{"id":2242,"depth":221,"text":2243},{"id":2678,"depth":221,"text":2679},{"id":3386,"depth":221,"text":3386},{"id":3481,"depth":199,"text":3481},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FNestJS\u002Fnew\u002Fdatabase","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FNestJS\u002Fnew\u002Fdatabase.md","md",{"items":3556},[3557,3561,3565,3569,3573,3577],{"path":3558,"title":3559,"description":3560,"category":10,"score":267},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fauth","认证与授权","认证（Authentication）：确认「你是谁」（如 JWT、Session）。 - 授权（Authorization）：确认「你能做什么」（如 RBAC、策略检查）。",{"path":3562,"title":3563,"description":3564,"category":10,"score":267},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fcache","缓存","@nestjs\u002Fcache-manager 统一缓存 API，存储实现可插拔。",{"path":3566,"title":3567,"description":3568,"category":10,"score":267},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fservice","提供者与服务","Service 是最常见的 Provider，封装业务逻辑。见 module。",{"path":3570,"title":3571,"description":3572,"category":10,"score":267},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fguards","守卫 (Guards) 与授权","守卫决定是否放行请求，常用于认证与授权。见 auth。",{"path":3574,"title":3575,"description":3576,"category":10,"score":267},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fconfig","配置管理（Config 模块）","@nestjs\u002Fconfig 加载 .env 并提供 ConfigService。见 工程化 env。",{"path":3578,"title":3579,"description":3580,"category":10,"score":267},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fcron","定时任务","@nestjs\u002Fschedule 基于 cron 表达式调度任务。",{"series":3582,"title":3583,"items":3584,"index":280,"prev":3645,"next":3646},"booklet\u002Fend\u002Fnestjs\u002Fnew","new",[3585,3587,3591,3593,3595,3599,3601,3605,3606,3610,3614,3616,3620,3624,3628,3632,3635,3639,3641],{"path":3558,"title":3559,"date":3586,"pinned":14},"2025-12-23",{"path":3588,"title":3589,"date":3590,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fbase","NestJS 基础","2021-03-09",{"path":3562,"title":3563,"date":3592,"pinned":14},"2025-07-04",{"path":3574,"title":3575,"date":3594,"pinned":14},"2023-08-26",{"path":3596,"title":3597,"date":3598,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fcontroller","控制器与路由","2020-07-18",{"path":3578,"title":3579,"date":3600,"pinned":14},"2023-04-12",{"path":3602,"title":3603,"date":3604,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fcustom-decorators","自定义装饰器","2021-09-19",{"path":7,"title":8,"date":13,"pinned":14},{"path":3607,"title":3608,"date":3609,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fdeploy","部署与运维","2023-01-24",{"path":3611,"title":3612,"date":3613,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Ferror","异常处理","2020-01-28",{"path":3570,"title":3571,"date":3615,"pinned":14},"2023-09-09",{"path":3617,"title":3618,"date":3619,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fintercept","拦截器 (Interceptors)","2021-04-26",{"path":3621,"title":3622,"date":3623,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Flogger","日志记录","2022-10-10",{"path":3625,"title":3626,"date":3627,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fmiddleware","中间件 (Middleware)","2021-11-26",{"path":3629,"title":3630,"date":3631,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fmodule","模块系统与依赖注入","2022-06-15",{"path":3633,"title":3634,"date":3598,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fpipes","管道 (Pipes) 与数据验证",{"path":3636,"title":3637,"date":3638,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fqueue","队列（Bull）","2021-07-01",{"path":3566,"title":3567,"date":3640,"pinned":14},"2024-12-02",{"path":3642,"title":3643,"date":3644,"pinned":14},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnestjs\u002Fnew\u002Fwebsocket","WebSocket（网关）","2022-12-14",{"path":3602,"title":3603,"date":3604,"pinned":14},{"path":3607,"title":3608,"date":3609,"pinned":14}]