Sequelize
Sep 30th, 2014
AGENDA
-
Introduction - ORM
-
Sequelize
-
Installing
-
Connection
-
Models
-
Data Types
-
Getters & Setters
-
Validation
-
Finders
-
Instances
______________________________________________
Sequelize - A Node Js ORM library
AGENDA
-
Associations
-
Hooks
-
Raw SQL
-
DB Syncrhronization
-
Conclusion
-
Learn More
-
Challenge
______________________________________________
Sequelize - A Node Js ORM library
pre-requisites
Javascript - Intermediate
Notions of databases
Notions of Node.js
______________________________________________
Sequelize - A Node Js ORM library
ORM
Object-Relational Mapping
A layer between the application and persistence
Avoid the need to write raw SQL
SELECT * FROM Users WHERE id = 4
Become
user = Users.find(4);
______________________________________________
Sequelize - A Node Js ORM library
ORM
Another commercial solutions
- EJB, Hibernate - Java
-
Doctrine - PHP
- ADO.NET Entity Framework - .Net
______________________________________________
Sequelize - A Node Js ORM library
SEQUELIZE
"The Sequelize library provides easy access to MySQL, MariaDB, SQLite or PostgreSQL databases by mapping database entries to objects and vice versa"
______________________________________________
Sequelize - A Node Js ORM library
Sequelize
Entirely written in JavaScript
Can be used with Node.js
- MySQL
- SQLite
- PostgreSQL
- MariaDB
______________________________________________
Sequelize - A Node Js ORM library
Installing
$ npm install sequelize
$ npm install mysql
On your application you need to require the library
var Sequelize = require("sequelize");
______________________________________________
Sequelize - A Node Js ORM library
Connection
var sequelize = new Sequelize('db', 'username'[, 'password'] [,'options']);
// You can also specify a non-default host/port
var sequelize = new Sequelize('database', 'username', 'password', {
host: "my.server",
port: 12345
});
Using connection string:
var sequelize = new Sequelize('mysql://user:pass@example.com:9821/dbname'[, 'options']);
Options
______________________________________________
Sequelize - A Node Js ORM library
Models
- Represent tables
var Book = sequelize.define('Book', {
title: Sequelize.STRING,
description: Sequelize.TEXT,
publication: Sequelize.DATE
});
______________________________________________
Sequelize - A Node Js ORM library
Models
- You can set options on each column
// Allow null, default value
flag: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true}
// Unique values
someUnique: {type: Sequelize.STRING, unique: true}
// Primary Key
id: { type: Sequelize.INTEGER, primaryKey: true}
// autoIncrement
increment: { type: Sequelize.INTEGER, autoIncrement: true }
// comments - only for MySQL and PG
hasComment: { type: Sequelize.INTEGER, comment: "Comment!" }
______________________________________________
Sequelize - A Node Js ORM library
Data types
Sequelize.STRING(1234) // VARCHAR(1234)
Sequelize.STRING.BINARY // VARCHAR BINARY
Sequelize.TEXT // TEXT
Sequelize.INTEGER // INTEGER
Sequelize.BIGINT(11) // BIGINT(11)
Sequelize.FLOAT(11, 12) // FLOAT(11,12)
Sequelize.DECIMAL(10, 2) // DECIMAL(10,2)
Sequelize.DATE // DATETIME for mysql/sqlite; TIMESTAMP
// WTZ Postgres
Sequelize.BOOLEAN // TINYINT(1)
Sequelize.ENUM('value 1', 'value 2') // ENUM
Sequelize.ARRAY(Sequelize.TEXT) // Defines an array. PostgreSQL only
Sequelize.BLOB('tiny') // Other options are medium and long
Sequelize.UUID // UUID for PostgreSQL and SQLite,
// CHAR(36) BINARY for MySQL
______________________________________________
Sequelize - A Node Js ORM library
Getters & setters
- You can define the way to access your module values
- Defining as part of a property:
var Book = sequelize.define('Book', {
title: {
type : Sequelize.STRING,
get : function() {
return "Book title"
},
set : function(value) { /*...*/}
}
});
______________________________________________
Sequelize - A Node Js ORM library
GETTERS & SETTERS
-
Defining as part of the model options
var Book = sequelize.define('Book', { title:Sequelize.STRING } }, { getterMethods : { title : function() {/* Return a value */} }, setterMethods : { title : function(v) { /*...*/ } } });
______________________________________________
Sequelize - A Node Js ORM library
GETTERS & SETTERS
Helpers
- getDataValue()
function() {
return this.getDataValue('title');
}
- setDataValue()
function(title) {
return this.setDataValue('title', title.toString().toLowerCase());
}
______________________________________________
Sequelize - A Node Js ORM library
______________________________________________
Sequelize - A Node Js ORM library
VALIDATION
Property level:
var Book= sequelize.define('Book', {
title: {
type: Sequelize.STRING,
validate: {
isAlphanumeric: true,
notEmpty: true
}
}
});
______________________________________________
Sequelize - A Node Js ORM library
VALIDATION
Model Level
var Contact = Sequelize.define('Contact', {
name: { type: Sequelize.STRING },
address1: { type: Sequelize.STRING },
address2: { type: Sequelize.STRING },
,
}, {
validate: {
atLeastOneAddress: function() {
if ((this.address1 === "") && (this.address2 === "")) {
throw new Error('Require at least one address');
}
}
}
})
______________________________________________
Sequelize - A Node Js ORM library
VALIDATION
Built-in validators
is: /^[a-z]+$/i, // RegExp
not: ["[a-z]",'i'], // will not allow letters
isEmail: true, // checks for email format (foo@bar.com)
isUrl: true, // checks for url format (http://foo.com)
isAlpha: true, // will only allow letters
isNumeric: true // will only allow numbers
isInt: true, // checks for valid integers
isFloat: true, // checks for valid floating point numbers
isNull: true, // only allows null
len: [2,10], // allow values with length between 2 and 10
isDate: true, // only allow date strings
isAfter: "2011-11-05", // allow date strings after a specific date
isBefore: "2011-11-05", // allow date strings before a specific date
max: 23, // only allow values <= 23
min: 23, // only allow values >= 23
isCreditCard: true, // check for valid credit card numbers
______________________________________________
Sequelize - A Node Js ORM library
VALIDATION
Custom validators
isEven: function(value) {
if(parseInt(value) % 2 != 0) {
throw new Error('Only even values are allowed!')
}
}
isInt: {
msg: "Must be an integer number of pennies"
}
______________________________________________
Sequelize - A Node Js ORM library
Finders
-
find()
- returns a single entry
// search for a known id
Project.find(123).success(function(project) {});
// search for attributes
Project.find({ where: {title: 'aProject'} }).success(function(project) {});
// only select some attributes and rename one
Project.find({
where: {title: 'aProject'},
attributes: ['id', ['name', 'title']]
}).success(function(project) {});
______________________________________________
Sequelize - A Node Js ORM library
FINDERS
-
findOrCreate()
- Check if an element exists and if not, create it
User.findOrCreate(
{ username: 'tbonfim' },
{ fullname: 'Thiago Bonfim' })
.success(function(user, created) {});
The success callback function will receive the retrieved/created user and the flag 'created'
______________________________________________
Sequelize - A Node Js ORM library
FINDERS
-
findAndCountAll()
- Returns an object with two properties, the total number of records and an array of objects containing the records
Project.findAndCountAll({ where: ["title LIKE 'NodeJS%'"] }) .success(function(result) { /* result.count and result.rows */ });
______________________________________________
Sequelize - A Node Js ORM library
FINDERS
-
findAll()
-
Search for multiple elements in the database
Project.findAll().success(function(projects) { // returns all instances of projects }); // Using where Project.findAll({ where: { id: { gt: 6, // id > 6 gte: 6 // id >= 6 lt: 1, // id < 1 lte: 1, // id <= 1 ne: 20, // id != 20 between: [6, 10], // BETWEEN 6 AND 10 nbetween: [11, 15] // NOT BETWEEN 11 AND 15 } } });
______________________________________________
Sequelize - A Node Js ORM library
FINDERS
-
count()
Project.count([where]).success(function(c) {});
-
max()
Project.max('Column', [where]).success(function(max) {});
-
min()
Project.min('Column', [where]).success(function(min) {});
-
sum()
Project.sum('Column', [where]).success(function(sum) {});
______________________________________________
Sequelize - A Node Js ORM library
Instances
-
build()
- Create an unsaved object
var Task = sequelize.define('Project', {
title: Sequelize.STRING,
rating: { type: Sequelize.STRING, defaultValue: 3 }
});
var task = Task.build({title: 'very important task'});
Note: When you use build() you have to use the save() method to store values!
______________________________________________
Sequelize - A Node Js ORM library
INSTANCES
-
create()
- create and store an instance
Task.create({
title: 'Task 1',
description: 'A hard task',
deadline: new Date() })
.success(function(task) {});
You can define which attributes to set
User.create({ username:'tbonfim', isAdmin:true}, [ 'username' ]) .success(function(user) { // only the attribute 'username' will be set});
______________________________________________
Sequelize - A Node Js ORM library
INSTANCES
-
save()
task.title = 'Another title';
task.save().success(function() {});
You can also set the properties you want to save
task.title = 'Another title';
task.description = 'Very easy task';
task.save(['title']).success(function() {
// will only save title
});
______________________________________________
Sequelize - A Node Js ORM library
INSTANCES
- updateAttributes()
- another way to update instance values
task.updateAttributes({
title: 'Another title'
}, [<attributes to save>]).success(function() {});
______________________________________________
Sequelize - A Node Js ORM library
INSTANCES
- destroy()
- Delete an object from the database
task.destroy().success(function() { });
Can be used to delete multiple instances
Task.destroy({ subject: 'programming'})
.success(function(affectedRows){});
______________________________________________
Sequelize - A Node Js ORM library
INSTANCES
-
bulkCreate()
- Create bulks of instances
Task.bulkCreate([
{subject: 'programming', status: 'executing'},
{subject: 'reading', status: 'executing'},
{subject: 'programming', status: 'finished'}
]).success(function() {});
- update()
- Update bulks of instances
Task.update(
{status: 'inactive'}, // set status = 'inactive'
{subject: 'programming'} // where subject = 'programming'
).success(function(affectedRows) {});
______________________________________________
Sequelize - A Node Js ORM library
ASSOCIATIONS
You can specify associations between multiple modules
Automatically create indexes to control the relationship between tables
- One-To-One
- One-To-Many
- Many-To-Many
______________________________________________
Sequelize - A Node Js ORM library
One-To-One associations
Connect one source with exactly one target
Methods belongsTo() and hasOne()
var User = sequelize.define('User', {/* ... */});
var Project = sequelize.define('Project', {/* ... */});
// One-way associations, from Project to User
Project.hasOne(User);
// To get the association working from User to Project, we need to do this:
User.belongsTo(Project);
______________________________________________
Sequelize - A Node Js ORM library
One-To-Many associations
Connect one source with multiple targets
Targets however are connected to only one source
var User = sequelize.define('User', {/* ... */});
var Project = sequelize.define('Project', {/* ... */});
Project.hasMany(User, {as: 'Workers'});
______________________________________________
Sequelize - A Node Js ORM library
Many-To-Many associations
Connect multiple resources with multiple targets
Project.hasMany(User, { as: 'Workers' });
User.hasMany(Project);
Will create a new model called ProjectUsers
You can specify the name of an existing join table
Project.hasMany(User, {through: 'project_has_users'});
User.hasMany(Project, {through: 'project_has_users'});
You can also add attributes to the join table
UserProjects = sequelize.define('UserProjects', {status: DataTypes.STRING});
User.hasMany(Project, { through: UserProjects });
Project.hasMany(User, { through: UserProjects });
______________________________________________
Sequelize - A Node Js ORM library
Associating objects
After setting the associations, you will be able to use helper methods to access associated instances
// many associations project.getTasks().success(function(associatedTasks) {}); project.setTasks(tasks).success(function(associatedTasks) {});
// one associations project.getTask().success(function(associatedTasks) {}); project.setTask(task).success(function(associatedTasks) {}); // add/ remove project.removeTask(task).success(function() {}); project.addTask(task).success(function() {}); // checking associations project.hasUser(u).success(function(result){// result will be true or false});
______________________________________________
Sequelize - A Node Js ORM library
HOOKS
Functions called before and after calls in Sequelize are executed
beforeBulkCreate(daos, fields, fn)/ afterBulkCreate(daos, fields, fn)
beforeBulkDestroy(daos, fields, fn)/ afterBulkDestory(daos, fields, fn)
beforeBulkUpdate(daos, fields, fn)/ afterBulkUpdate(daos, fields, fn)
beforeCreate(dao, fn)/ afterCreate(dao, fn)
beforeDestroy(dao, fn)/ afterDestroy(dao, fn)
beforeUpdate(dao, fn)/ afterUpdate(dao, fn)
beforeValidate(dao, fn)/afterValidate(dao, fn)
______________________________________________
Sequelize - A Node Js ORM library
HOOKS
var User = sequelize.define('User', { username: DataTypes.STRING }, {
hooks: { beforeValidate: function(user, fn) { /* fn(null, user); */ } } }); // another way to add a hook User.hook('beforeValidate', function(user, fn) { /* fn(null, user); */ });
______________________________________________
Sequelize - A Node Js ORM library
Executing raw SQL queries
Sometimes its just easier to execute raw/ already existing SQL queries
-
query()
sequelize.query('query', [, model], [, options], [, replacements])
.success(function(rows) {});
______________________________________________
Sequelize - A Node Js ORM library
Database synchronization
Use Sequelize to create the needed database structure
After defining models just call the method sync()
Project.sync()
.success(function(){})
.error(function(error){});
Project.sync({force: true}); // drop the table if exists and then create
Project.drop();
// Instead of synchronizing all of your models, you can use Sequelize to just
// synchronize your database once:
sequelize.sync()
.success(function(){})
.error(function(error){});
sequelize.sync({force: true});
sequelize.drop();
______________________________________________
Sequelize - A Node Js ORM library
CONCLUSION
ORM solution is a must to have
Sequelize is a mature solution
Another solutions
______________________________________________
Sequelize - A Node Js ORM library
CONCLUSION
______________________________________________
Sequelize - A Node Js ORM library
Learn More
Sequelize - Documentation, articles, blog...
______________________________________________
Sequelize - A Node Js ORM library
Challenge
-
Create 3 models with at least 3 attributes
-
Associate the models using at least one One-to-Many relationship and one Many-to-Many
- Create multiple instances with sample data (you can choose creating one by one or bulk create)
-
Retrieve your instances by using one of the Finders using 'where' conditions
-
Destroy your instances
-
Send me your solution using a GitHub repository
______________________________________________
Sequelize - A Node Js ORM library
Sequelize
By Thiago Oliveira Bonfim
Sequelize
A presentation about Sequelize, an ORM tool for Node.js
- 4,769