-
Notifications
You must be signed in to change notification settings - Fork 7
typeorm_server
JunBae edited this page Nov 28, 2019
·
7 revisions
- https://github.com/connect-foundation/2019-11 에서 server코드를 확인
- find - select와 같음
- findOne - 결과 한개만
- findAndCount - [결과, 갯수]형식으로 출력한다.
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
@Entity()
export class 모델명 {
@PrimaryGeneratedColumn({ 옵션 })
컬럼이름: 타입;
@column({ 옵션 })
컬럼이름: 타입;
...
}
- 컬럼 선언
- @PrimaryGeneratedColumn()
- PrimaryKey로 선정하고 Auto Increment도 같이 적용한다.
- @column()
- 하나의 컬럼을 만든다
- @PrimaryGeneratedColumn()
- 컬럼타입(mysql기준)
- string - 기본 varchar(255)로 선언된다.
- 옵션으로 {type:text}를 선언하게되면 text로 생성된다.
- number - 기본 int(11)로 선언된다.
- boolean - 기본 tiny(4)로 선언된다.
- string - 기본 varchar(255)로 선언된다.
- 컬럼 옵션
- type
- nullable
- default
- 관계 설정
- 관계를 설정할때 이름을 설정할때 헷갈리지않게 신중히 작성해야 find가 잘 작동된다.
- @OneToMany(관계설정)
- 1대다 의 관계
- 외래키가 만들어지지않지만 상대와 연결여부를 알 수있다고 한다.
- @ManyToOne(관계설정)
- 다대1 의 관계
- 선언이 된 모델이 외래키를 가지게된다.
//유저가 여러개의 상품을 가진다고 할때 //users @OneToMany( type => Products, product => product.seller//이부분에 주목해야함. product를 기준으로 user를 어떻게 선언됐는지 정하는부분으로 find에서 relations에서 모델명을 이 이름으로 사용해야한다. ) products: Products[];//실제 데이터베이스에서는 products_id라고 만들어진다.(products가 id를 pk로 가질경우) //products @ManyToOne( type => Users, user => user.products//user기준으로 products를 products라고 선언하고 있다는 표현 ) seller: Users;//users가 seller라고 표현
- find 구조
- find(모델명,{find옵션});
import { Auction_logs } from "../models/Auction_logs"
...
this.em.find(Auction_logs,{find옵션});
- find 옵션들
- relations - 연관된 테이블을 join해서 보여준다.
find(models,{relations:["연결된모델명","또다른모델명",...]}) // 위에서 선언한 users, products를 이용한 예시 findAndCount(Products, {relations: ["seller"]}//users가 아닌 seller로 해야 연결이된다.
- join - relations와 같다.
find(models,{ join: { alias: "user", leftJoinAndSelect: { profile: "user.profile", photo: "user.photos", video: "user.videos" } })
- where
- mysql의 where과 같은 기능으로, 조건에 맞는 데이터를 찾는다.
- MoreThanOrEqual
-
=를 표현하는 함수이다.
-
find(models,{where:{컬럼이름:원하는값}} find(models,{where:{컬럼이름:MoreThanOrEqual(원하는값)}}
- order
find(models,{order:{컬럼이름:"정렬기준"} find(models,{order:{컬럼이름:"DESC"}
- skip, take
- 페이징(skip은 시작위치, take는 가져오는 갯수)
- ex) skip(0) take(10)은 1부터 10까지 가져온다.
find(models,{skip:1,take:2}
- cache
- 캐쉬여부
find(models,{cache:true}
- 단순히 mysql로 된 쿼리를 날릴때 사용
await this.em.query("select * from ~~~");
- controllers폴더를 참고
@JsonController("/log")// /log로 들어온다.
export class LogController {
constructor(private readonly logService: LogService) {}//service를 사용하도록 초기화하는부분
@Get()//메소드 지정
public find() {//해당 메소드가 처리하는 함수
return this.logService.find()//서비스 연결
}
@Get("/:id")//파라메터 지정
public findOne(@Param("id") id: string) {//Get의 파라메터를 꺼내는 방식
return this.logService.findOne(parseInt(id))
}
}
- 메소드
- @Get(), @Post(), @Put(), @Delete()과 같이 사용가능
- 파라메터 파싱
- Get
@Get("/:id") public findOne(@Param("id") id: string) {}//Param을 이용해 추출가능
- Post
@Post() public findOne(@BodyParam("userid") userid: number) {}//BodyParam을 이용해 추출가능
-
models
- 데이터베이스 테이블을 정의하는곳
- @PrimaryGeneratedColumn()
- 키를 정의
- generated라 선언하여 auto incresemenet도 같이 적용
- @Column
- 일반적인 컬럼을 선언
- @PrimaryGeneratedColumn()
- 속성
- string, number, date, boolean등을 사용가능
- 관계
- OneToOne, OneToMany, ManyToOne, ManyToMany를 선언가능
- 예시
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne} from 'typeorm'; import { Images } from './Images'; import { Users } from './Users2'; @Entity() export class Products { @PrimaryGeneratedColumn() id: number; @Column() title: string; @OneToMany(type => Images, images => images.id) images: Images[]; @ManyToOne(type => Users, users => users.id) user: Users; }
- 데이터베이스 테이블을 정의하는곳
-
repositories
-
entity manager와 repository
- entity manager를 통해 insert, update, create, delete(crud)가 가능
- repository는 entitymanager와 비슷하지만, concrete entity로 제한된다.
-
repository는 하나의 테이블에서 나오는 로직을 처리
import { EntityRepository, Repository, EntityManager } from 'typeorm'; import { Users } from '../models/Users'; /** Entity Manager - Constructor Injecction * 1. TypeOrm 역시 TypeDI의 Container를 사용한다.(server.ts 참조) * 2. 그래서 TypeOrm의 EntityManager는 TypeDI에 등록되있다. * 3. 그렇기 때문에, 아래서 @Inject 데코레이터 없이 생성자 주입이 가능하다. * 4. TODO: TypeDi와 Container 연결없이, 생성자 Injection이 되는지 확인해보자. */ @EntityRepository() export class UserRepository { constructor(private readonly em: EntityManager) {} public find() { return this.em.find(Users); } public findOne(id: number) { return this.em.findOne(Users, id); } //find 심화 //select * from auction_log where user_id=user_id, is_winning=true //위의 내용을 type orm으로 바꾸기 public findBuyLogs(user_id : number) { return this.em.find(Auction_logs,{ where:{ user: { id: user_id }, is_winning:true } }); public save(user: Users) { return this.em.save(user); } }
-
-
services
- 필요에 따라 여러 repository를 조합하여 처리 하기 위한 처리단계
import { Service } from 'typedi'; import { UserRepository } from '../repositories/UserRepository'; import { InjectRepository } from 'typeorm-typedi-extensions'; import { Users } from '../models/Users'; /** TODO: Transaction을 어떻게 처리해야 좋을까? */ @Service() export class UserService { constructor( @InjectRepository() private readonly userRepository: UserRepository ) {} /** GET */ public find() { return this.userRepository.find(); } public findOne(id: number) { return this.userRepository.findOne(id); } /** POST */ public create(user: Users) { return this.userRepository.save(user); } /** PUT, PATCH */ public update(id: number, user: Users) { /**TODO: 해당 id값으로 Entitiy를 조회해서, 새로운 user 엔티티로 변경 */ } /** DELETE */ public delete(id: number) { /**TODO: 해당 id값으로 Enitity 삭제 */ } }
-
controllers
-
service에서 함수를 사용한다.
-
api폴더에 파일을 생성한다.
-
예시
import { JsonController, Get, Param, Post, Body, Patch, Put, Delete, OnUndefined } from 'routing-controllers'; //service와 모델을 import한다. import { UserService } from '../../services/UserService'; import { Users } from '../../models/Users'; /** TypeDi Constructor Injection 작동 방식 * 1. TypeDi의 Container를 routing-controllers가 사용한다.(server.ts 소스 코드 참조) * 2. TypeDi가 Controller로 등록된 클래스들을 알고 있다. * 3. TypeDi는 @Inject를 통해서 dependency를 주입하는데, 생성자 주입(Constructor Injection)의 경우 @Inject를 생략해도 된다. */ //컨트롤러 설정 부분 //아래의 의미는 localhost:3000/api/users 로 시작한다는 의미이다.//자신이 만든 api이름을 넣으면 된다. @JsonController('/users') export class UserController { constructor(private readonly userService: UserService) {} @Get() public find() { return this.userService.find(); } //get으로 받는 부분 //get의 api의 마지막은 param이 아닌경우 에러가 난다. //ex) Get('/feafea/:num')(o) / Get('/feafea')(x) //Get내부에서 조건문을 사용하는 방식을 고려해보자. @Get('/:id') public findOne(@Param('id') id: string) { return this.userService.findOne(parseInt(id)); } @Post() public create(@Body() user: Users) { //TODO: user을 Users Model에 맞게 class-transformer를 사용해서 처리하자 return this.userService.create(user); } //post으로 받는 부분 //post body로 값을 넘기는 경우 BodyParam 을 이용하자 // @BodyParam("name") userName: number //위의 의미는 body의 name부분을 받아서 userName에 넣는다는 의미이다. 헷갈리지 않도록 하자. @Post('/tests') public aaabbbb(@BodyParam("name") userName: number) { if(userName>10){//이런식으로 내부에 조건문을 활용할수 있다.//쓸지는 모르지만 참고//좋은 방식인지는 모르겠다. return [1,1,1]; } return this.logService.findBuyLogs(userName); } @Put('/:id') @Patch('/:id') public update(@Param('id') id: string, @Body() user: Users) { //TODO: user을 Users Model에 맞게 class-transformer를 사용해서 처리하자 return this.userService.update(parseInt(id), user); } @Delete('/:id') public delete(@Param('id') id: string) { return this.userService.delete(parseInt(id)); } }
-
-
typeorm관련 https://typeorm.io
-
find-option https://github.com/typeorm/typeorm/blob/master/docs/find-options.md
-
typeorm 라우팅 https://github.com/typestack/routing-controllers
-
many-to-one 관계에서의 find를 하는법 https://github.com/typeorm/typeorm/issues/2552
부스트캠프 맴버십 - 그룹프로젝트 (서준배, 최성찬, 홍승표, 황선준)