KNEX.JS
Knex.js(2.0.0)
Knex.js是一个“batteries included”的SQL查询构建器,用于PostgreSQL,CockroachDB,MSSQL,MySQL,MariaDB,SQLite3,Better-SQLite3,Oracle和Amazon Redshift数据库, Knex.js致力于灵活,可移植性且增加使用者体验。它具有传统的节点样式回调以及用于更简洁的异步流控制的承诺接口,流接口,全功能查询和架构构建器,事务支持(带保存点),连接池以及不同查询客户端和方言之间的标准化响应。
安装和连接数据库
Knex的主要目标环境是Node.js,本教程使用的数据库是mysql数据库,使用的IDE工具是vscode
可以使用vscode插件"Code Runner"代替node指令达到快捷运行代码的目的
安装
使用npm安装knex和数据库依赖包
$ npm install knex --save
# 挑选一个你想要操作的数据库,安装相关依赖包
$ npm install pg --save
$ npm install pg-native --save
$ npm install sqlite3 --save
$ npm install better-sqlite3 --save
$ npm install mysql --save
$ npm install mysql2 --save
$ npm install oracledb --save
$ npm install tedious --save
测试连接
新建test01.js,测试node.js,knex.js,mysql是否成功安装且是否能正常进行连接
这个示例中包含了异常捕获抛出和关闭数据库连接,这些不是必须的,但是会使得代码在发生错误时能将错误日志输出到控制台,帮助我们完善代码
const options = {
client: 'mysql2',
connection: {
host: '127.0.0.1',
user: 'root',
password: 'password',
database: 'bookstore'
}
}
const knex = require('knex')(options);
knex.raw("SELECT VERSION()").then(
(version) => console.log((version[0][0]))
).catch((err) => { console.log( err); throw err })
.finally(() => {
knex.destroy();
});
使用node test01.js运行代码
node .\test01.js
Server running at http://127.0.0.1:8000/
初始化库
该模块本身就是一个函数,它接受Knex的配置对象,接受一些参数。该参数是必需的,并将用于确定连接数据库的参数和一些配置信息
const knex = require('knex')({
client: 'mysql2',
connection: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'password',
database: 'bookstore'
}
});
可选配置
userParams
userParams是一个可选参数,允许您传递可通过属性访问的任意参数:knex.userParams
userParams: {
userParam1: '451'
}
池
由配置创建的客户端使用 tarn.js库初始化连接池。此连接池的 MySQL 和 PG 库拥有默认设置。要更改池的配置设置,请将一个选项作为初始化块中的键之一传递。min: 2, max: 10pool
const knex = require('knex')({
client: 'mysql',
connection: {
host : '127.0.0.1',
port : 3306,
user : 'your_database_user',
password : 'your_database_password',
database : 'myapp_test'
},
pool: { min: 0, max: 7 }
});
获取连接超时
acquireConnectionTimeout
默认值为 60000ms,用于确定在无法获取连接时 knex 在引发超时错误之前应等待多长时间。最常见的原因是用尽了事务连接的所有池,然后尝试在事务池仍然已满时在事务之外运行查询。引发的错误将提供有关连接所针对的查询的信息,以简化查找罪魁祸首的工作。
const knex = require('knex')({
client: 'pg',
connection: {...},
pool: {...},
acquireConnectionTimeout: 10000
});
日志
Knex 包含一些内部日志功能,用于打印警告、错误、弃用和调试信息(如果适用)。这些日志函数通常记录到控制台,但可以使用 log 选项和提供替代函数来覆盖。不同的日志函数可用于单独的 knex 实例。
const knex = require('knex')({
log: {
warn(message) {
},
error(message) {
},
deprecate(message) {
},
debug(message) {
},
}
});
Knex.js 基本操作
在系统学习Knex.js的查询生成器,标识符语法等等知识之前,本文会先讲述使用Knex.js进行建表(CREATE)、插入数据(INSERT)、选择所有行(SELECT)、限制输出(WHERE)、排序行(ORDERBY)这几个案例来帮助读者更加快的理解Knex.js的查询生成器
下面案例使用到的所有方法和参数,在查询生成器部分都有详细解读
创建表
在这个示例中,我们创建一个新的数据库表
create table `users` (`id` int unsigned not null auto_increment primary key, `name` varchar(255), `price` integer(11))
const knex = require('knex')({
client: 'mysql2',
connection: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'password',
database: 'bookstore'
}
});
knex.schema.createTable('cars', (table) => {
table.increments('id')
table.string('name')
table.integer('price')
}).then(() => console.log("table created"))
.catch((err) => { console.log(err); throw err })
.finally(() => {
knex.destroy();
});
插入数据
这个示例中,我们将尝试向上文创建的表中插入一些数据
const knex = require('knex')({
client: 'mysql2',
connection: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'password',
database: 'bookstore'
}
});
const cars = [
{ name: 'Audi', price: 52642 },
{ name: 'Mercedes', price: 57127 },
{ name: 'Skoda', price: 9000 },
{ name: 'Volvo', price: 29000 },
{ name: 'Bentley', price: 350000 },
{ name: 'Citroen', price: 21000 },
{ name: 'Hummer', price: 41400 },
{ name: 'Volkswagen', price: 21600 },
]
knex('cars').insert(cars).then(() => console.log("data inserted"))
.catch((err) => { console.log(err); throw err })
.finally(() => {
knex.destroy();
});
选择所有行
这个示例将会演示查询这个表中所有数据并且打印到控制台
const knex = require('knex')({
client: 'mysql2',
connection: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'password',
database: 'bookstore'
}
});
knex.from('cars').select("*")
.then((rows) => {
for (row of rows) {
console.log(`${row['id']} ${row['name']} ${row['price']}`);
}
}).catch((err) => { console.log( err); throw err })
.finally(() => {
knex.destroy();
});
限制输出
这个示例将会演示使用limit关键字约束检索到的数据
const knex = require('knex')({
client: 'mysql2',
connection: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'password',
database: 'bookstore'
}
});
knex.from('cars').select("name", "price").where('price', '>', '50000')
.then((rows) => {
for (row of rows) {
console.log(`${row['name']} ${row['price']}`);
}
})
.catch((err) => { console.log( err); throw err })
.finally(() => {
knex.destroy();
});
排序行
这个示例将会演示使用orderby关键字对检索到的数据进行排序
const knex = require('knex')({
client: 'mysql2',
connection: {
host: '127.0.0.1',
port: 3306,
user: 'root',
password: 'password',
database: 'bookstore'
}
});
knex.from('cars').select('name', 'price').orderBy('price', 'desc')
.then((rows) => {
for (row of rows) {
console.log(`${row['name']} ${row['price']}`);
}
}).catch((err) => { console.log( err); throw err })
.finally(() => {
knex.destroy();
});
结果打印
在使用knex对象进行查询生成器的构建之后,运行代码并不会输出任何内容,尽管您构建了正确的查询语句,所以这里需要打印查询到的结果
.then((rows) => {
console.log(rows);
})
以上这种方式会将结果赋值给rows,rows为一个键值对对象数组,数组中每一个key就是您查询的表中的属性名称,value就是您查询的表中的属性值;您可以根据查询的表中的内容来对数组进行遍历输出。
例如,查询了表cars中的所有内容,表有id、name、price三个属性,可以通过一下遍历的方式进行更清楚的输出,也可以在循环语句内完成赋值或进行业务的处理等操作
.then((rows) => {
for (row of rows) {
console.log(`${row['id']} ${row['name']} ${row['price']}`);
}
})
异常捕获
在进行完查询生成器构建sql语句进行查询和打印结果后,通常需要使用异常捕获来打印出捕获到的异常,通常情况下就算使用错误的方法或者sql语句执行错误,knex也不会主动向控制台输出错误内容,所以我们就需要手动制定异常输出来输出异常
.catch((err) => { console.log( err); throw err })
关闭连接池
在进行完所有操作后,需要及时关闭数据库连接池,连接池是宝贵的资源,所以使用完一个knex对象后需要进行连接池的手动关闭,关闭需要写在finally语句块中
.finally(() => {
knex.destroy();
});
查询生成器(Query Builder)
Query Builder需要指明query操作对应的table或直接调用knex对象的方法。
整个构造过程包括,构造sql语句,调用interface方法(接口方法用于执行语句或者转换为字符串打印出来)。
查询
select([*columns])
column(columns)
from([tableName])
knex.column('title', 'author', 'year').select().from('books')
// select "title", "author", "year" from "books"
插入
insert(data, [returning])`
`returning(column)` /`returning([column1, column2, ...])
knex('books')
.returning('id')
.insert({title: 'Slaughterhouse Five'})
// insert into "books" ("title") values ('Slaughterhouse Five') returning "id"
修改
update(data, [returning])` / `update(key, value, [returning])
knex('books')
.where('published_date', '<', 2000)
.update({
status: 'archived',
thisKeyIsSkipped: undefined
})
// update "books" set "status" = 'archived' where "published_date" < 2000
删除
del()
knex('accounts')
.where('activated', false)
.del()
// delete from "accounts" where "activated" = false
运算
方法 | 说明 |
---|---|
count(column) | 个数 |
min(column) | 最小值 |
max(column) | 最大值 |
sum(column) | 求和 |
avg(column) | 平均 |
increment(column, amount) | 自增 |
decrement(column, amount) | 自减 |
knex对象
查询生成器首先指定要查询的 tableName,这在上文连接中会指定,然后就是在 knex 对象上调用任何方法。这启动了一个类似 jQuery 的链,您可以使用它根据需要调用其他查询生成器方法来构造查询,最终调用任何接口方法,以转换为String,或者使用 promise、回调或流执行查询。
例:使用knex对象完成查询
//这种查询仅仅会构造查询函数,并不会进行结果的输出
knex.from('cars').select("*")
超时(timeout)
设置查询的超时,如果超过超时,将引发超时错误。该错误包含有关查询、绑定和设置的超时的信息。对于要确保执行时间不会过长的复杂查询非常有用。用于传递选项的可选第二个参数:取消: 如果 ,则达到超时,取消查询。
//select * from `books`
knex.select().from('books').timeout(1000)
选择(select)
创建一个选择查询,为查询获取一个可选的列数组,如果在生成查询时未指定任何列,则最终默认为 *。选择调用的响应将使用从数据库中选择的对象数组进行解析。
//select `title`, `author`, `year` from `books`
knex.select('title', 'author', 'year').from('books')
//select * from `books`
knex.select().table('books')
作为(as)
允许为子查询指定别名,并命名为当前查询的字符串。如果查询不是子查询,则将忽略它。
//select avg(`sum_column1`) from (select sum(`column1`) as `sum_column1` from `t1` group by `column1`) as `t1`
knex.avg('sum_column1').from(function() {
this.sum('column1 as sum_column1').from('t1').groupBy('column1').as('t1')
}).as('ignored_alias')
列(column)
这里的列类似于mysql中字段的概念,专门设置要在选择查询中选择的列,采用数组、对象或列名列表。传递对象将自动使用给定键为列添加别名。
//select `title`, `author`, `year` from `books`
knex.column('title', 'author', 'year').select().from('books')
//select `title`, `author` as `by`, `year` from `books`
knex.column('title', {by: 'author'}, 'year').select().from('books')
从(from)
指定当前查询中使用的表,如果已指定表名,则替换当前表名。这通常用于在高级 where 或联合方法中执行的子查询中。
//select * from `users`
knex.select('*').from('users')
来自表(fromRaw)
可以将fromRaw参数体内的sql执行后的表格作为表格参数进行二次检索
//select * from (select * from "users" where "age" > '18')
knex.select('*').fromRaw('(select * from "users" where "age" > ?)', '18')
与(with)
向查询中添加“with”子句。PostgreSQL、Oracle、SQLite3 和 MYSQL 支持 “With” 子句。可以在别名后提供可选的列列表;如果提供,它必须至少包含一个列名。
//with `with_alias` as (select * from "books" where "author" = 'Test') select * from `with_alias`
knex.with('with_alias', knex.raw('select * from "books" where "author" = ?', 'Test')).select('*').from('with_alias')
其中方法
其中(where)
a.对象和键值语法
//select `id` from `users` where `first_name` = 'Test' and `last_name` = 'User'
knex('users').where({
first_name: 'Test',
last_name: 'User'
}).select('id')
//select * from `users` where `id` = 1
knex('users').where('id', 1)
b.操作符语法
//select * from `users` where (`id` in (1, 11, 15) and `id` not in (17, 19)) and (`id` > 10)
knex('users')
.where((builder) =>
builder.whereIn('id', [1, 11, 15]).whereNotIn('id', [17, 19])
)
.andWhere(function() {
this.where('id', '>', 10)
})
c.分组where
//select * from `users` where (`id` = 1 or `id` > 10) or (`name` = 'Tester')
knex('users').where(function() {
this.where('id', 1).orWhere('id', '>', 10)
}).orWhere({name: 'Tester'})
d.计算,模糊
//select * from `users` where `columnName` like '%rowlikeme%'
knex('users').where('columnName', 'like', '%rowlikeme%')
e.回调型
处理复杂查询(嵌套查询、并列查询)的时候更简洁
knex('users').where(function() {
this.where('id', 1).orWhere('id', '>', 10)
})
// select * from "users" where ("id" = 1 or "id" > 10)
f.链式调用型
常用于处理复杂查询或条件较多的情况
// 嵌套查询的例子
var subquery = knex('users').where('votes', '>', 100).andWhere('status', 'active').orWhere('name', 'John').select('id');
knex('accounts').where('id', 'in', subquery)
// select * from "accounts" where "id" in (select "id" from "users" where "votes" > 100 and "status" = 'active' or "name" = 'John')
其中不(whereNot)
与where用法一致,将where替换为where not ,意为:其中不
//select * from `users` where not `id` = 1
knex('users').whereNot('id', 1)
注:
whereNot
不能用in
或者between
类型的子查询,需要用not in
或者not between
替代。
whereNot('id','in',subquery)
这种写法是错误的;
where('id','not in',subquery)
这种写法是正确的。
在…其中(whereIn)
.where(‘id’, ‘in’, obj) 的简写,.whereIn 和 .orWhereIn 方法将 “where in” 子句添加到查询中。请注意,将空数组作为值传递会导致查询从不返回任何行 (WHERE 1 = 0
)
whereIn('id',subquery)`可以用于替代`where('id','in',subquery)
//select `name` from `users` where `id` in (1, 2, 3) or `id` in (4, 5, 6)
knex.select('name').from('users')
.whereIn('id', [1, 2, 3])
.orWhereIn('id', [4, 5, 6])
whereNotIn
whereNotIn('id',subquery)`可以用于替代`where('id','not in',subquery)
whereNull
knex('users').whereNull('updated_at')
// select * from "users" where "updated_at" is null
whereNotNull
作用和whereNull相反
whereExists(builder | callback)
// builder可以作为参数传递给另一个builder
knex('users').whereExists(knex.select('*').from('accounts').whereRaw('users.account_id = accounts.id'))
// select * from "users" where exists (select * from "accounts" where users.account_id = accounts.id)
whereNotExists
作用和whereExists相反
whereRaw(query, [bindings])
执行原始的SQL语句
knex('users').whereRaw('id = ?', [1])
// select * from "users" where id = 1
连接/加入
熟悉sql语句的读者能更快熟悉这部分内容,并且更具本文档可以续写出所有join方法
加入(join)
连接生成器可用于指定表之间的连接,第一个参数是连接表,接下来的三个参数分别是第一个连接列、连接运算符和第二个连接列。
//select `users`.`id`, `contacts`.`phone` from `users` inner join `contacts` on `users`.`id` = `contacts`.`user_id`
knex('users')
.join('contacts', 'users.id', '=', 'contacts.user_id')
.select('users.id', 'contacts.phone')
内加入/内连接(innerJoin)
//select * from `users` inner join `accounts` on `users`.`id` = `accounts`.`user_id`
knex.from('users').innerJoin('accounts', 'users.id', 'accounts.user_id')
左加入/左连接(leftJoin)
//select * from `users` left join `accounts` on `users`.`id` = `accounts`.`user_id`
knex.select('*').from('users').leftJoin('accounts', 'users.id', 'accounts.user_id')
左外连接(leftOuterJoin)
//select * from `users` left outer join `accounts` on `users`.`id` = `accounts`.`user_id`
knex.select('*').from('users').leftOuterJoin('accounts', 'users.id', 'accounts.user_id')
在方法上
在(onIn)
//select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` in (7, 15, 23, 41)
knex.select('*').from('users').join('contacts', function() {
this.on('users.id', '=', 'contacts.id').onIn('contacts.id', [7, 15, 23, 41])
})
在…为空(onNull)
//select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`email` is null
knex.select('*').from('users').join('contacts', function() {
this.on('users.id', '=', 'contacts.id').onNull('contacts.email')
})
在…存在(onExists)
//select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and exists (select * from `accounts` where users.account_id = accounts.id)
knex.select('*').from('users').join('contacts', function() {
this.on('users.id', '=', 'contacts.id').onExists(function() {
this.select('*').from('accounts').whereRaw('users.account_id = accounts.id');
})
})
在两者之间(onBetween)
//select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`id` and `contacts`.`id` between 5 and 30
knex.select('*').from('users').join('contacts', function() {
this.on('users.id', '=', 'contacts.id').onBetween('contacts.id', [5, 30])
})
清除方法
清除(clear)
从查询中清除指定的运算符。可用的运算符:“选择”别名“列”、“与”、“选择”、“列”、“位置”、“联合”、“连接”、“组”、“顺序”、“有”、“限制”、“偏移”、“计数器”、“计数器”。方法的计数器别名 .clearCounter()
//select * from `users`
knex.select('email', 'name').from('users').where('id', '<', 10).clear('select').clear('where')
"有"方法
有(heaving)
having(column, operator, value)
select * from `users` group by `count` having `count` > 100 order by `name` desc
knex('users')
.groupBy('count')
.orderBy('name', 'desc')
.having('count', '>', 100)
havingRaw(column, operator, value)
having调用原生sql语句的方法
knex('users')
.groupBy('count')
.orderBy('name', 'desc')
.havingRaw('count > ?', [100])
// select * from "users" group by "count" having count > 100 order by "name" desc
有…在…(havingIn)
//select * from `users` having `id` in (5, 3, 10, 17)
knex.select('*').from('users').havingIn('id', [5, 3, 10, 17])
存在有(havingExists)
//select * from `users` having exists (select * from `accounts` where users.account_id = accounts.id)
knex.select('*').from('users').havingExists(function(){this.select('*').from('accounts').whereRaw('users.account_id = accounts.id');
})
分组(groupBy)
//select * from `users` group by `count`
knex('users').groupBy('count')
排序(orderBy)
orderBy(column|columns, [direction], [nulls])
将 order by 子句添加到查询中。列可以是字符串,也可以是与字符串和对象混合的列表。nulls 指定 null 值的放置位置(可以是“第一个”或“最后一个”)
//select * from `users` order by `email` asc
knex('users').orderBy('email')
groupByRaw(sql)
groupBy调用原生sql语句的方法
knex.select('year', knex.raw('SUM(profit)')).from('sales').groupByRaw('year WITH ROLLUP')
// select "year", SUM(profit) from "sales" group by year WITH ROLLUP
限制(limit)
向查询中添加限制子句。可以指定可选的 skipBinding 参数,以避免将 limit 添加为准备值(某些数据库不允许为 limit 添加准备好的值)。
//select * from `users` limit 10 offset 30
knex.select('*').from('users').limit(10).offset(30)
联合查询(union)
创建联合查询,使用可选的布尔换行获取数组或回调、生成器或原始语句的列表来生成联合语句。
//select * from `users` where `last_name` is null union select * from `users` where `first_name` is null
knex.select('*').from('users').whereNull('last_name').union(function() {this.select('*').from('users').whereNull('first_name')
})
插入(insert)
创建插入查询,获取要插入到行中的属性哈希或要作为单个插入命令执行的插入数组。
//insert into `books` (`title`) values ('Slaughterhouse Five')
knex('books').insert({title: 'Slaughterhouse Five'})
更新(update)
创建更新查询,获取属性的哈希或要根据其他查询约束进行更新的键/值对。
//update `books` set `status` = 'archived' where `published_date` < 2000
knex('books')
.where('published_date', '<', 2000)
.update({
status: 'archived',
thisKeyIsSkipped: undefined
})
删除(delete)
//delete from `accounts` where `activated` = false
knex('accounts')
.where('activated', false)
.del()
最小值/最大值(min/max)
//select min(`age`) from `users`
knex('users').min('age')
//select max(`age`) from `users`
knex('users').max('age')
总和(sum)
//select sum(`products`) from `users`
knex('users').sum('products')
平均(avg)
//select avg(`age`) from `users`
knex('users').avg('age')
架构生成器(Shema Builder)
这一部分的方法主要用于创建数据表、删除数据表或修改数据表的结构,即对应SQL中的create、drop、alter。这些方法都是在schema对象上调用。
raw
用于执行原始的SQL请求
knex.schema.raw(statement)
withSchema
用于指定schema名
knex.schema.withSchema([schemaName])
创建表(createTable)
创建新表
knex.schema.createTable(tableName, callback)
例子:
//create table `users` (`id` int unsigned not null auto_increment primary key, `name` varchar(255), `created_at` datetime, `updated_at` datetime)
knex.schema.createTable('users', function (table) {
table.increments();
table.string('name');
table.timestamps();
})
createTableIfNotExists
先判断表是否存在,若不存在创建新表
knex.schema.createTableIfNotExists(tableName, callback)
类似于:
create table if not exists ...
复制表(createTableLike)
//create table `new_users` like `users`
knex.schema.createTableLike('new_users', 'users')
重命名表(renameTable)
//rename table `users` to `old_users`
knex.schema.renameTable('users', 'old_users')
删除表(dropTable)
//drop table `users`
knex.schema.dropTable('users')
dropTableIfExists
先判断表是否存在,若存在删除表
knex.schema.dropTableIfExists(tableName)
判断表是否存在(hasTable)
判断表是否存在,返回布尔值
knex.schema.hasTable(tableName)
例子:先判断表是否存在,如果不存在,则创建表
knex.schema.hasTable('users').then(function(exists) {
if (!exists) {
return knex.schema.createTable('users', function(t) {
t.increments('id').primary();
t.string('first_name', 100);
t.string('last_name', 100);
t.text('bio');
});
}
});
hasColumn
判断列名是否存在,用法和hasTable类似
knex.schema.hasColumn(tableName, columnName)
table/alterTable
用callback的内容修改tableName对应的表
knex.schema.table(tableName, callback)
例子:
knex.schema.table('users', function (table) {
table.dropColumn('name');
table.string('first_name');
table.string('last_name');
})
//alter table "users" add column "first_name" varchar(255), add column "last_name" varchar(255);
//alter table "users" drop column "name"
操作column的方法
table对象的作用十分广泛,我们可以使用上文的table对象来对column进行操作
这一部分的方法,多用于添加、删除、修改字段的名称或类型、设置主键外键唯一键等。这些方法都是在table对象上调用。
方法 | 说明 |
---|---|
increments(name) | 自增列,会被用作主键 |
integer(name) | int类型 |
bigInteger(name) | bigInt类型 |
text(name,[textType]) | 文本类型,MySQL下有text,mediumtext,longtext可选 |
string(name,[length]) | 字符串类型,默认长度255字符 |
float(name,[precision],[scale]) | 浮点类型,默认为8和2 |
decimal(column,[precision],[scale]) | 十进制数类型,默认为8和2 |
boolean(name) | 布尔型 |
date(name) | date类型 |
dateTime(name) | dateTime类型 |
time(name) | time类型 |
timestamp(name,[standard]) | timestamp类型,PostgreSQL下默认为timestampz |
timestamps() | 添加created_at 和updated_at 字段 |
binary(name,[length]) | 二进制数类型,MySQL下可选择长度 |
enu(col,values) | 枚举类型,第二个参数需要是数组 |
json(name) | json类型,使用pgSQL内建的JSON格式,需要调用JSON.stringify()方法强制转换成JSON格式,在不支持json的数据库中会变成字符串类型 |
jsonb(name) | jsonb类型,可以使用本地的json格式 |
uuid(name) | uuid类型,使用pgSQL内建的uuid类型,不支持的数据库会变成36位的字符串 |
specificType(column,value) | 添加不支持的类型 |
删改字段
方法 | 说明 |
---|---|
dropColumn(name) | 通过name删除指定的字段 |
dropColumns(*names) | 删除多个字段 |
dropTimestamps() | 删除时间戳字段 |
renameColumn(from, to) | 重命名该字段 |
添加配置信息
方法 | 说明 |
---|---|
comment(value) | 添加注释 |
engine(val) | 设置表的引擎,只对MySQL有效,且只能在创建表时调用 |
charset(val) | 设置表的字符集,只对MySQL有效,且只能在创建表时调用 |
collate(val) | 设置表的简介,只对MySQL有效,且只能在创建表时调用 |
inherits(val) | 设置该表的父表,只对PostgreSQL有效,且只能在创建表时调用 |
添加特殊键
方法 | 说明 |
---|---|
index(columns, [indexName], [indexType]) | 在columns上添加索引,indexName默认为column名,indexType类型在pgsql下可选 |
unique(columns) | 添加唯一键 |
foreign(columns) | 将已存在的键设置为外键,和references搭配使用 |
例子
knex.schema.table('users', function (table) {
table.integer('user_id').unsigned()
table.string('email')
table.foreign('user_id').references('Items.user_id_in_items')
table.unique('email')
})
链式操作
有的方法可以进行链式操作,通常是在定义字段的同时,链在末尾完成功能。这些方法都是在column对象上调用
方法 | 说明 |
---|---|
index([indexName], [indexType]) | 将该column设为索引 |
primary([constraintName]) | 将该column设为主键,如果传入多个参数,则设置为联合主键 |
unique() | 将该column设为唯一键 |
references(column) | 设置外键所引用的表和字段,详见下方的例子 |
inTable(table) | 设置外键所在的表的表名,详见下方的例子 |
onDelete(command) | 设置运行onDelete时的SQL命令 |
onUpdate(command) | 设置运行onUpdate时的SQL命令 |
defaultTo(value) | 在插入时设置该column的默认值 |
unsigned() | 设置该column为无符号整数 |
notNullable() | 在创建column的时候设置该字段不可为空 |
nullable() | 显式设置该column可以为空,默认都是可以为空 |
first() | 将该column作为表的第一列,只在MySQL aliter表的时候有效 |
after(field) | 将该column插入到给定参数之后,只在MySQL aliter表的时候有效 |
comment(value) | 为该column添加注释 |
collate(collation) | 对该column添加校对器,只对MySQL有效 |
例子
knex.schema.table('users', function (table) {
table.integer('user_id').unsigned().notNullable()
table.foreign('user_id').references('user_id_in_items').inTable('Items')
// 下面这种写法和上面的写法是等价的
//table.foreign('user_id').references('Items.user_id_in_items')
})
架构构建
索引
将字段指定为索引。如果指定了 indexName,则使用它来代替tableName_columnName的标准索引命名约定。在MySQL中,存储引擎索引类型可能是“btree”或“hash”索引类型,更多信息请参阅索引选项部分:https://dev.mysql.com/doc/refman/8.0/en/create-index.html。可以选择为PostgreSQL和MySQL指定索引类型。如果这是从无法编制索引的字段链接出来的,则为 No-op。在PostgreSQL,SQLite和MSSQL中,可以通过设置“where”谓词来指定部分索引。