Welcome back.
And this video, we are going to set up the Dow interface and the database class.
Therefore, let's start by creating the Dow interface.
The Dow interface is basically an interface file that we need to create in our project that has the
Dow keyword annotated to it.
So let's go ahead and add it to our project by simply creating a new.
Scotland file class and here select interface, call it employee doll.
And Dull stands for data annotation.
And Dow is short for data access object, so your Dow must be an interface, and it should be annotated
with the Dow keyword, so at Dow here.
Again, this is from Android X Room, so you need to import that as well for it to be usable inside
of the Dow.
We now define the functions in it to be used for querying the database.
There are available annotations already simplified for frequent operations, which we're going to use.
So let's get started with the first one.
The first one will be if we want to store data, we need to use to it.
Insert keyword and here with a capital high at insert from Android X Room.
And then we need to make it the suspend function using that code routine class, because this is an
operation that will take quite some time for relatively speaking, will take some time.
And this mustn't be done on the main threat.
It has to be done on a background threat, which is achievable by using call routines.
OK, so suspend fund insert is how I'm going to call this function and what it will do is it will store
an employee entity in our database.
So now we need to do the same thing with an update function.
So here update from Rome as well.
This will also be a suspend function, and I'm going to call this one update.
And what should it update?
Well, an employee entry.
So employee entity, then the next thing needs to be done with the delete function as well.
So we now know how to insert, how to update.
Now, let's delete.
And this will also be a suspend function I'm going to call delete and we need to pass the employee entity
that we want to delete.
So this will permanently delete the entry from our database.
So now we need to have a function to retrieve their employees.
And there are two different ways.
One of them is to retrieve all employees that we have in our database, and the other one is to only
get a particular one where we have the ID that we want to delete.
So let's go ahead and use that query keyboard here.
Does this also from Android X Room another annotation?
And you see, at this point, it just imports the room namespace entirety.
So here for the query in brackets, you can define what the query should be.
And here you can enter sequel code.
So something like select star from and then the table that you want to use.
So in our case, this would be, for example, the employee table.
You need to use these quotation parentheses here, and you see that the idea is so Android Studio directly
gave me the table that it defines.
So it found our employee entity table, which was this employee table.
Now we, of course, need to create function, and this will not be a suspend function, even though
it will also be a function that will run in the background.
So I'm going to call this one fetch all amplio.
Yes.
OK, like so and this will return a flow, and it's going to be.
This one here.
So the flow from coal routine is not the Java util or anything like that, you see there are a bunch
of different flows.
But we're talking about this flow interface and it will be a list of employee entities that we are going
to get.
Mike, so.
And now you might wonder, what the heck is this flow?
Well, a flow is part of the chorus in class used to hold values that can always change at runtime.
That's because it automatically emits value more like a life update.
With Flow, all you need is to collect the value from the variable or method without needing to always
repeat codes to update the user interface.
The collect method keeps emitting data as it changes.
And that's really, really cool because otherwise you would always have to notify your recycler view
that data has changed and all that kind of stuff.
Now you don't have to do that.
The flow takes care of that.
There are other ways or methods you can use to listen to a flow depending on your needs.
For example, collect latest just like the name would make you expected, it returns the lost value
from an update and forgets the previous ones.
Then, with collected indexed, you can get an index of an element with its value.
With combined, you can transform flows and return its values automatically when they change.
There's a lot that flow can do in our code with so many utility methods, but these are the basics that
we need to get started using it.
So this will select start, which means all entries from this table.
And then this is the function that we need to call in order to get all the entries, and it will return
a flow which is part of the origin class.
Just like the suspense keyword, it runs the operation on a different thread, but with an additional
feature of omitting updates automatically when they occur.
And then we have final one, which will be getting us a specific entry so we can also use this query,
and I'm going to call this function for each employee by ID.
OK, and I need to pass the ID that I want to specifically fetch and I'm going to select start from.
And here I need to define where the idea is equal to our ID.
And that's how you can achieve that.
OK, so it's going to be equal to this ID we are passing.
So basically, this will allow us to get an individual employee by the uniquely identifiable ID.
So basically, the role where the idea column fits with the idea that we passed to the function call
and it also returns a flow.
But this time not a list of employee entity, but an individual employee entity object.
So just one role.
That's the idea behind this employee by I.T..
Because for any given ID, there is only one entry.
OK, so now we need to create a database, and that means an abstract class of tap room database.
So let's go ahead and do that.
And is there an abstract class?
Doesn't seem like it.
I'm just going to use class here.
I'm going to call this one employee data base like so.
OK, so this will be an abstract class that will inherit from the room database class here.
So room database this one here from Katie.
OK, and what you need to define here is some additional information about this database.
So you need to define the version and two entities that you want to use.
So here you add to that database annotation and you need to import that database.
You see, it's this one here, and then you can enter two entities that you want to use.
So this can be an array.
In our case, it will just be one entry and that is going to be our employee entity, which is a class.
So we need to add, call and call and class and the version name.
So let's say this is version one of our database.
If we were to update our database, meaning, for example, we change the amount of properties that
we have in the table, then we have to change the version and then we would have to go into data migration,
which would make it super difficult in some cases, because let's say you need the new property in your
project for it to work, but you don't have it for most uses, then you would have to alter, generate
it and so forth.
So this would go too far from this video.
So for our purposes, we are just going to dump the entire database and restart it, so to speak.
OK, so whenever we make changes, we're going to delete it and then start from scratch, which is not
something you can do with an existing database.
OK, so just so you know, you can of course, do it, but you shouldn't.
All right.
So now we need to connect the database to our DAO.
So let's create an abstract function called employee DAO.
And this will return our employee DAO.
So this and pretty dull class that we created this interface better set.
It's not really a class.
So then we need to define a companion object, which allows us to add functions on the employee database
class, for example, classes can call employee database, get instance context to instantiate a new
employee database.
So let's create a companion object here.
And here I am going to create a private, for instance.
Which will keep an employee database instance, and this will be no by default, and we're going to
set it later.
So this will keep a reference to any database returned via get instance.
This will help us to avoid repeatedly initializing the database, which is expensive in terms of performance.
The value of a volatile variable will never be cached, and all rights and rights will be done to and
from the main memory.
It means the changes made by one thread to share data are visible to other threads also, and we need
to add the add volatile keyword here.
So this will be a volatile variable.
Then we need to have a helper function to get the database.
So if a database has already been retrieved, the previous database will be returned.
Otherwise, we're going to create a new database.
This function is going to be thread safe, and college should cache the results for multiple database
calls to avoid overhead.
This is an example of a simple singleton pattern that takes another singleton as an argument in Scotland.
So if you want to learn more about singletons, I would recommend for you to check out the Wikipedia
page.
So the singleton pattern is a software design pattern that restricts the instantiation of a class to
one single instance.
This is useful when exactly one object is needed to coordinate actions across the system, so you don't
want to have multiple different instances of the same object.
Therefore, you used a singleton pattern where if the object already exists, delete the object and
create a new instance of the object or skip the creation of the object if you have the object already.
So there are different ways of handling this.
So what we're going to do here is we're going to create get instance with the context.
Well, we need to pass the context, right?
And let's import context here with the employee database.
So it's going to return an employee database.
And here we need to synchronize it.
So we used a synchronized method.
We need to pass the lock to it, which will be this and then we can execute some code.
So here, multiple threads can ask for the database at the same time and to ensure we only initialize
at once.
By using this synchronized function, only one thread may enter a synchronized block at a time.
OK, so that's why we're using it.
So now we need to copy the current value of instance, to a local variable.
So Kotlin can SmartCast, so SmartCast is only available to local variables.
Therefore, let's create a local variable called instance, which will be our instance that we have
created here.
Our NPG database object.
And then we're checking if instance is null.
So at the beginning, it is null.
But then if it was created before, it will not be null anymore.
So if it is, now, let's create a new entry.
So we're saying instance is room dot database builder.
So we're building the database with the context and we're going to use the application context.
Therefore, then we need to pass the amperage database.
So I believe that their base class, the Java, and then we need to say which database we want to use,
and we called our database employee database.
OK, so this will be the database name.
And now.
Let's call fallback to destructive migration and then build it.
Like so so what's going to happen here is that it wipes and rebuilds instead of migrating if no migration
object exists.
So migration is not part of this lesson, as I said.
So if you want to know more about migrations, check out this article.
Understanding migrations with room from Android developers on their medium that come so quite advanced
topic and Florina Montanez Google has written an article here.
I would recommend for you to check it out if you want to know more about it.
So migrations, the idea behind that is really if you are making changes to your database, you will
need to migrate your old database to the new one or the old version to the new one.
So this would go too far for this course.
For now, at this point, we can assign the instance to our instance object.
So the instance that we just created will be assigned to our instance global object here.
And of course, our get instance method needs to get an instance.
So here we return the instance and let me see if I return it at the right spot.
I believe I have to go a little further in like so.
OK.
So that will be our employee data base class where we basically just returned the instance of our database.
I have talked a lot about some details and have gone into a lot more detail than necessary, I believe.
But this will give you maybe a little bit of a better idea.
What's going on at the same time might confuse you a little more if you just want to be able to use
it, just follow along.
If you want to dig deeper into it, we'll definitely have to check out the documentation for it.
But for just using the room database with its basic functionalities, what you're going to learn is
going to suffice.
So let's go over to the next video where we're going to finalize this project.
And then finally, we'll be able to store data and delete data and update data in our school data.