本文共 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!