<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>EastAshDev</title>
    <link>https://eastash.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 12 Apr 2026 17:36:10 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>EastAshLee</managingEditor>
    <item>
      <title>TypeORM</title>
      <link>https://eastash.tistory.com/3</link>
      <description>&lt;h3 data-ke-size=&quot;size26&quot;&gt;제목1&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size23&quot;&gt;제목2&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;제목3&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;본문1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본문2&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;본문3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;인용1&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;인용2&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;인용3&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인용4&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리스트1
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;3
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;4
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;리스트2
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;3
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;리스트3
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;3
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;4&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평문&lt;/p&gt;
&lt;pre id=&quot;code_1664616479287&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;코드블럭&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식문서 &lt;a href=&quot;http://typeorm.io&quot;&gt;typeorm.io&lt;/a&gt; 를 통해 글을 작성하였다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 시작하기&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CLI를 이용하여 새로운 프로젝트를 생성하려면 다음 명령어를 실행시킨다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 존재하는 Node 프로젝트에서도 사용할 수 있지만, 어떤 파일들을 덮어쓰기 할 수 있으니 조심해야 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;You can generate an ESM project by running&amp;nbsp;&lt;br /&gt;npx typeorm init --name MyProject --database postgres --module esm&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;You can generate an even more advanced project with express installed by running&lt;br /&gt;npx typeorm init --name MyProject --database mysql --express&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;You can generate a docker-compose file by running&amp;nbsp;&lt;br /&gt;npx typeorm init --name MyProject --database postgres --docker&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;brainfuck&quot;&gt;&lt;code&gt;npx typeorm init --name MyProject --database postgres &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용할 데이터 베이스 이름을 넣어준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용 가능한 데이터베이스들&lt;br /&gt;&amp;nbsp;&lt;code&gt;mysql&lt;/code&gt;,&amp;nbsp;&lt;code&gt;mariadb&lt;/code&gt;,&amp;nbsp;&lt;code&gt;postgres&lt;/code&gt;,&amp;nbsp;&lt;code&gt;cockroachdb&lt;/code&gt;,&amp;nbsp;&lt;code&gt;sqlite&lt;/code&gt;,&amp;nbsp;&lt;code&gt;mssql&lt;/code&gt;,&amp;nbsp;&lt;code&gt;sap&lt;/code&gt;,&amp;nbsp;&lt;code&gt;spanner&lt;/code&gt;,&amp;nbsp;&lt;code&gt;oracle&lt;/code&gt;,&amp;nbsp;&lt;code&gt;mongodb&lt;/code&gt;,&amp;nbsp;&lt;code&gt;cordova&lt;/code&gt;,&amp;nbsp;&lt;code&gt;react-native&lt;/code&gt;,&amp;nbsp;&lt;code&gt;expo&lt;/code&gt;,&amp;nbsp;&lt;code&gt;nativescript&lt;/code&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성 시 다음과 같은 디렉터리 구조를 가진 프로젝트가 생성된다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;MyProject ├── src                   // 타입스크립트 코드들이 존재하는 폴더 │   ├── entity            // entity들이 존재하는 폴더 │   │   └── User.ts       // sample entity │   ├── migration         // migration들이 존재하는 폴더 │   ├── data-source.ts    // data source 와 connection 설정 파일 │   └── index.ts          // applicatoin의 start point ├── .gitignore            // gitignore 파일 ├── package.json          // node module dependencies └── tsconfig.json         // TypeScript compiler options &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm i를 통해 의존 라이브러리들을 설치한다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;cd MyProject npm install &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;data-source.ts 파일을 수정하여 database connection 설정을 한다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;exportconst AppDataSource =new DataSource({ type: &quot;postgres&quot;,     host: &quot;localhost&quot;,     port: 5432,     username: &quot;test&quot;,     password: &quot;test&quot;,     database: &quot;test&quot;,     synchronize:true,     logging:true,     entities: [Post, Category],     subscribers: [],     migrations: [], }) &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 중요한 옵션은 &lt;code&gt;host&lt;/code&gt;,&amp;nbsp;&lt;code&gt;username&lt;/code&gt;,&amp;nbsp;&lt;code&gt;password&lt;/code&gt;,&amp;nbsp;&lt;code&gt;database&lt;/code&gt;,&amp;nbsp;&lt;code&gt;port&lt;/code&gt;&amp;nbsp;등이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정을 마쳤다면, 다음 명령어를 통해 어플리케이션을 실행한다.&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;npm start &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 프로젝트는 성공적으로 실행될 것이고, 새로운 user을 당신의 데이터 베이스에 넣을 것이다. 그리고 계속 프로젝트를 이어나가기 위해서는, 엔티티들을 더 생성하는것을 시작해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Table - Model 매핑하기&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;Model 생성하기&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypeORM을 이용하여 데이터베이스를 이용하기 위해서는 &lt;code&gt;model&lt;/code&gt;을 통해 &lt;code&gt;database table&lt;/code&gt;을 만들어야 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 Photo 모델이 있다고 하자&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;export class Photo {     id: number     name: string     description: string     filename: string     views: number     isPublished: boolean } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 Photo를 database에 저장하고 싶다면, &lt;code&gt;database table&lt;/code&gt; 이 필요할 것이다. &lt;code&gt;database table&lt;/code&gt;은 &lt;code&gt;model&lt;/code&gt;로부터 생성할 수 있는데, 이러한 모델을 &lt;code&gt;Entity&lt;/code&gt;라고 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;Entity 생성하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Entity&lt;/code&gt; 는 &lt;code&gt;@Entity&lt;/code&gt; 로 데코레이팅 된 모델이다. 데이터베이스 테이블들은 &lt;code&gt;Entity&lt;/code&gt;를 통해 만들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;Entity&lt;/code&gt;를 통해 &lt;code&gt;CRUD operation&lt;/code&gt; 작업을 할 수 있다&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;import { Entity } from &quot;typeorm&quot;  @Entity() export class Photo {     id: number     name: string     description: string     filename: string     views: number     isPublished: boolean } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;code&gt;database table&lt;/code&gt;은 Photo &lt;code&gt;Entity&lt;/code&gt;를 통해 생성될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 column이 없는 database table은 없으므로 이번에는 column을 만들어보자&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;Table Column 추가하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;column&lt;/code&gt;을 추가하기 위해서는, &lt;code&gt;entity&lt;/code&gt;의 속성을 &lt;code&gt;@Column&lt;/code&gt; 으로 데코레이팅 해주면 된다.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;import { Entity, Column } from &quot;typeorm&quot;  @Entity() export class Photo {     @Column()     id: number      @Column()     name: string      @Column()     description: string      @Column()     filename: string      @Column()     views: number      @Column()     isPublished: boolean } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;code&gt;Entity&lt;/code&gt;의 속성들이 photo 테이블의 &lt;code&gt;coluimn&lt;/code&gt;로 추가되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;컬럼의 타입&lt;/code&gt;은 Entity 각각의 &lt;code&gt;속성의 타입&lt;/code&gt;으로 정해진다.&lt;br /&gt;ex ) number &amp;rarr; integer, string &amp;rarr; varchar, boolean &amp;rarr; bool&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;@Column&lt;/code&gt; 데코레이터에 직접 명시해줌으로써 &lt;code&gt;컬럼의 타입&lt;/code&gt;을 정할 수도 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size23&quot;&gt;✔️&amp;nbsp;Primary Column 생성하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 &lt;code&gt;Entity&lt;/code&gt;에는 최소한 하나의 &lt;code&gt;Primary Key&lt;/code&gt;가 존재햐아 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;@PrimaryColumn&lt;/code&gt; 데코레이터로 &lt;code&gt;primary key&lt;/code&gt; column을 만들 수 있다.&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;import { Entity, Column, PrimaryColumn } from &quot;typeorm&quot;  @Entity() export class Photo {     @PrimaryColumn()     id: number     ... } &lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size23&quot;&gt;✔️&amp;nbsp;Auto-generated column 생성하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;auto-generated&lt;/code&gt; 컬럼 (auto-increment / sequence / serial / generated identity column) 을 생성하고 싶다면, &lt;code&gt;@PrimaryColumn&lt;/code&gt; 데코레이터를 사용한다.&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;import { Entity, Column, PrimaryColumn } from &quot;typeorm&quot;  @Entity() export class Photo {     @PrimaryGeneratedColumn()     id: number     ... } &lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size23&quot;&gt;✔️&amp;nbsp;Column의 데이터 타입 명시하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;@Column&lt;/code&gt; 데코레이터의 인자를 통해 &lt;code&gt;데이터 타입&lt;/code&gt;을 명시할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;import { Entity, Column, PrimaryGeneratedColumn } from &quot;typeorm&quot;  @Entity() export class Photo {     @PrimaryGeneratedColumn()     id: number      @Column({         length: 100,     })     name: string      @Column(&quot;text&quot;)     description: string      @Column()     filename: string      @Column(&quot;double&quot;)     views: number      @Column()     isPublished: boolean } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Default로, string &amp;rarr; varchar(255), number &amp;rarr; integer-like 타입으로 변환이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Column의 타입은 데이터베이스 명세에 따르는데, 더 많은 정보는 &lt;a href=&quot;https://typeorm.io/entities#column-types&quot;&gt;이곳&lt;/a&gt;을 참고한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. DataSource 생성하기&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Database에 관련된 설정들은 DataSource을 통해 할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import &quot;reflect-metadata&quot; import { DataSource } from &quot;typeorm&quot; import { Photo } from &quot;./entity/Photo&quot;  const AppDataSource = new DataSource({     type: &quot;postgres&quot;,     host: &quot;localhost&quot;,     port: 5432,     username: &quot;root&quot;,     password: &quot;admin&quot;,     database: &quot;test&quot;,     entities: [Photo],     synchronize: true,     logging: false, })  // to initialize initial connection with the database, register all entities // and &quot;synchronize&quot; database schema, call &quot;initialize()&quot; method of a newly created database // once in your application bootstrap AppDataSource.initialize()     .then(() =&amp;gt; {         // here you can start to work with your database     })     .catch((error) =&amp;gt; console.log(error)) &lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의! synchronize 옵션을 걸어놓으면, application이 실행할 때 마다 entity을 통해 동기화된다! (테이블이 덮어씌워진다)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AppDataSource.initialize().then()에 callback으로 database를 이용하는 코드들을 작성한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size23&quot;&gt;✔️&amp;nbsp;Express의 App.ts 경우&lt;/h4&gt;
&lt;pre class=&quot;livescript&quot;&gt;&lt;code&gt;import { AppDataSource } from &quot;./data-source&quot;  AppDataSource.initialize().then(async () =&amp;gt; {     ...     const app = express()     app.listen(3000)     ... }).catch(error =&amp;gt; console.log(error)) &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application 시작에 AppDataSource.initialize()를 통해 데이터베이스와 연결한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. &lt;code&gt;EntityManager&lt;/code&gt; VS &lt;code&gt;Repository&lt;/code&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 photo를 데이터베이스에 Insert하기&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import { Photo } from &quot;./entity/Photo&quot; import { AppDataSource } from &quot;./index&quot;  const photo = new Photo() photo.name = &quot;Me and Bears&quot; photo.description = &quot;I am near polar bears&quot; photo.filename = &quot;photo-with-bears.jpg&quot; photo.views = 1 photo.isPublished = true  await AppDataSource.manager.save(photo) console.log(&quot;Photo has been saved. Photo id is&quot;, photo.id) &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;entity를 save()하고 나면 id 값을 생성하여 entity 객체를 수정하고 데이터베이스에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;save()가 반환하는 객체는 인자로 넘겨준 entity와 같은 객체이다. (id만 수정됨)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;&lt;code&gt;EntityManager&lt;/code&gt; 을 이용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예제에서는 &lt;code&gt;EntityManager&lt;/code&gt;을 이용하여 Entity를 다루었었다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import { Photo } from &quot;./entity/Photo&quot; import { AppDataSource } from &quot;./index&quot;  const savedPhotos = await AppDataSource.manager.find(Photo) console.log(&quot;All photos from the db: &quot;, savedPhotos) &lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;EntityManager&lt;/code&gt; 을 이용하면, 아무 Entity나 CRUD 작업을 할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EntityManager&lt;/code&gt;는 모든 entity의 repository 들의 집합처럼 여기면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;&lt;code&gt;Repository&lt;/code&gt; 를 이용하기&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Entity를 다루는 일이 많을 경우, &lt;code&gt;Repository&lt;/code&gt;가 &lt;code&gt;EnityManager&lt;/code&gt;보다 유리하다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;EntityManager&lt;/code&gt; 대신 &lt;code&gt;Repository&lt;/code&gt;를 사용해보자.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;import { User } from &quot;./entity/User&quot;  const userRepository = dataSource.getRepository(User) const user = await userRepository.findOneBy({     id: 1, }) user.name = &quot;Umed&quot; await userRepository.save(user) &lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;Repository&lt;/code&gt; 는 Entity와 1대1로 대응되도록 만들어지고, Entity를 다루는 모든 operation을 &lt;code&gt;Repository&lt;/code&gt;에서 한다.&lt;/li&gt;
&lt;li&gt;Repositry는 operation이 특정 entity에만 제한된 EntityManager와 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. Reopitory를 통해 CRUD 작업하기&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;1. 조회하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;find&lt;/code&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;findOneBy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;findBy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;findAndCount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Ex Code&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-tsx&quot;&gt;import { Photo } from &quot;./entity/Photo&quot; import { AppDataSource } from &quot;./index&quot;  const photoRepository = AppDataSource.getRepository(Photo) const allPhotos = await photoRepository.find() console.log(&quot;All photos from the db: &quot;, allPhotos)  const firstPhoto = await photoRepository.findOneBy({     id: 1, }) console.log(&quot;First photo from the db: &quot;, firstPhoto)  const meAndBearsPhoto = await photoRepository.findOneBy({     name: &quot;Me and Bears&quot;, }) console.log(&quot;Me and Bears photo from the db: &quot;, meAndBearsPhoto)  const allViewedPhotos = await photoRepository.findBy({ views: 1 }) console.log(&quot;All viewed photos: &quot;, allViewedPhotos)  const allPublishedPhotos = await photoRepository.findBy({ isPublished: true }) console.log(&quot;All published photos: &quot;, allPublishedPhotos)  const [photos, photosCount] = await photoRepository.findAndCount() console.log(&quot;All photos: &quot;, photos) console.log(&quot;Photos count: &quot;, photosCount) &lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;2. 수정하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;code&gt;조회하기 + 엔티티 수정하기 + 저장하기&lt;/code&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import { Photo } from &quot;./entity/Photo&quot; import { AppDataSource } from &quot;./index&quot;  const photoRepository = AppDataSource.getRepository(Photo) const photoToUpdate = await photoRepository.findOneBy({     id: 1, }) photoToUpdate.name = &quot;Me, my friends and polar bears&quot; await photoRepository.save(photoToUpdate) &lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;3. 삭제하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;remove&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import { Photo } from &quot;./entity/Photo&quot; import { AppDataSource } from &quot;./index&quot;  const photoRepository = AppDataSource.getRepository(Photo) const photoToRemove = await photoRepository.findOneBy({     id: 1, }) await photoRepository.remove(photoToRemove) &lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;4. 추가하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;save&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;const photo = new Photo() photo.name = &quot;Me and Bears&quot; photo.description = &quot;I am near polar bears&quot; photo.filename = &quot;photo-with-bears.jpg&quot; photo.views = 1 photo.isPublished = true  const photoRepository = AppDataSource.getRepository(Photo)  await photoRepository.save(photo) &lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 연관/관계 테이블 다루기&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;1대1 관계 생성하기&lt;/h3&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import {     Entity,     Column,     PrimaryGeneratedColumn,     OneToOne,     JoinColumn, } from &quot;typeorm&quot; import { Photo } from &quot;./Photo&quot;  @Entity() export class PhotoMetadata {         ...      @OneToOne(() =&amp;gt; Photo)     @JoinColumn()     photo: Photo } &lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 &lt;code&gt;Entity&lt;/code&gt;와 &lt;code&gt;1대1 관계&lt;/code&gt;를 설정하기 위해서는 &lt;code&gt;@OneToOne&lt;/code&gt; 데코레이터를 사용해야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;@OneToOne&lt;/code&gt; 데코레이터의 인자로 &lt;code&gt;() &amp;rArr; Photo&lt;/code&gt; 를 줌으로써 관계를 맺을 Entity의 클래스를 설정한다.&lt;/li&gt;
&lt;li&gt;( 가독성 향상을 위해 &lt;code&gt;(type) &amp;rArr; Photo&lt;/code&gt; 로 명시할 수도 있다. )&lt;/li&gt;
&lt;li&gt;언어의 스펙으로 인해 Class 자체를 인자로 보내지 않고 Arrow Function을 인자로 보낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;관계를 소유하는 Entity를 설정하기 위해 &lt;code&gt;@JoinColumn&lt;/code&gt; 데코레이터를 사용한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;관계는 양방향 또는 단방향이 될 수 있다.&lt;/li&gt;
&lt;li&gt;한쪽만 관계를 소유할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계를 소유하는 쪽은 1 : n 일 때 n 쪽이 되어야 한다. (Foreign Key를 가진 쪽)&lt;br /&gt;1이 되어버리면 하나의 레코드가 여러개의 상대 레코드와 조인이 된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;1대1 관계 저장하기&lt;/h3&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;import { Photo } from &quot;./entity/Photo&quot; import { PhotoMetadata } from &quot;./entity/PhotoMetadata&quot;  // create a photo const photo = new Photo() photo.name = &quot;Me and Bears&quot; photo.description = &quot;I am near polar bears&quot; photo.filename = &quot;photo-with-bears.jpg&quot; photo.views = 1 photo.isPublished = true  // create a photo metadata const metadata = new PhotoMetadata() metadata.height = 640 metadata.width = 480 metadata.compressed = true metadata.comment = &quot;cybershoot&quot; metadata.orientation = &quot;portrait&quot; metadata.photo = photo // this way we connect them  // get entity repositories const photoRepository = AppDataSource.getRepository(Photo) const metadataRepository = AppDataSource.getRepository(PhotoMetadata)  // first we should save a photo await photoRepository.save(photo)  // photo is saved. Now we need to save a photo metadata await metadataRepository.save(metadata)  // done console.log(     &quot;Metadata is saved, and the relation between metadata and photo is created in the database too&quot;, ) &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계를 소유한 쪽이 나중에 저장이 되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;관계를 소유한 쪽 = RK를 가지고 있는 쪽&lt;/code&gt; 이므로 RK가 가르키는 대상이 먼저 저장이 되는게 당연히 올바른 순서이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;관계를 역전하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계는 양방향, 단방향이 될 수 있다. 위에서는 단방향으로 설정했는데, 관계를 소유한 PhotoMetaData는 Photo에 대한 정보를 알 수 있지만, Photo는 PhotoMetaData에 대해 알지 못한다. 이렇게 되면 Photo에서 PhotoMetaData에 접근하기 어려워지는데, 관계를 역전하여 양방향으로 만들어 이 문제를 해결할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import {     Entity,     Column,     PrimaryGeneratedColumn,     OneToOne,     JoinColumn, } from &quot;typeorm&quot; import { Photo } from &quot;./Photo&quot;  @Entity() export class PhotoMetadata {     /* ... other columns */      @OneToOne(() =&amp;gt; Photo, (photo) =&amp;gt; photo.metadata)     @JoinColumn()     photo: Photo } &lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import { Entity, Column, PrimaryGeneratedColumn, OneToOne } from &quot;typeorm&quot; import { PhotoMetadata } from &quot;./PhotoMetadata&quot;  @Entity() export class Photo {     /* ... other columns */      @OneToOne(() =&amp;gt; PhotoMetadata, (photoMetadata) =&amp;gt; photoMetadata.photo)     metadata: PhotoMetadata } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대편 관계에 대해 명시하기 위해 @OneToOne 데코레이터에 두번째 인자로 &lt;code&gt;photo =&amp;gt; photo.metadata&lt;/code&gt; 화살표 함수를 넣어주었다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;@JoinColumn&lt;/code&gt; 데코레이터는 관계를 소유하는 한 쪽에만 달아주는 것을 명심하자!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;⚠️ ES Module을 사용하는 경우&lt;/h3&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;... @OneToOne(() =&amp;gt; Photo, (photo) =&amp;gt; photo.metadata) @JoinColumn() photo: Relation  ... @OneToOne(() =&amp;gt; PhotoMetadata, (photoMetadata) =&amp;gt; photoMetadata.photo) metadata: Relation &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;속성의 타입을 &lt;code&gt;Relation&lt;/code&gt;으로 감싸 &lt;code&gt;circular dependency&lt;/code&gt; 문제를 해결한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;연관된 테이블들을 같이 조회하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연관된 테이블을 같이 조회하는 방법은 두가지가 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;find&lt;/code&gt; 메서드 이용하기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;QueryBuilder&lt;/code&gt; 이용하기&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size23&quot;&gt;✔️&amp;nbsp;&lt;code&gt;find&lt;/code&gt; 메서드를 이용하는 방법&lt;/h4&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import { Photo } from &quot;./entity/Photo&quot; import { PhotoMetadata } from &quot;./entity/PhotoMetadata&quot; import { AppDataSource } from &quot;./index&quot;  const photoRepository = AppDataSource.getRepository(Photo) const photos = await photoRepository.find({     relations: {         metadata: true,     }, }) &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;find&lt;/code&gt; 옵션을 이용하여 연관된 테이블을 같이 조회할 수 있다.&lt;br /&gt;더 많은 find 옵션은 &lt;a href=&quot;https://typeorm.io/find-options&quot;&gt;여기&lt;/a&gt;를 참조.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size23&quot;&gt;✔️&amp;nbsp;&lt;code&gt;QueryBuilder&lt;/code&gt; 을 이용하는 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;find option&lt;/code&gt;을 이용하는 방법은 심플해서 유용하지만, 복잡한 쿼리를 사용하려 한다면 &lt;code&gt;QueryBuilder&lt;/code&gt;가 유리하다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import { Photo } from &quot;./entity/Photo&quot; import { PhotoMetadata } from &quot;./entity/PhotoMetadata&quot; import { AppDataSource } from &quot;./index&quot;  const photos = await AppDataSource.getRepository(Photo)     .createQueryBuilder(&quot;photo&quot;)     .innerJoinAndSelect(&quot;photo.metadata&quot;, &quot;metadata&quot;)     .getMany() &lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;QueryBuilder&lt;/code&gt; 을 사용해야 할 때는 SQL query를 직접 작성할 필요가 있을 때다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;Casecade를 이용하여 관계된 Object를 자동으로 저장하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;@OneToOne&lt;/code&gt; 데코레이터에서 &lt;code&gt;cascase&lt;/code&gt; 옵션을 설정해 줌으로써 cascade를 설정할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;export class Photo {     /// ... other columns      @OneToOne(() =&amp;gt; PhotoMetadata, (metadata) =&amp;gt; metadata.photo, {         cascade: true,     })     metadata: PhotoMetadata } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;cascade&lt;/code&gt;를 허용하면 photo를 PhotoMetaData와 따로 저장할 수 없게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;photo Entitiy Object에 metadata를 속성으로 할당하고, &lt;code&gt;save()&lt;/code&gt;를 호출하면 cascade 옵션으로 인해 metadata도 자동으로 같이 저장된다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;import { AppDataSource } from &quot;./index&quot;  // create photo object const photo = new Photo() photo.name = &quot;Me and Bears&quot; photo.description = &quot;I am near polar bears&quot; photo.filename = &quot;photo-with-bears.jpg&quot; photo.isPublished = true  // create photo metadata object const metadata = new PhotoMetadata() metadata.height = 640 metadata.width = 480 metadata.compressed = true metadata.comment = &quot;cybershoot&quot; metadata.orientation = &quot;portrait&quot;  photo.metadata = metadata // this way we connect them  // get repository const photoRepository = AppDataSource.getRepository(Photo)  // saving a photo also save the metadata await photoRepository.save(photo)  console.log(&quot;Photo is saved, photo metadata is saved too.&quot;) &lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cascade는 photo에만 걸었기 때문에 metadata 측에서 저장할 때는 cascade가 동작하지 않는다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;1대다, 다대1 관계 생성하기&lt;/h3&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import {Entity,Column,PrimaryGeneratedColumn,OneToMany,JoinColumn} from &quot;typeorm&quot; import { Photo } from &quot;./Photo&quot;  @Entity() export class Author {     @PrimaryGeneratedColumn()     id: number      @Column()     name: string      @OneToMany(() =&amp;gt; Photo, (photo) =&amp;gt; photo.author) // note: we will create author property in the Photo class below     photos: Photo[] } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auther 측에서 photo와 &lt;code&gt;1대다&lt;/code&gt; 관계이므로 &lt;code&gt;@OneToMany&lt;/code&gt; 데코레이터를 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;OneToMany&lt;/code&gt;는 반대편의 &lt;code&gt;ManyToOne&lt;/code&gt; 없이 존재할 수 없다.&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from &quot;typeorm&quot; import { PhotoMetadata } from &quot;./PhotoMetadata&quot; import { Author } from &quot;./Author&quot;  @Entity() export class Photo {     /* ... other columns */      @ManyToOne(() =&amp;gt; Author, (author) =&amp;gt; author.photos)     author: Author } &lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1대다, 다대1 관계에서는 항상 다대1 관계를 가지는 측이 주인이다.&lt;br /&gt;다 쪽이 RK를 가지고 있고, 다쪽이 봤을 때 1은 항상 하나의 레코드이므로.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size26&quot;&gt;✔️&amp;nbsp;다대다 관계 형성하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다대다 관계를 형성하는 Photo와 Album Entity를 보자.&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import {     Entity,     PrimaryGeneratedColumn,     Column,     ManyToMany,     JoinTable, } from &quot;typeorm&quot;  @Entity() export class Album {     @PrimaryGeneratedColumn()     id: number      @Column()     name: string      @ManyToMany(() =&amp;gt; Photo, (photo) =&amp;gt; photo.albums)     @JoinTable()     photos: Photo[] } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1대1 관계와 마찬가지로 @JoinTable 데코레이터를 이용해 소유하는 측을 설정하자.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;export class Photo {     /// ... other columns      @ManyToMany(() =&amp;gt; Album, (album) =&amp;gt; album.photos)     albums: Album[] } &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application을 실행하면 ORM은 두 테이블의 피벗 테이블을 생성한다.&lt;/p&gt;
&lt;pre class=&quot;gherkin&quot;&gt;&lt;code&gt;+-------------+--------------+----------------------------+ |                album_photos_photo_albums                | +-------------+--------------+----------------------------+ | album_id    | int(11)      | PRIMARY KEY FOREIGN KEY    | | photo_id    | int(11)      | PRIMARY KEY FOREIGN KEY    | +-------------+--------------+----------------------------+ &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스에 album과 photo를 저장해보자&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import { AppDataSource } from &quot;./index&quot;  // create a few albums const album1 = new Album() album1.name = &quot;Bears&quot; await AppDataSource.manager.save(album1)  const album2 = new Album() album2.name = &quot;Me&quot; await AppDataSource.manager.save(album2)  // create a few photos const photo = new Photo() photo.name = &quot;Me and Bears&quot; photo.description = &quot;I am near polar bears&quot; photo.filename = &quot;photo-with-bears.jpg&quot; photo.views = 1 photo.isPublished = true photo.albums = [album1, album2] await AppDataSource.manager.save(photo)  // now our photo is saved and albums are attached to it // now lets load them: const loadedPhoto = await AppDataSource.getRepository(Photo).findOne({     where: {         id: 1,     },     relations: {         albums: true,     }, }) &lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. QueryBuilder 사용하기&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡한 SQL을 만들려고 할 때, &lt;code&gt;QueryBuilder&lt;/code&gt;을 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;const photos = await AppDataSource.getRepository(Photo)     .createQueryBuilder(&quot;photo&quot;) // first argument is an alias. Alias is what you are selecting - photos. You must specify it.     .innerJoinAndSelect(&quot;photo.metadata&quot;, &quot;metadata&quot;)     .leftJoinAndSelect(&quot;photo.albums&quot;, &quot;album&quot;)     .where(&quot;photo.isPublished = true&quot;)     .andWhere(&quot;(photo.name = :photoName OR photo.name = :bearName)&quot;)     .orderBy(&quot;photo.id&quot;, &quot;DESC&quot;)     .skip(5)     .take(10)     .setParameters({ photoName: &quot;My&quot;, bearName: &quot;Mishka&quot; })     .getMany() &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 자세한 내용은 &lt;a href=&quot;https://typeorm.io/select-query-builder&quot;&gt;이곳&lt;/a&gt; 참조.&lt;/p&gt;</description>
      <author>EastAshLee</author>
      <guid isPermaLink="true">https://eastash.tistory.com/3</guid>
      <comments>https://eastash.tistory.com/3#entry3comment</comments>
      <pubDate>Thu, 29 Sep 2022 17:30:39 +0900</pubDate>
    </item>
  </channel>
</rss>