crud is not enough
In the previous study, the use of common Warehouse interface Genericrepository, and through the genericbaserepository,genericjparepository to implement, implementation for CRUD, this kind of implementation is very similar, in addition, We also need to be based on the unique key or key to query, not only using primary key, but also based on a number of conditions to query or retrieve, the results of the return page and so on. Genericrepository provides a basic crud that is not sufficient.
The implementation of these interfaces is rather cumbersome, and we take pagination as an example. If we need to get the number of pages, we need to get the total, the code is as follows:
@PersistenceContext private Entitymanager Entitymanager; @Override Public Long count (predicate ... restrictions) {Criteriabuilder builder = This.entityManager.getCriteriaBuilde
R ();
criteriaquery<long> Countcriteria = Builder.createquery (Long.class);
root<testpage> root = Countcriteria.from (Testpage.class); typedquery<long> countquery = This.entityManager.createQuery (Countcriteria.select (Builder.count (Root)). whe
Re (restrictions));
return Countquery.getsingleresult (); @Override Public list<testpage> page (int page, int numperpage, predicate ... restrictions) {Criteriabuilder Bui
Lder = This.entityManager.getCriteriaBuilder ();
criteriaquery<testpage> criteria = Builder.createquery (Testpage.class);
root<testpage> root = Criteria.from (Testpage.class); typedquery<testpage> pagedquery = This.entityManager.createQuery (Criteria.select (Root). by (BUILDER.ASC
(Root.get ("UserName"))
. where (restrictions)); "Note" sEtfristresult:position of the first result, numbered from 0, this auto-assigned ID number is not the same as starting at 1 return Pagedquery.setfirstresult ((page-1)
*numperpage). Setmaxresults (Numperpage). Getresultlist (); }
We can add these two methods to the genericjparepository, but when we get the paging information, we may specify some sort or some sorts, or we can filter, that is, where in the example (restrictions), This causes the caller to fall into JPA code and, if materialized according to the specific scenario, may need to add code to many entity warehouses and not be universal. the role of Spring data
The warehouse code does not contain any business logic (in service), nor does it contain a UI (in controller), which is a generic boilerplate code. Spring data is a project that is independent of the spring framework. The programmer simply defines the interface, and Spring data can dynamically generate the required warehouse code when runtime.
Spring data supports jpa,jdbctemplate,nosql and so on, all of which are spring data Commons, and we can just select the part that implements JAP, the spring data JPA. Simple Small Example the introduction of Pom
<!-- in our small experiment, SPRING-DATA-JPA could not use the 2 version, injected abnormal-->
<dependency>
<groupId> org.springframework.data</groupid>
<artifactId>spring-data-jpa</artifactId>
< Version>1.11.10.release<version>
</dependency>
If we want to use the version of Spring Data JPA 2 (for example, 2.0.5.RELEASE), we need to upgrade the spring framework to 5.x, and the Spring Framework 5.x requires Javax.servlet to be 4.0. Configure spring data in context
Just add @enablejparepositories
@EnableJpaRepositories ("cn.wei.flowingflying.chapter22.site.repositories")/* If we do not use the default method name in Entitymanagerfactory and TransactionManager, we need to specify that the * @EnableJpaRepositories (basepackages = " Cn.wei.flowingflying.chapter22.site.repositories "* entitymanagerfactoryref =" Entitymanagerfacto Rybean ",//defaults to Entitymanagerfactory * transactionmanagerref =" Jpatransactionmanager ")//default to Trans ActionManager */@ComponentScan (basepackages = "Cn.wei.flowingflying.chapter22.site", excludefilters = @Componen Tscan.filter ({controller.class, controlleradvice.class})) public class Rootcontextconfiguration implements Asyncconfigurer, schedulingconfigurer{... @Bean public Localcontainerentitymanagerfactorybean Entitymanag
Erfactory () throws propertyvetoexception{map<string, object> properties = new hashtable<> ();
Properties.put ("Javax.persistence.schema-generation.database.action", "none"); Properties.pUT ("Hibernate.show_sql", "true");
Properties.put ("Hibernate.dialect", "Org.hibernate.dialect.MySQL5InnoDBDialect");
Localcontainerentitymanagerfactorybean factory = new Localcontainerentitymanagerfactorybean ();
Factory.setjpavendoradapter (New Hibernatejpavendoradapter ());
Factory.setdatasource (This.springjpadatasource ());
Factory.setpackagestoscan ("cn.wei.flowingflying.chapter22.site.entity");
Factory.setsharedcachemode (sharedcachemode.enable_selective);
Factory.setvalidationmode (Validationmode.none);
Factory.setjpapropertymap (properties);
return factory; @Bean public Platformtransactionmanager TransactionManager () throws propertyvetoexception{return new
Jpatransactionmanager (This.entitymanagerfactory (). GetObject ()); }
}
Warehouse Interface
Since spring data can generate code for us automatically, how to write the warehouse interface becomes critical. Org.springframework.data.repository.repository<t, ID extends serializable> is the most basic interface in spring data, and there is no way All other interfaces inherit it. T is the entity class, and the ID is the type of the primary key.
/* Crudrepository is the interface that spring data provides to add, delete, and check the warehouse interface, we simply inherit it, it will provide the following interface
*➤count () return long, that is total number
*➤delete (T) , delete (id), delete (iterable<? extends T>), DeleteAll ()
*➤exists (ID) query ID exists, return boolean
*➤findall (), FindAll (iterable<id>), both return iterable<t>
*➤findone (ID)
*➤save (s), where S is the inheritance of T, which may execute the INSERT, It is also possible to perform an update operation, returning S (if it is insert, from which we can get the automatically assigned ID)
*➤save (iterable<s>), returning iterable<s>
Public
Interface Authorrepository extends crudrepository<author,long>{
}
If we need to sort or page, we will inherit Org.springframework.data.repository.pagingandsortingrepository<t, ID extendsserializable> , provides:
@Service public class Defaultbookmanager implements Bookmanager {@Inject authorrepository
Authorrepository; @Override @Transactional public list<author> getauthors () {//Return This.tolist (Authorrepository.getall ());
Before the Code return This.tolist (Authorrepository.findall ()); @Override @Transactional public void Saveauthor (Author Author) {/* Previous code if (Author.getid () < 1) This.aut
Horrepository.add (author); else This.authorRepository.update (author);
* * This.authorRepository.save (author);
}/* "Problem" Why the warehouse returns a iterable<e> we want to convert to collection, such as list.
* In the native JDBC town of Nan Guan, the bustling is resultset, is iterable, which allows us to execute statements while continuing to read information from the database.
* In the transaction method, we have commit the transaction, close the ResultSet, convert to the list such collection, make sure that all the data is read before the end of the transaction.
* Private <E> list<e> tolist (iterable<e> i) {list<e> List = new arraylist<> ();
I.foreach (List::add);
return list; }
... ...
}
FindAll (Sort) findall (pageable)
using the Warehouse interface
@Service public
class Defaultbookmanager implements Bookmanager {
@Inject authorrepository authorrepository;
@Override
@Transactional public
list<author> getauthors () {
//return this.tolist ( Authorrepository.getall ()); Previous code return
this.tolist (Authorrepository.findall ());
}
@Override
@Transactional public
void Saveauthor (Author Author) {/
* Previous Code
if (author.getid () < 1)
This.authorRepository.add (author);
else
This.authorRepository.update (author); */
This.authorRepository.save (author);
}
/* "Problem" why the warehouse return is a iterable<e>, we want to convert to collection, such as list.
* In the native JDBC town of Nan Guan, the bustling is resultset, is iterable, which allows us to execute statements while continuing to read information from the database.
* In the transaction method, we have commit the transaction, close the ResultSet, convert to the list such collection, make sure that all the data is read before the end of the transaction.
*
Private <E> list<e> tolist (iterable<e> i) {
list<e> List = new arraylist< > ();
I.foreach (list::add);
return list;
}
... ...
}
RELATED links: My professional Java for WEB applications related articles