Databeheer met TypeORM
TypeORM is an ORM ( Object Relational Mapper) that can run in NodeJS and can be used with JavaScript (ES5, ES6, ES7, ES8). Its goal is to help you to develop any kind of application that uses databases - from small applications with a few tables to large scale enterprise applications with multiple databases.
Installeer typeorm
npm install typeorm
Installeer sqlite3
npm install sqlite3
Installeer body-parser
npm install body-parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
import bodyParser from "body-parser";
import { DataSource } from "typeorm";
const DS = new DataSource({
type: process.env.DATABASE_TYPE,
database: process.env.DATABASE_NAME,
synchronize: true,
});
export default DS;
import DataSource from "./lib/DataSource.js";
DataSource.initialize()
.then(() => {
// start the server
app.listen(process.env.PORT, () => {
console.log(
`Application is running on http://localhost:${process.env.PORT}/.`
);
});
})
.catch(function (error) {
console.log("Error: ", error);
});
PORT=3000
DATABASE_TYPE=sqlite
DATABASE_NAME="typeorm-demo.sqlite3"
Databeheer met TypeORM
An entity is an object that exists. It doesn't have to do anything; it just has to exist. In database administration, an entity can be a single thing, person, place, or object.
import typeorm from "typeorm";
const { EntitySchema } = typeorm;
export default new EntitySchema({
name: "NavigationItem",
tableName: "navigation_items",
columns: {
id: {
primary: true,
type: "int",
generated: true,
},
url: {
type: "varchar",
},
text: {
type: "varchar",
},
},
});
Voorbeeld SQL-syntax:
SELECT navigation_items.id, navigation_items.url, navigation_items.text
FROM navigation_items
WHERE navigation_items.url="https://www.google.be"
Wij zullen geen SQL schrijven tijdens de lessen, achterliggend zal TypeORM jouw verzoeken omzetten naar SQL zodat de dev-complexiteit van onze applicatie aanzienlijk lager ligt.
import DataSource from "../lib/DataSource.js";
const navigationItemRepository = DataSource.getRepository("NavigationItem");
const menuItems = await navigationItemRepository.find();
// import typeorm
import DataSource from "../lib/DataSource.js";
export const home = async (req, res) => {
// get reposito
const navigationItemRepository = DataSource.getRepository("NavigationItem");
// fetch the menu items
const menuItems = await navigationItemRepository.find();
res.render("home", {
menuItems
});
};
Databeheer met TypeORM
The primary or most-commonly-used HTTP verbs (or methods, as they are properly called) are POST, GET, PUT, and DELETE. These correspond to create, read, update, and delete (or CRUD) operations, respectively.
Een overzicht van andere HTTP methods kan je hier vinden.
Databeheer met TypeORM
Een REST API (Representational State Transfer Application Program Interface) is een architectuurstijl waarmee software kan communiceren met andere software via een netwerk of op hetzelfde apparaat. Doorgaans gebruiken ontwikkelaars REST-API's om webservices te bouwen.
import typeorm from "typeorm";
const { EntitySchema } = typeorm;
export default new EntitySchema({
name: "Interest",
tableName: "interests",
columns: {
id: {
primary: true,
type: "int",
generated: true,
},
name: {
type: "varchar",
}
},
});
import {
postInterest,
deleteInterest,
getInterests,
updateInterest
} from "./controllers/api/interest.js";
// insert the interests
const insertedInterest = await interestRepository.save(req.body);
const interest = await interestRepository.findOne({
where: { name: req.body.name }
});
// check if the name already exists
const interest = await interestRepository.findOneBy({
id: req.body.id
});
// update the interest
await interestRepository.save({ ...interest, ...req.body });
// check if the id exists
const interest = await interestRepository.findOneBy({ id: 1 });
// remove the interest
await interestRepository.remove({ id });
Databeheer met TypeORM
In relational databases, a relationship exists between two tables when one of them has a foreign key that references the primary key of the other table. This single fact allows relational databases to split and store data in different tables, yet still link the disparate data items together.
import typeorm from "typeorm";
const { EntitySchema } = typeorm;
export default new EntitySchema({
name: "UserMeta",
tableName: "user_meta",
columns: {
id: {
primary: true,
type: "int",
generated: true,
},
address: {
type: "varchar",
},
zipCode: {
type: "varchar",
},
city: {
type: "varchar"
}
}
});
import typeorm from "typeorm";
const { EntitySchema } = typeorm;
export default new EntitySchema({
name: "UserMeta",
tableName: "user_meta",
columns: {
// ...
},
relations: {
user: {
target: "User",
type: "one-to-one",
joinColumn: {
name: "user_id",
},
onDelete: "CASCADE",
},
},
});
import typeorm from "typeorm";
const { EntitySchema } = typeorm;
export default new EntitySchema({
name: "User",
tableName: "users",
columns: {
// ...
},
relations: {
meta: {
target: "UserMeta",
type: "one-to-one",
inverseSide: "user",
cascade: true,
},
},
});
We kunnen nu users ophalen, inclusief de relatie via
const users = await userRepository.find({relations: ["meta"]});
const insertedUser = await userRepository.save({
...req.body,
meta: {
address: "Industrieweg 232",
zipCode: "9050",
city: "Mariakerke"
}
});
import typeorm from "typeorm";
const { EntitySchema } = typeorm;
export default new EntitySchema({
name: "Pet",
tableName: "pets",
columns: {
id: {
primary: true,
type: "int",
generated: true,
},
animal: {
type: "varchar",
},
name: {
type: "varchar",
},
age: {
type: "int",
},
},
relations: {},
});
[...]
relations: {
meta: {
target: "UserMeta",
type: "one-to-one",
inverseSide: "user",
cascade: true,
},
pets: {
target: "Pet",
type: "one-to-many",
inverseSide: "owner",
cascade: true,
}
}
[...]
[...]
relations: {
owner: {
target: "User",
type: "many-to-one",
inverseSide: "pets",
joinColumn: {
name: "owner_id",
},
onDelete: "CASCADE",
},
}
[...]
await userRepository.find({ relations: ["pets"] });
&
await petRepository.find({ relations: ["owner"] });
await userRepository.save({
...req.body,
pets: [
{ animal: "dog", name: "felix", age: 5 },
{ animal: "cat", name: "miss puss", age: 1 }
]
});
import typeorm from "typeorm";
const { EntitySchema } = typeorm;
export default new EntitySchema({
name: "User",
tableName: "users",
columns: {
// ...
},
relations: {
// ...,
interests: {
target: "Interest",
type: "many-to-many",
joinTable: {
name: "users_interests",
},
cascade: true
}
}
});
export const postUser = async (req, res, next) => {
try {
// get the repository
const userRepository = DataSource.getRepository('User');
const interestRepository = DataSource.getRepository('Interest');
// FOR DEMO - insert the user and fetch all the interests
const insertedUser = await userRepository.save({
...req.body,
interests: await interestRepository.find()
});
// send a status code
res.status(200).json({ status: `Inserted user with id ${insertedUser.id}.` });
} catch(e) {
next(e.message)
}
}
export const getUsers = async (req, res, next) => {
try {
// get the repository
const userRepository = DataSource.getRepository('User');
// get the interests and return them with status code 200
res.status(200).json(await userRepository.find({ relations: ["interests"] }));
} catch(e) {
next(e.message);
}
}