ActiveRecordimplementation, you can use it as well:
npm install typeorm --save
npm install reflect-metadata --save
npm install @types/node --save-dev
npm install mysql --save(you can install
mysql2instead as well)
npm install pg --save
npm install sqlite3 --save
npm install mssql --save
npm install sql.js --save
npm install oracledb --save
libsection of compiler options, or install
nameis the name of your project and
databaseis the database you'll use. Database can be one of the following values:
MyProjectdirectory with the following files:
You can also run
typeorm initon an existing node project, but be careful - it may override some files you already have.
ormconfig.jsonfile and put your own database connection configuration options in there:
You can generate an even more advanced project with express installed by running
typeorm init --name MyProject --database mysql --expresscommand.
You can generate a docker-compose file by running
typeorm init --name MyProject --database postgres --dockercommand.
@Entitydecorator. A database table will be created for such models. You work with entities everywhere with TypeORM. You can load/insert/update/remove and perform other operations with them.
Photomodel as an entity:
Photoentity and we'll be able to work with it anywhere in our app. We have created a database table, however, what table can exist without columns? Let's create a few columns in our database table.
isPublishedcolumns will be added to the
phototable. Column types in the database are inferred from the property types you used, e.g.
numberwill be converted into
bool, etc. But you can use any column type your database supports by explicitly specifying a column type into the
@PrimaryColumndecorator to a
app.tswhatever you call it) file and set up our connection there:
typein the options to the database type you are using:
mongodb. Also make sure to use your own host, port, username, password and database settings.
synchronizemakes sure your entities will be synced with the database, every time you run the application.
ts-nodethen you need to specify paths to
.tsfiles instead. If you are using
outDirthen you'll need to specify paths to
.jsfiles inside the outDir directory. If you are using
outDirand when you remove or rename your entities make sure to clear
outDirdirectory and re-compile your project again, because when you remove your source
.tsfiles their compiled
.jsversions aren't removed from output directory and still are loaded by TypeORM because they are present in the
index.ts, a connection with the database will be initialized and a database table for your photos will be created.
savemethod returns an instance of the same object you pass to it. It's not a new copy of the object, it modifies its "id" and returns it.
EntityManagerto save it. Using entity manager you can manipulate any entity in your app. For example, let's load our saved entity:
savedPhotoswill be an array of Photo objects with the data loaded from the database.
EntityManager. Each entity has its own repository which handles all operations with its entity. When you deal with entities a lot, Repositories are more convenient to use than EntityManagers:
id = 1will be updated in the database.
id = 1will be removed from the database.
PhotoMetadata.ts. This PhotoMetadata class is supposed to contain our photo's additional meta-information:
@OneToOne. It allows us to create a one-to-one relationship between two entities.
type => Photois a function that returns the class of the entity with which we want to make our relationship. We are forced to use a function that returns a class, instead of using the class directly, because of the language specifics. We can also write it as
() => Photo, but we use
type => Photoas a convention to increase code readability. The type variable itself does not contain anything.
@JoinColumndecorator, which indicates that this side of the relationship will own the relationship. Relations can be unidirectional or bidirectional. Only one side of relational can be owning. Using
@JoinColumndecorator is required on the owner side of the relationship.
photo => photo.metadatais a function that returns the name of the inverse side of the relation. Here we show that the metadata property of the Photo class is where we store PhotoMetadata in the Photo class. Instead of passing a function that returns a property of the photo, you could alternatively simply pass a string to
"metadata". But we used this function-typed approach to make our refactoring easier.
@JoinColumndecorator only on one side of a relation. Whichever side you put this decorator on will be the owning side of the relationship. The owning side of a relationship contains a column with a foreign key in the database.
find*methods or using
QueryBuilderfunctionality. Let's use
find*methods allow you to specify an object with the
QueryBuilderallows more complex queries to be used in an elegant way:
QueryBuilderallows the creation and execution of SQL queries of almost any complexity. When you work with
QueryBuilder, think like you are creating an SQL query. In this example, "photo" and "metadata" are aliases applied to selected photos. You use aliases to access columns and properties of the selected data.
@OneToOnedecorator a bit:
cascadeallows us not to separately save photo and separately save metadata objects now. Now we can simply save a photo object, and the metadata object will be saved automatically because of cascade options.
metadataproperty, instead of the metadata's
photoproperty as before. The
cascadefeature only works if you connect the photo to its metadata from the photo's side. If you set the metadata's side, the metadata would not be saved automatically.
Authorcontains an inverse side of a relation.
OneToManyis always an inverse side of the relation, and it can't exist without
ManyToOneon the other side of the relation.
@ManyToOnewill store the id of the related object.
phototable, adding a new
authorcolumn and creating a foreign key for it: