Java for Web Learning Notes (103): Using JPA (3) JPA warehouses in the spring framework __java

Source: Internet
Author: User
Tags iterable
Small Example

We use a database of previous JPA small examples, with three tables Authors,books and publishers. First on the table author data reading and writing, read and write is nothing but to change the check, that is, crud. Before, we have done entity and database table corresponding, here skip. Creating warehouse Interfaces

Public interface Authorrepository {
	iterable<author> getAll ();
	Author get (long id);
	void Add (Author Author);
	void Update (Author Author);
	void Delete (Author Author);
	void Delete (long id);

implementation of warehouse interface

@Repository public class Defaultauthorrepository implements authorrepository{//"Attention" The previous study learned that: Entitymanager do not use @inject or @autowire,
	Instead, it uses @persistencecontext to obtain the Entitymanager object that is unique within the same transaction from proxy (Sharedentitymanagerbean).

	@PersistenceContext Entitymanager Entitymanager; The/* example uses the Java Persistence Query Language (JPQL). Instead of using the table name (which has been mapped), JPQL uses the class name */@Override public iterable<author> GetAll () {return this.entityManager.createQuery (
	"Select a from Author a" a.name ", Author.class). Getresultlist (); @Override public Author get (long id) {return this.entityManager.createQuery (' Select a from Author a WHERE a.id =:
	ID ", Author.class). Setparameter (" id ", id). Getsingleresult ();		
	@Override public void Add (Author Author) {this.entityManager.persist (Author);		
	@Override public void Update (Author Author) {this.entityManager.merge (Author); @Override public void Delete (Author authOR) {This.entityManager.remove (author);
		                  @Override public void Delete (long id) {this.entityManager.createQuery (' delete from Author a WHERE a.id =: id ')		
	. Setparameter ("id", id). executeupdate (); }
}
Common code for CRUD

Additions and deletions is the most basic data access, we want to implement this operation for each table, the code is similar, just map to different objects, the following describes the common code. generic interface definition: Genericrepository I is the type of index, E is the type of entity.

@Validated public
Interface Genericrepository<i extends Serializable, E extends serializable> {
	@NotNull Iterable<e> getAll ();	
	E Get (@NotNull I ID);
	void Add (@NotNull E entity);
	void Update (@NotNull E entity);
	void Delete (@NotNull E entity);
	void Deletebyid (@NotNull I ID); Cannot distinguish E and I, so a different method name is required
Accordingly, the warehouse interface can be written as:
Public interface Bookrepository extends Genericrepository<long, book>{book
	getbyisbn (@NotNull String ISBN) ; Add additional Interfaces
} public

Interface Publisherrepository extends Genericrepository<long, publisher>{}//No increase

get Types I and e:genericbaserepository we need to get the correct long,book type from Bookrepository<long, book>. The following are the relevant code:

/* Here is a general approach, we do not specifically implement JPA, because it is possible to NON-JPA warehouse.
 For JPA, further use of genericjparepository to inherit. * Abstract indicates that the implementation of this interface cannot be used. * * Public abstract class Genericbaserepository<i extends Serializable, E extends serializable> implements
	pository<i,e>{protected final class<i> idclass;
	
	Protected final class<e> Entityclass; @SuppressWarnings ({"Unchecked", "rawtypes"}) public genericbaserepository () {* * is intended to pass ((Parameterizedtype) THIS.GETCL Ass (). Getgenericsuperclass ()). Getactualtypearguments () to obtain the specific types of I and E in <I,E>. Since this genericbaserepository is inherited, it may be inherited several times, so it is necessary to find the class with the specific parameterizedtype in the Super class all the way up. In the code we've been looking up to specify the type of argument.
                 It's clear that when you find Genericbaserepository, you fail, and you don't have to go up. * Even if we use only one integration and make sure so, we cannot use it directly ((Parameterizedtype) This.getclass (). Getgenericsuperclass ()). Getactualtypearguments () Because inheritance is also possible for the transaction proxying and exception translation in the spring framework, it can be an error to get the type directly, so you need to take a retrospective approach.
		*/Type Genericsuperclass = This.getclass (). Getgenericsuperclass (); while (!) ( GenericsuperclaSS instanceof Parameterizedtype)) {if (!) ( Genericsuperclass instanceof Class)) throw new IllegalStateException ("Unable to determine type arguments" + "is
			Cause generic superclass neither parameterized type nor class. ");
						if (Genericsuperclass = = genericbaserepository.class) throw new IllegalStateException ("Unable to determine type" +
			"Arguments because no parameterized generic superclass found");
		Genericsuperclass = ((Class) genericsuperclass). Getgenericsuperclass ();
		} parameterizedtype type = (Parameterizedtype) genericsuperclass;
		type[] arguments = type.getactualtypearguments ();
		This.idclass = (class<i>) arguments[0];
	This.entityclass = (class<e>) arguments[1]; }
}
Common JPA implementations: Genericjparepository
Public abstract class Genericjparepository<i extends Serializable, E extends serializable> extends

	Genericbaserepository<i, e>{@PersistenceContext protected Entitymanager Entitymanager; "Note" Query.from (this.entityclass) corresponds to SQL is a table, because there is no explicit class name, you cannot use the JPQL statement, but use the criteria API @Override public @NotNull
		Iterable<e> GetAll () {Criteriabuilder builder = This.entityManager.getCriteriaBuilder ();
		criteriaquery<e> query = Builder.createquery (This.entityclass); Return This.entityManager.createQuery (Query.select (Query.from (This.entityclass)). Getresultlis		
	T ();
	@Override public E get (@NotNull I ID) {return this.entityManager.find (This.entityclass, id);		
	@Override public void Add (@NotNull E entity) {this.entityManager.persist (entity);		
	@Override public void Update (@NotNull E entity) {This.entityManager.merge (entity);		
@Override public void Delete (@NotNull E entity) {This.entityManager.remove (entity);	/* The attribute name here is ID (this is true for each class), and if not, Deletebyid (@NotNull I ID, String idname) is required. */@Override public void Deletebyid (@NotNull I id) {Criteriabuilder builder = This.entityManager.getCriteriaBuilder ()
		;
		criteriadelete<e> query = Builder.createcriteriadelete (This.entityclass);
		                  This.entityManager.createQuery (Query.where (Builder.equal (Query.from (This.entityclass). Get ("id"), id))			
	. executeupdate (); }
}
The final Deletebyid is equivalent to

Criteriabuilder builder = This.entityManager.getCriteriaBuilder ();
criteriadelete<e> query = Builder.createcriteriadelete (this.entityclass);
root<e> root = Query.from (this.entityclass);           Read Entityclass corresponding table
query.where (builder.equal ("id"), id);        The condition of the read,
this.entityManager.createQuery (query). executeupdate ();//Because query is createcriteriadelete, execution is delete
Let's look at the example of the criteria API: Ask for ascending order by name corresponding column, and get all the books, the code reads as follows:

...
root<book> root = Query.from (book.class);
Return This.entityManager.createQuery (Query.select (Root). by (Builder.asc (Root.get ("name")))
                         . Getresultlist ();

The implementation of the specific warehouse has a common implementation, the specific implementation can greatly simplify the code

@Repository public
class Defaultbookrepository extends Genericjparepository<long, book> implements bookrepository{
    @Override Public book
    GETBYISBN (String ISBN) {
        Criteriabuilder builder = This.entityManager.getCriteriaBuilder ();
        criteriaquery<book> query = Builder.createquery (this.entityclass);
        root<book> root = Query.from (this.entityclass);
        Return This.entityManager.createQuery (Query.select (Root). where (Builder.equal (Root.get ("ISBN"), ISBN))
                                 . Getsingleresult ();
    }

@Repository public
class Defaultpublisherrepository extends Genericjparepository<long, publisher> Implements publisherrepository{
}

RELATED links: My professional Java for WEB applications related articles

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.