14 KiB
Repository
Overview
On a given Collection
object, you can get its Repository
object to perform read and write operations on the data table.
const { UserCollection } = require("./collections");
const UserRepository = UserCollection.repository;
const user = await UserRepository.findOne({
filter: {
id: 1
},
});
user.name = "new name";
await user.save();
Query
Basic Query
On the Repository
object, call the find*
methods to perform query. The filter
parameter is supported by all query methods to filter the data.
// SELECT * FROM users WHERE id = 1
userRepository.find({
filter: {
id: 1
}
});
Operator
The filter
parameter in the Repository
also provides a variety of operators to perform more diverse queries.
// SELECT * FROM users WHERE age > 18
userRepository.find({
filter: {
age: {
$gt: 18
}
}
});
// SELECT * FROM users WHERE age > 18 OR name LIKE '%张%'
userRepository.find({
filter: {
$or: [
{ age: { $gt: 18 } },
{ name: { $like: "%张%" } }
]
}
});
Refer to Filter Operators for more details on operators.
Field Control
Control the output fields by the fields
, except
, and appends
parameters when performing query.
fields
: Specify output fieldsexcept
: Exclude output fieldsappends
: Append output associated fields
// The result contains only the <i>id</i> and <i>name</i> fields
userRepository.find({
fields: ["id", "name"],
});
// The result does not contain only the <i>password</i> field
userRepository.find({
except: ["password"],
});
// The result contains data associated with the <i>posts</i> object
userRepository.find({
appends: ["posts"],
});
Associated Field Query
The filter
parameter supports filtering by associated fields, for example:
// Find the <i>user</i> objects whose associated posts have title of "post title"
userRepository.find({
filter: {
"posts.title": "post title"
}
});
Associated fields can also be nested:
// Find the <i>user</i> objects whose associated posts have comments containing "keywords"
await userRepository.find({
filter: {
"posts.comments.content": {
$like: "%keywords%"
}
}
});
Sort
Sort query results by the sort
parameter.
// SELECT * FROM users ORDER BY age
await userRepository.find({
sort: 'age'
});
// SELECT * FROM users ORDER BY age DESC
await userRepository.find({
sort: '-age'
});
// SELECT * FROM users ORDER BY age DESC, name ASC
await userRepository.find({
sort: ['-age', "name"],
});
Sort by the field of the associated object is also supported:
await userRepository.find({
sort: 'profile.createdAt'
});
Create
Basic Create
Create new data objects via Repository
.
await userRepository.create({
name: "Mark",
age: 18,
});
// INSERT INTO users (name, age) VALUES ('Mark', 18)
// Bulk creation
await userRepository.create([
{
name: "Mark",
age: 18,
},
{
name: "Alex",
age: 20,
},
])
Create Association
Create associated objects at the same time of creating data. Similar to query, nested use of associated objects is also supported. For example:
await userRepository.create({
name: "张三",
age: 18,
posts: [
{
title: "post title",
content: "post content",
tags: [
{
name: "tag1",
},
{
name: "tag2",
},
],
},
],
});
// When crearing a user, creat a post to associate with the user, and create tags to associate with the post
If the associated object is already in the database, you can pass its ID to create an association with it.
const tag1 = await tagRepository.findOne({
filter: {
name: "tag1"
},
});
await userRepository.create({
name: "Mark",
age: 18,
posts: [
{
title: "post title",
content: "post content",
tags: [
{
id: tag1.id, // Create an association with an existing associated object
},
{
name: "tag2",
},
],
},
],
});
Update
Basic Update
After getting the data object, you can modify the properties directly on the data object (Model
), and then call the save
method to save the changes.
const user = await userRepository.findOne({
filter: {
name: "Mark",
},
});
user.age = 20;
await user.save();
The data object Model
is inherited from Sequelize Model, refer to Sequelize Model for the operations on Model
.
Or update data via Repository
:
// Update the records that meet the filtering condition
await userRepository.update({
filter: {
name: "Mark",
},
values: {
age: 20,
},
});
Control which fields to update by the whitelist
and blacklist
parameters, for example:
await userRepository.update({
filter: {
name: "Mark",
},
values: {
age: 20,
name: "Alex",
},
whitelist: ["age"], // Only update the <i>age</i> field
});
Update Associated Field
Associated objects can be set while updating, for example:
const tag1 = tagRepository.findOne({
filter: {
id: 1
},
});
await postRepository.update({
filter: {
id: 1
},
values: {
title: "new post title",
tags: [
{
id: tag1.id // Associate with tag1
},
{
name: "tag2", // Create new tag and associate with it
},
],
},
});
await postRepository.update({
filter: {
id: 1
},
values: {
tags: null // Disassociate post from tags
},
})
Delete
Call the destroy()
method in Repository
to perform the deletion operation. Filtering condition has to be specified to delete.
await userRepository.destroy({
filter: {
status: "blocked",
},
});
Constructor
It is usually not called directly by the developer, the instantiation is done mainly by specifying a coressponding repository type that is already registered in the parameter of db.colletion()
. Repository type is registered through db.registerRepositories()
.
Signature
constructor(collection: Collection)
Example
import { Repository } from '@nocobase/database';
class MyRepository extends Repository {
async myQuery(sql) {
return this.database.sequelize.query(sql);
}
}
db.registerRepositories({
books: MyRepository
});
db.collection({
name: 'books',
// here link to the registered repository
repository: 'books'
});
await db.sync();
const books = db.getRepository('books') as MyRepository;
await books.myQuery('SELECT * FROM books;');
Instance Member
database
The database management instance where the context is located.
collection
The corresponding data table management instance.
model
The corresponding data model class.
Instance Method
find()
Find datasets from the database with the specified filtering conditions and sorting, etc.
Signature
async find(options?: FindOptions): Promise<Model[]>
Type
type Filter = FilterWithOperator | FilterWithValue | FilterAnd | FilterOr;
type Appends = string[];
type Except = string[];
type Fields = string[];
type Sort = string[] | string;
interface SequelizeFindOptions {
limit?: number;
offset?: number;
}
interface FilterByTk {
filterByTk?: TargetKey;
}
interface CommonFindOptions extends Transactionable {
filter?: Filter;
fields?: Fields;
appends?: Appends;
except?: Except;
sort?: Sort;
}
type FindOptions = SequelizeFindOptions & CommonFindOptions & FilterByTk;
Detailed Information
filter: Filter
Query conditions for filtering data results. In the query parameters that passed in, key
is the name of the field, value
is the corresponding value. Operators can be used in conjunction with other filtering conditions.
// Find records with name "foo" and age above 18
repository.find({
filter: {
name: "foo",
age: {
$gt: 18,
},
}
})
Refer to Operators for more information.
filterByTk: TargetKey
Query data by TargetKey
, this is shortcut for the filter
parameter. The field of TargetKey
can be configured in Collection
, the default is primaryKey
.
// By default, find records with id 1
repository.find({
filterByTk: 1,
});
fields: string[]
Query columns. It is used to control which data fields to output. With this parameter, only the specified fields will be returned.
except: string[]
Exclude columns. It is used to control which data fields to output. With this parameter, the specified fields will not be returned.
appends: string[]
Append columns. It is used to load associated data. With this parameter, the specified associated fields will be returned together.
sort: string[] | string
Specify the sorting method of the query results. The input parameter is the name of the field, by default is to sort in the ascending order (asc
); a -
symbol needs to be added before the field name to sort in the descending order (desc
). For example, ['-id', 'name']
means to sort by id desc, name asc
.
limit: number
Limit the number of results, same as limit
in SQL
.
offset: number
The offset of the query, same as offset
in SQL
.
Example
const posts = db.getRepository('posts');
const results = await posts.find({
filter: {
createdAt: {
$gt: '2022-01-01T00:00:00.000Z',
}
},
fields: ['title'],
appends: ['user'],
});
findOne()
Find a single piece of data from the database for specific conditions. Equivalent to Model.findOne()
in Sequelize.
Signature
async findOne(options?: FindOneOptions): Promise<Model | null>
Example
const posts = db.getRepository('posts');
const result = await posts.findOne({
filterByTk: 1,
});
count()
Query a certain amount of data from the database for specific conditions. Equivalent to Model.count()
in Sequelize.
Signature
count(options?: CountOptions): Promise<number>
Type
interface CountOptions extends Omit<SequelizeCountOptions, 'distinct' | 'where' | 'include'>, Transactionable {
filter?: Filter;
}
Example
const books = db.getRepository('books');
const count = await books.count({
filter: {
title: 'Three character classic'
}
});
findAndCount()
Find datasets from the database with the specified filtering conditions and return the number of results. Equivalent to Model.findAndCountAll()
in Sequelize.
Signature
async findAndCount(options?: FindAndCountOptions): Promise<[Model[], number]>
Type
type FindAndCountOptions = Omit<SequelizeAndCountOptions, 'where' | 'include' | 'order'> & CommonFindOptions;
Detailed Information
The query parameters are the same as find()
. An array is returned with the first element of the query results, and the second element of the total number of results.
create()
Inserts a newly created data into the data table. Equivalent to Model.create()
in Sequelize. When the data object to be created carries any assiciated field, the corresponding assiciated data record is created or updated along with it.
Signature
async create<M extends Model>(options: CreateOptions): Promise<M>
Example
const posts = db.getRepository('posts');
const result = await posts.create({
values: {
title: 'NocoBase 1.0 Release Notes',
tags: [
// Update data when there is a primary key and value of the associated table
{ id: 1 },
// Create data when there is no primary key and value
{ name: 'NocoBase' },
]
},
});
createMany()
Inserts multiple newly created data into the data table. This is equivalent to calling the create()
method multiple times.
Signature
createMany(options: CreateManyOptions): Promise<Model[]>
Type
interface CreateManyOptions extends BulkCreateOptions {
records: Values[];
}
Detailed Information
records
: An array of data objects to be created.transaction
: Transaction object. If no transaction parameter is passed, the method will automatically create an internal transaction.
Example
const posts = db.getRepository('posts');
const results = await posts.createMany({
records: [
{
title: 'NocoBase 1.0 Release Notes',
tags: [
// Update data when there is a primary key and value of the associated table
{ id: 1 },
// Create data when there is no primary key and value
{ name: 'NocoBase' },
]
},
{
title: 'NocoBase 1.1 Release Notes',
tags: [
{ id: 1 }
]
},
],
});
update()
Update data in the data table. Equivalent to Model.update()
in Sequelize. When the data object to be updated carries any associated field, the corresponding associated data record is created or updated along with it.
Signature
async update<M extends Model>(options: UpdateOptions): Promise<M>
Example
const posts = db.getRepository('posts');
const result = await posts.update({
filterByTk: 1,
values: {
title: 'NocoBase 1.0 Release Notes',
tags: [
// Update data when there is a primary key and value of the associated table
{ id: 1 },
// Create data when there is no primary key and value
{ name: 'NocoBase' },
]
},
});
destory()
Delete data from the data table. Equivalent to Model.destroy()
in Sequelize.
Signature
async destory(options?: TargetKey | TargetKey[] | DestoryOptions): Promise<number>
Type
interface DestroyOptions extends SequelizeDestroyOptions {
filter?: Filter;
filterByTk?: TargetKey | TargetKey[];
truncate?: boolean;
context?: any;
}
Detailed Information
filter
:Specify the filtering conditions of the records to be deleted. Refer to thefind()
method for the detailed usage of the filter.filterByTk
:Specify the filtering conditions by TargetKey.truncate
: Whether to empty the table data, this parameter is valid if nofilter
orfilterByTk
parameter is passed.transaction
: Transaction object. If no transaction parameter is passed, the method will automatically create an internal transaction.