typeorm插入之save与insert
发布日期:2021-05-28 16:24:07 浏览次数:27 分类:技术文章

本文共 5346 字,大约阅读时间需要 17 分钟。

typeorm的Repository的数据库操作方法内部都调用了EntityManager的对应方法,对于同一类操作一般会有几个不同方法,如save、insert都可以用于插入

除了他们对于subscriber、entity listener的触发不同之外,在使用上它们也有区别

 

1.插入一个新的对象

 

实体:

 

import { Entity , PrimaryGeneratedColumn , Column } from 'typeorm'@Entity()export class User{    @PrimaryGeneratedColumn()    id:number    @Column({        type:'varchar'    })    name:string}

 

 

save:

 

import { createConnection,Repository } from 'typeorm'import { User } from './User'createConnection({    name:'test',    type: 'mysql',    host: 'localhost',    port: 3306,    username: 'root',    password: '123456',    database: "test",    synchronize:true,    dropSchema:true,    charset:'UTF8',    entities: [        User    ]}).then(async (connection)=>{    let userRepository = connection.getRepository(User)    let user = userRepository.create({name:'张三'})    let result = await userRepository.save(user)    console.log('执行结果为:')    console.log(result)    console.log('执行完之后实体对象:')    console.log(user)    console.log('执行完毕')})

输出:

 

 

执行结果为:User { name: '张三', id: 1 }执行完之后实体对象:User { name: '张三', id: 1 }执行完毕

 

 

insert:

 

then(async (connection)=>{    let userRepository = connection.getRepository(User)    let user = userRepository.create({name:'张三'})    let result = await userRepository.insert(user)    console.log('执行结果为:')    console.log(result)    console.log('执行完之后实体对象:')    console.log(user)    console.log('执行完毕')})

输出:

 

 

执行结果为:undefined执行完之后实体对象:User { name: '张三' }执行完毕

说明:

 

save会返回保存后的对象,包含了自动生成id,insert返回undefined

save保存之后,原实体对象上会出现自动生成id,insert插入之后原实体对象不变

这一步为了突出save对实体的改变,使用了自动生成id,如果id不是自动生成,那么只有返回值有区别

 

2.插入一个已存在数据库实体

 

实体:

 

import { Entity , PrimaryGeneratedColumn , Column ,PrimaryColumn} from 'typeorm'@Entity()export class User{    @PrimaryColumn({        type:'int'    })    id:number    @Column({        type:'varchar'    })    name:string}

注意:当主键不是自动生成时,需要指定主键类型,如果不指定会报错:无法猜测主键类型

 

 

save:

 

then(async (connection)=>{    let userRepository = connection.getRepository(User)    let user = userRepository.create({id:1,name:'张三'})    let result = await userRepository.save(user)    let result1 = await userRepository.save(user)    console.log('执行结果为:')    console.log(result)    console.log(result1)    console.log('执行完之后实体对象:')    console.log(user)    console.log('执行完毕')})

输出:

 

 

执行结果为:User { id: 1, name: '张三' }User { id: 1, name: '张三' }执行完之后实体对象:User { id: 1, name: '张三' }执行完毕

 

 

 

insert:

 

then(async (connection)=>{    let userRepository = connection.getRepository(User)    let user = userRepository.create({id:1,name:'张三'})    let result = await userRepository.insert(user)    let result1 = await userRepository.insert(user)    console.log('执行结果为:')    console.log(result)    console.log(result1)    console.log('执行完之后实体对象:')    console.log(user)    console.log('执行完毕')})

输出:

 

 

UnhandledPromiseRejectionWarning: QueryFailedError: ER_DUP_ENTRY: Duplicate entry '1' for key 'PRIMARY'

说明:

 

重复插入同一对象,save方法不出现错误,而且每次插入效果相同,insert方法报错

 

3.插入一个更改对象

save:

 

then(async (connection)=>{    let userRepository = connection.getRepository(User)    let user = userRepository.create({id:1,name:'张三'})    let result = await userRepository.save(user)    console.log(result==user)    console.log(result)    console.log(user)    user.name = '李四'    let result1 = await userRepository.save(user)    console.log(result)    console.log(result1)    console.log(user)})

输出:

 

 

trueUser { id: 1, name: '张三' }User { id: 1, name: '张三' }User { id: 1, name: '李四' }User { id: 1, name: '李四' }User { id: 1, name: '李四' }

使用insert插入还是报错,这里不演示了

 

说明:

save方法返回的对象与被操作的实体对象是一个对象,使用==判断引用为true

save可以保存修改实体,也就是实际上起了update的作用

 

问题:save方法如何判断一个实体对象应该被插入为新数据库条目,还是应该更新已有数据库条目?

1.非自动生成主键

 

then(async (connection)=>{    let userRepository = connection.getRepository(User)    let user = userRepository.create({id:1,name:'张三'})    let result = await userRepository.save(user)    user.id = 2    let result1 = await userRepository.save(user)})

显然,此时的数据库实体User只能通过id来识别一个实体,当id改变时save会将对象识别为一个需要插入而不是更新的实体,此时数据库数据为:

 

 

+----+--------+| id | name   |+----+--------+|  1 | 张三   ||  2 | 张三   |+----+--------+

假如给name加上索引:

 

 

import { Entity , PrimaryGeneratedColumn , Column ,PrimaryColumn} from 'typeorm'@Entity()export class User{    @PrimaryColumn({        type:'int'    })    id:number    @Column({        type:'varchar',        unique:true    })    name:string}

此时再执行,输出为:

 

 

UnhandledPromiseRejectionWarning: QueryFailedError: ER_DUP_ENTRY: Duplicate entry '张三' for key 'name'

说明,即便name加上了唯一性约束,save方法依然将id改变后的实体作为一个需要新插入的实体对待,说明索引应该不会影响save方法对一个实体的插入、更新的识别

2.自动生成主键

 

关于自动生成主键,唯一的原则是:如果不设置主键,则自动生成主键,如果设置主键,则按照设置的主键来处理,还是按照主键来识别一个实体是否应该插入、更新

then(async (connection)=>{    let userRepository = connection.getRepository(User)    let user = userRepository.create({name:'张三'})    let result = await userRepository.save(user)    console.log(user)    user.name = '李四'    let result1 = await userRepository.save(user)    console.log(user)

输出:

 

 

User { name: '张三', id: 1 }User { name: '李四', id: 1 }

此时,第一次插入主键为自动生成,第二次插入时主键为第一次生成主键,即1,此时save方法更新第一条数据

then(async (connection)=>{    let userRepository = connection.getRepository(User)    let user = userRepository.create({name:'张三'})    let result = await userRepository.save(user)    console.log(user)    user.id = null    user.name = '李四'    let result1 = await userRepository.save(user)    console.log(user)})

输出:

 

 

User { name: '张三', id: 1 }User { name: '李四', id: 2 }

此时,第二次插入之前将主键设置为null,则这次插入使用新的主键,即save方法将插入一条新数据

 

 

 

转载地址:https://blog.csdn.net/qq_27868061/article/details/79315159 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:typeorm更新之save与update、updateById
下一篇:typeorm之subscriber

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年12月02日 06时07分21秒