[MUSIC] In the past example that we used, our implementation in the video repository was always in memory. It was always backed up by some simple Java data structure. But what if we wanted to store our videos in an actual database? So what if we wanted our video repository to provide an interface to a database, such as MongoDB or something else. So that we could save data into it. Or maybe we want to connect up to a MySQL database. Well if we use JPA, we can actually very easily convert our video repository into an interface that Spring will automatically provide an implementation for to connect to our database and save our video objects into a database. So let's take a look at some code that will do this. First we need to go and look at our video object. If we're going to begin storing videos in a database, we're going to have to do a little bit of work to use JPA with our video object. The first one is, is that we need to tell JPA that this is an object that we expect to be stored in a database, and the way that we do that is by adding an at entity annotation to the top of the class. So as we'll see here, this @entity annotation has been added to to the video class, signaling to JPA that this is something to store in a database. The next thing that we need to do, is because we're going to be storing these objects, we need a way of uniquely identifying each object. And we do that by adding an @ID annotation to the property in the video that we want to make unique. And to be the unique identifier to a video. So in this case, all we've done is added a simple long ID member variable to our video. So each video can be assigned a unique number that we can refer to it by, and if we want to go and look it up in the database, we can specify a particular ID. That we want JPA to go and get the video associated with. Now, one trick here is that, how do we make sure that our IDs are always unique? How when we store a new video, do we make sure that it has a unique ID? Now we could certainly keep track of this ourselves. And try to remember what our last ID was and automatically assign a new ID. But luckily, we don't actually have to do that. JPA can automatically, if we tell it to, generate unique IDs for each of our object instances that we store. So, in this example here, we're adding the @ Generated Value. Strategy=GenerationType.auto, and that's telling JPA every time we store a video for the first time in the repository, we want you to automatically assign a value to its ID, so that it's unique. So JPA is taking care of automatically making sure that our video ID is unique for each individual instance. The other thing is, all of the rest of the class is exactly the same as it was before. We have member variables and getters and setters. Everything else is the same. All of the logic is the same. But adding these simple annotations of @entity and then ID that's auto generated, this is enough to tell JPA what it needs to know in order to store our video in a variety of different types of databases. Now, this is the first piece which is to tell JPA about our entities, or the objects that we want to store. The second piece, is to provide, the information that Spring Data JPA needs to figure out how to automatically provide this storage logic for us. So, if you went and actually wrote code, to use JPA, you would see that you are writing similar code over and over. Just like we had when we're receiving HTTP, requests there's boiler plate code. When you're going to use JPA to store data in a database you're going to end up writing a very similar code over and over to be able to save objects, to be able to update the existing objects in the database, to be able to delete them or to search for them. So Spring Data actually takes all of this boiler plate code, and it automatically generates it for you if you tell it to. So, in this case, the way that we get Spring Data to automatically generate the code that we need to create, read, update, and delete the video objects that we want to store. Is we take our video repository and we add the @repository annotation to it. And then the second thing we do is we make sure that the repository interface extends the crud repository interface, provided by J, not by JPA but by Spring Data JPA. And what this does, is this crud repository specifies a variety of default methods like, Save to save an object. Find a particular object by its ID. Checking if an object exists. Getting all of a particular type of object that we've saved. Or deleting or counting the objects that we previously saved. So the crud repository is a super interface that we inherit from that provides a lot of the default functionality. And all we have to do is parameterize it by the type of object we're going to store. So the first thing here in the crud repository parameterization, is the type of object we're going to store, which is a video. And then the type of ID that videos have. In this case, if we go back and look at our video, we see that their ID is a long. So when we were parameterize it, we parameterize the crud repository with a long. So what this is saying is, this video repository is a JPA repository that Spring is going to create that will store videos and where each video has a unique long that is its identifier. And automatically because we inherit or extend this super interface, crud repository, we're going to get methods to save, find an existing object, find all existing objects, delete objects, or even go and query objects for, that meet a specific criteria. So in order to tell Spring to go and instantiate a implementation of this interface that automatically provides the logic that we need, we go, and in our Application class, all we have to do is add one new annotation, and that is EnableJPARepositories. And we're going to tell it where we want it to go and find those repository interfaces that it should provide implementations for. In this case we're saying, go and look at the package associated with the video repository class, and any classes that are in the video repository classes parent package, you should automatically go and create implementations of them. So, if we go here we're going to have this simple interface and it's going to dynamically allow us to create implementations of this interface that we can use. So, if we go back to our video service. We're still at auto wiring. And having Spring inject the implementation of our video repository into this controller. But one of the things you'll notice is that if we go back to the application, we are no longer providing the actual implementation. Instead, because we've added this enableJPArepositories, Spring is going to automatically dynamically create an implementation of that repository that provides all of the functionality we need to save video objects into a database. And then once it's created it, it's going to automatically go and inject it or auto-wire it into our video repository users. So all of the places that we are, at auto-wiring a video repository, Spring will take the JPA video repository implementation that it dynamically generates and attach it to all of the right locations. And then if we go and look down, we'll see that even though we didn't directly define it, we now have a method to save videos, we have a method to find all the videos that have been saved in the database, or we can even go and search for particular videos. Now, all of this is being provided for us, we don't actually have to provide an implementation of the repository. All we have to do is define the interface that we are expecting for the dynamically generated implementation. Spring is literally going and looking at this interface and saying, what database is currently configured and attached, and then automatically figuring out how to implement a version of this interface that can talk to that database and save video objects into it, and automatically translate them into the appropriate tables in the database. The other interesting thing that we've done is we've defined a custom method here in this video repository that's FindByName. And what this method is is it's defining a new way of querying for videos. We want to find all videos where the name parameter of the video, the member variable name of the video, matches a particular value that's provided in, in the, by the caller. There is a naming convention that Spring allows you to use. So any methods on your video repository that are find by and then the name of a member variable, Spring will automatically generate a method that generates the appropriate query in the database. To find all objects with the member variable of, in this case, name, that matches the value. And there's a whole specification for how you can name methods and annotate them to generate complex queries on your database. In this case, we're just using a very simple example, FindByName. But we could also go and add methods for other things like, if we wanted to find all videos by duration, we could say, findByDuration, and provide a value for the duration that we're want, videos that are exactly this long. And Spring data would automatically go and generate an implementation and an appropriate query to find all of the video objects that we had stored with that duration. Now this is all almost pure magic when you look at it. We're not actually providing any of the logic, and it's quite complex logic to go and interact with the database. All we're telling Spring is, here is an interface that we would like to have an implementation for, to store videos, to search for them, to delete them. Go and automatically produce an implementation for us. And Spring can figure out, based on our annotations, how to create an implementation of thisr repository that can do all of the things that we need it to do. So this vastly simplifies our work for creating data driven applications that are connected to a database