建立Entity Class並設定@ManyToMany
新增DTO、Service及修改app controller
新增@ManyToMany() inverse屬性於另一端Entity class,並以@JoinTable()建立Join Table
修改UserDTO
在UsersService裡修改新增程式碼
在UsersSerive裡修改讀取程式碼,載入關聯屬性
使用Postman測試
建立Role Entity
@Entity()
export class Role {
@PrimaryGeneratedColumn()
id: number;
@Column({
length: 50,
roleName: string;
@ManyToMany(type => User, user => user.roles) //設定bi-directional關聯
users: User[];
新增RoleDTO
import { IsString, MaxLength } from "class-validator";
export class RoleDTO {
@IsString()
@MaxLength(100)
roleName: string;
新增RoleService,記得註冊到Module
@Injectable()
export class RolesService {
constructor(
@InjectRepository(Role) // 注入 typeorm repository
private readonly roleRepo: Repository<Role>,
async addRole(roleDto: RoleDTO){
const role = new Role();
role.roleName = roleDto.roleName;
return await this.roleRepo.save(role);
async getRoleById(id){
return await this.roleRepo.findOne(id);
async getRolesByIds(ids){ //用在新增使用者時候要回傳Role[]
return await this.roleRepo.findByIds(ids);
async getRoles(){
return await this.roleRepo.find({relations:['users']}); //載入關聯屬性
修改appcontroller
@Get('role/list')
getRoles(){
return this.roleService.getRoles();
@Get('role/:roleId')
getRoleById(@Param('roleId') id){
return this.roleService.getRoleById(id);
@Post('role')
@UsePipes(new ValidationPipe({transform:true}))
addRole(@Body() roleDTO: RoleDTO){
return this.roleService.addRole(roleDTO);
修改user.entitie.ts,新增多對多關聯屬性
@ManyToOne(type => Department, dep => dep.users)
dep: Department;
@RelationId((user: User) => user.dep)
depId: number;
@ManyToMany(type => Role, role => role.users) //建立bi-directional多對多
@JoinTable() // 告訴typeorm要建立join table
roles: Role[];
修改userDTO,加入roleIds屬性
@IsNumber()
depId: number;
@IsNumber({
allowNaN: false,
allowInfinity:false,
},{each:true //檢查陣列每一個元素是否都是數字})
roleIds: number[];
修改user.service.ts
async addUser(data: UserDTO): Promise<User>{
const user = new User();
user.username = data.username;
user.email = data.email;
//user.depId = data.depId; 不能只指定id,必須傳入物件
user.dep = await this.depService.getDepById(data.depId);
// 先要取得role物件陣列,再指給user物件下的roles,save時才會儲存關聯
user.roles = await this.roleService.getRolesByIds(data.roleIds);
return await this.userRepo.save(user); // 新增一筆user資料
async getUsers(): Promise<User[]>{
return await this.userRepo.find({relations: ['dep', 'roles']}); // 載入dep及roles導覽屬性
async getUserById(id): Promise<User>{
return await this.userRepo.findOne(id, {relations: ['dep', 'roles']}); // 載入dep及roles導覽屬性
// return await this.userRepo.findOneOrFail(id); // 以id搜尋,沒找到會丟出例外
async updateUser(id, data: UserDTO){
const user = new User();
user.username = data.username;
user.email = data.email;
user.dep = await this.depService.getDepById(data.depId);
user.roles = await this.roleService.getRolesByIds(data.roleIds);
return await this.userRepo.update(id, user); // 用data裡的值更新到資料庫
使用postman測試
我已預先建立三個Role,先測試新增使用者
列出使用者清單,看是否有儲存關聯資料
列出Role清單,看是否載入關聯資料
Github source code