Chapter One: Spring Data JPA What is spring data is an open-source framework for simplifying database access and supporting cloud services. Its main goal is to make access to data easy and fast, and to support map-reduce framework and cloud computing data Services. Spring Data contains multiple sub-projects: Commons-Provides a shared infrastructure for use by individual sub-projects, supports cross-database persistence JPA-simplifies the creation of JPA data access tiers and persistent layer capabilities across storage Hadoop-Spring-based Hadoop job configuration and A POJO programming model of the MapReduce job Key-value-integrates Redis and Riak to provide a simple package document in several common scenarios-integrated documentation database: CouchDB and MongoDB and provides basic configuration mappings and repositories Support Graph-Integrated neo4j provides a powerful POJO-based programming model graph Roo Addon-roo support for NEO4JJDBC Extensions-supports Oracle RAD, advanced queuing, and advanced data type map Ping-provides object mapping framework based on Grails, supports different database examples-sample programs, documents and graphs database guidance-Advanced documentation Spring Data What is JPA? A framework for simplifying JPA development provided by spring nspring data JPA can do much to simplify the JPA notation, enabling access and manipulation of the information in almost no-write implementations. In addition to CRUD, it also includes some common functions such as paging, sorting, and so on. What spring data JPA has to look at is the interface provided by spring data JPA and is the core concept of spring data JPA: 1:repository: The topmost interface is an empty interface, The purpose is to unify the types of all repository and to automatically identify the components when they are scanned. 2:crudrepository: is a repository sub-interface that provides CRUD functionality 3:pagingandsortingrepository: is a crudrepository sub-interface, Add pagination and Sorting features 4:jparepository: is the Pagingandsortingrepository sub-interface, added some useful functions, such as: batch operation. 5:jpaspecifIcationexecutor: The interface used to do the query 6:specification: A query specification provided by Spring Data JPA, to make complex queries, simply set the query criteria around this specification to The HELLOWORLDN environment builds a common Java project in eclipse, mainly to add a bunch of jar packages. 1: First download Spring data Common and spring data JPA packages to the website and add the Dist jar package to the project. Here is Spring-data-commons-1.5.0.release.jar and spring-data-jpa-1.3.2.release.jar2: Add Spring3.2.3 jar package to the project 3:JPA implementation is chosen Hibernate4 .2.0, a total of the following additional Jar:antlr-2.7.7.jar, Aopalliance-1.0.jar, Asm-3.2.jar, Aspectjrt-1.7.1.jar, Aspectjweaver-1.7.1.jar, Commons-beanutils-1.8.3.jar, Commons-codec-1.7.jar, Commons-collections-3.2.1.jar, Commons-dbcp-1.4.jar, Commons-fileupload-1.2.2.jar, Commons-io-2.4.jar, Commons-lang3-3.1.jar, Commons-logging-1.1.1.jar, Commons-pool-1.6.jar, Dom4j-1.6.1.jar, Hibernate-commons-annotations-4.0.1.final.jar, Hibernate-core-4.2.0.final.jar, Hibernate-entitymanager-4.2.0.final.jar, Hibernate-jpa-2.0-api-1.0.1.final.jar, Javassist-3.15.0-ga.jar, Jboss-logging-3.1.0.ga.jar, Jboss-transaction-api_1.1_spec-1.0.0.final.jar, Mysql-connector-java-5.1.9.jar, Slf4j-api-1.7.3.jarn entity object, is the previous implementation party@entity@table (name= "Tbl_user") public class Usermodel {@Idprivate an integer uuid;private String name;private integer Age ;//Omit Getter/setter}ndao Interface public interface Userrepository extends Jparepository<usermodel, integer>{//empty, You don't have to write anything.} No implementation is required, and Spring Data JPA will do everything for us. N writes a Service for the logic layer, which is actually equivalent to the DAO client, which is used to test the @service@transactionalpublic class client { @Autowiredprivate userrepository ur; public void Testadd (Usermodel um) {ur.save (UM), public static void main (string[] args) {ApplicationContext ctx = new Cla Sspathxmlapplicationcontext ("Applicationcontext.xml"); Client C = (client) Ctx.getbean ("Client"); Usermodel um = new Usermodel (); Um.setage (1); Um.setname ("Zhang San"); Um.setuuid (1); C.testadd (UM);} The}n also needs to be configured in the spring configuration file, similar to the configuration using annotations: <?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "/http Www.springframework.org/schema/beans "xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance "xmlns:context=" http ://www.springframework.org/schema/context "xmlns:aop=" HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP "XMlns:tx= "Http://www.springframework.org/schema/tx" xmlns:jpa= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/DATA/JPA" xsi : schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ Spring-beans-3.0.xsdhttp://www.springframework.org/schema/context Http://www.springframework.org/schema/context /SPRING-CONTEXT-3.0.XSDHTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/ Spring-aop-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/ SPRING-TX-3.0.XSDHTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/DATA/JPA http://www.springframework.org/schema/data/jpa/ Spring-jpa.xsd "><context:component-scan base-package=" Cn.javass "><context:exclude-filter type=" Annotation "expression=" Org.springframework.stereotype.Controller "/></CONTEXT:COMPONENT-SCAN><AOP: Aspectj-autoproxy proxy-target-class= "true"/><!--opening the annotation transaction is only valid for the current configuration file--><tx:annotation-driven Transaction-manager= "TransactionmaNager "proxy-target-class=" true "/> <jpa:repositories base-package=" Cn.javass "Repository-im pl-postfix= "Impl" entity-manager-factory-ref= "Entitymanagerfactory" transaction-manager-ref= "Transac Tionmanager "> </jpa:repositories> <bean id=" entitymanagerfactory "class=" Org.springframewor K.orm.jpa.localcontainerentitymanagerfactorybean "> <property name=" dataSource "ref=" DataSource "/> & Lt;property name= "Packagestoscan" value= "Cn.javass"/> <property name= "Persistenceprovider" > < ; Bean class= "org.hibernate.ejb.HibernatePersistence"/> </property> <property name= "Jpavendoradap ter "> <bean class=" org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter "> <p Roperty name= "Generateddl" value= "false"/> <property name= "database" value= "MYSQL"/> <property name= "datAbaseplatform "value=" Org.hibernate.dialect.MySQL5InnoDBDialect "/> <property name=" Showsql "value=" tr UE "/> </bean> </property> <property name=" Jpadialect "> <bean C lass= "Org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> </property> <property name= "Jpap Ropertymap "> <map> <entry key=" Hibernate.query.substitutions "value=" True 1, False 0 "/> <entry key=" hibernate.default_batch_fetch_size "value="/> <entry key= "Hib Ernate.max_fetch_depth "value=" 2 "/> <entry key=" Hibernate.generate_statistics "value=" true "/> <entry key= "Hibernate.bytecode.use_reflection_optimizer" value= "true"/> <entry key= "Hib Ernate.cache.use_second_level_cache "value=" false "/> <entry key=" Hibernate.cache.use_query_cache "Val Ue= "false"/> </map> </property> </bean><!--transaction Manager configuration-<bean id= "TransactionManager" class= "O Rg.springframework.orm.jpa.JpaTransactionManager "> <property name=" entitymanagerfactory "ref=" Entitymanagerfactory "/> </bean> <bean name=" DataSource "class=" Org.apache.commons.dbcp.BasicDataSource "><property name=" Driverclassname "><value>org.gjt.mm.mysql.Driver</value></property> <property name= "url" ><value>jdbc:mysql://localhost:3306/cc?useunicode=true&characterencoding= Utf-8</value></property><property name= "username" > <value>root</value> </ Property><property name= "Password" value= "CC"/></bean></beans> configuration is complete, you can run the client test, Of course, the database and the table need to be prepared or can be added under <jpa:repositories> filter, such as: <repositories base-package= "Com.acme.repositories" ><context:exclude-filter type= "regex" expression= ". *somerepository"/></repositories> Chapter II: JPAREPOSitory basic function Jparepository The basic functions of the demonstration specific look at the code shows where: Pageable interface implementation class is the Pagerequest,page interface implementation class is Pageimpl. Example below:page<usermodel> p = ur.findall (new Pagerequest (0,2,new Sort (Direction. DESC, "uuid"))); System. Out.println ("list=" +p.getcontent ()); Chapter Three: Jparepository query directly in the interface to define the query method, if it is in line with the specification, can not write implementation, the currently supported keywords are as follows: Spring Data JPA Framework in the method name resolution, will first take the method name of the extra prefix interception, such as Find, FindBy, read, Readby, get, Getby, and then parse the rest of the sections. If you create the following query: Findbyuserdepuuid (), the framework when parsing the method, the first to remove the findBy, and then to parse the remaining attributes, assuming the query entity is DOC1: First Judge Userdepuuid (according to the POJO specification, The first letter to lowercase) is a property of the query entity and, if it is, a query based on that property, and if it does not, proceed to the second step; 2: The string that starts with the first capital letter from right to left is the UUID here), and then checks whether the remaining string is a property of the query entity, and if so, is a query based on the property, and if it does not, repeat the second step, continue from right to left, and finally assume that the user is a property of the query entity; 3: Then the remainder (DEPUUID) is processed to determine if the type of the user has a Depuuid attribute, and if so, This means that the method is ultimately queried according to the value of "Doc.user.depUuid", otherwise it continues to be intercepted from right to left according to the rules of Step 2, and ultimately indicates a query based on the value of "Doc.user.dep.uuid". 4: There may be a special case, such as doc contains a user attribute, there is also a USERDEP property, there is confusion. You can explicitly add "_" between attributes to explicitly express the intent, such as "Findbyuser_depuuid ()" or "Findbyuserdep_uuid ()" Special parameters: You can also add paging or sorting parameters directly to the parameters of the method, such as:page< UsermoDel> Findbyname (String name, pageable pageable); List<usermodel> Findbyname (String name, sort sort); JPA Namedqueries can also be used as follows: 1: Use @namedquery on an entity class, as shown in the following example: @NamedQuery (name = "Usermodel.findbyage", query = "Select O from Usermodel o where o.age >=? 1 ") 2: Define a method with the same name in the Repository interface of the DAO you implement, as shown in the following example: Public list<usermodel> findbyage (int Age); 3: Then it can be used, and spring will first find out if there is a namedquery with the same name, and if so, it will not be parsed according to the method defined by the interface. Using @Query, you can use @Query on a custom query method to specify the query statement that the method executes, such as: @Query ("Select O from Usermodel o where o.uuid=?1") public list< usermodel> findbyuuidorage (int uuid); Note: 1: The number of parameters of the method must be the same as the number of parameters required in @query 2: If it is like, the following parameters need to be preceded or followed by "%", For example: @Query ("Select O from Usermodel o where o.name like? 1%") Public list<usermodel> findbyuuidorage (String name) ; @Query ("Select O from Usermodel o where o.name like%?1") public list<usermodel> findbyuuidorage (String name); @Query ("Select O from Usermodel o where o.name like%?1%") public list<usermodel> findbyuuidorage (String name); Of course, this will not add '% ' when passing parameter values.And of course it's not wrong. N You can also use @Query to specify a local query, as long as you set Nativequery to True, such as: @Query (value= "select * from Tbl_user where name is like%?1", nativequery=true) public list<usermodel> findbyuuidorage (String name); Note: The current version of the local query does not support page flipping and dynamic sorting using the named parameters. Use @param, such as: @Query (value= "Select O from Usermodel o where o.name like%:nn") public list<usermodel> Findbyuuidorage (@Param ("nn") String name), and also support for updating the Query statement of the class, add @modifying, for example: @Modifying @query (value= "update Usermodel o set o.name=:newname where o.name like%:nn ") public int findbyuuidorage (@Param (" nn ") String name, @Param (" Newna Me ") String newName); Note: 1: The return value of the method should be int, indicating the number of rows affected by the UPDATE statement 2: The transaction must be added at the point where the call is made, no transaction does not function properly jparepository query creation order Spring Data When JPA creates a proxy object for an interface, what strategy does it take precedence if it finds that there are a number of these cases available at the same time? <jpa:repositories> provides the Query-lookup-strategy property to specify the order of lookups. It has the following three values: 1:create-if-not-found: If the method specifies a query statement through @query, the statement is used to implement the query, and if not, the lookup defines whether a named query that matches the criteria is defined, and if it is found, the named query is used; The query is created by parsing the method name. This is the default value for the Query-lookup-strategy property 2:create: Creates a query by parsing the method name. Even if a named query is compliant, or the method is passed @Query the specified query statement, it will be ignored 3:use-dEclared-query: If the method specifies a query statement through @query, the statement is used to implement the query, and if not, the lookup defines whether a named query that matches the criteria is defined and, if found, uses the named query; throws an exception if neither is found Fourth: Customized expansion jparepository If you do not want to expose so many ways, you can customize their own repository, but also in their own repository to add their own public methods of course more flexible is to write an implementation class, To achieve your own needs Method 1: Write a class with the same name as the interface, plus the suffix impl, which is configured in the previous XML, can be automatically scanned. This class does not need to implement any interfaces. 2: In the interface to add their own methods, such as: Public page<object[]> getbycondition (Userquerymodel u); 3: In the implementation class, to implement this method is good, will be automatically found Java code: view Copy to clipboard print public class Userrepositoryimpl {@PersistenceContext private entitymanager em; Public page<object[]> getbycondition (Userquerymodel u) {String hql = ' Select O.uuid,o.name from Usermodel o where 1 =1 and O.uuid=:uuid "; Query q = em.createquery (HQL); Q.setparameter ("UUID", U.getuuid ()); Q.setfirstresult (0); Q.setmaxresults (1); page<object[]> page = new pageimpl<object[]> (Q.getresultlist (), New Pagerequest (0,1), 3); return page; }} Fifth: Specifications query Spring Data JPA support JPA2.0 criteria query, the corresponding interface is JpaspecificationexEcutor. Criteria query: is a type-safe and more object-oriented query This interface is basically defined around the specification interface, and the specification interface only defines one of the following methods: Predicate Topredicate (Root <T> root, criteriaquery<?> query, Criteriabuilder CB); To understand this approach, and to use it correctly, you need to be familiar with and understand JPA2.0 's criteria query, because the parameters and return values of this method are the objects defined in the JPA standard. Criteria query basic concept criteria queries are based on the concept of a meta-model, which is defined for a managed entity of a specific persistence unit, which can be an entity class, an embedded class, or a mapped parent class. Criteriaquery interface: Represents a specific top-level query object that contains the various parts of the query, such as: Select, from, where, group BY, order By et Note: The Criteriaquery object only works on the criteria query for an entity type or an embedded type root interface: The root object that represents the criteria query, the query root of the criteria query defines the entity type, and the desired result is obtained for future navigation. It is similar to the FROM clause in SQL queries 1:root instances are typed and define the types that can occur in the FROM clause of a query. 2: The query root instance can be obtained by passing in an entity type to the Abstractquery.from method. 3:criteria queries, you can have multiple query roots. 4:abstractquery is the parent class of the Criteriaquery interface, which provides a way to get the root of the query. Criteriabuilder Interface: Builder object used to build Critiaquery predicate: a simple or complex predicate type, which is actually equivalent to a condition or a combination of conditions. Criteria query Base Object Build 1: Criteriabuilder Object 2 can be obtained by Entitymanager's Getcriteriabuilder or Entitymanagerfactory Getcriteriabuilder method: by adjusting Use Criteriabuilder's CreateQuery or Createtuplequery method to obtain an example of Criteriaquery 3: by calling the Criteriaquery from method toTo get the root instance Filter 1: The filter condition is applied to the FROM clause of the SQL statement. In the criteria query, the query condition is applied to the Criteriaquery object through a predicate or expression instance. 2: These conditions use the Criteriaquery. Where method is applied to the Criteriaquery object 3:criteriabuilder also as the factory of the predicate instance, by calling the Criteriabuilder conditional method ( Equal,notequal, GT, Ge,lt, le,between,like, etc.) create predicate objects. 4: Composite predicate statements can be constructed using Criteriabuilder's and, or Andnot methods. Build a simple predicate example: predicate p1=cb.like (Root.get ("name"). As (String.class), "%" +uqm.getname () + "%"); predicate p2=cb.equal (Root.get ("UUID"). As (Integer.class), Uqm.getuuid ()); predicate p3=cb.gt (Root.get ("age"). As (Integer.class), Uqm.getage ()); Build a combined predicate example: predicate p = Cb.and (P3,cb.or ( P1,P2)); Of course, it can be shaped like the previous dynamic stitching query statements, such as: Java code: View Copy to clipboard printing specification<usermodel> spec = new Specification<usermodel> ( {public predicate topredicate (root<usermodel> Root, criteriaquery<?> query, Criteriabuilder CB) { list<predicate> list = new arraylist<predicate> (); if (Um.getname ()!=null && um.getname (). Trim (). LengTh () >0) {List.add (Cb.like (Root.get ("name"). As (String.class), "%" +um.getname () + "%")); } if (Um.getuuid () >0) {List.add (Cb.equal (Root.get ("UUID"). As (Integer.class), Um.getuuid ())); } predicate[] P = new predicate[list.size ()]; Return Cb.and (List.toarray (p)); } }; You can also use Criteriaquery to come to the last predicate, as shown in the following example: Java code: View Copy to clipboard print specification<usermodel> spec = new specification <UserModel> () {public predicate topredicate (root<usermodel> Root, criteriaquery<?> qu ery, Criteriabuilder CB) {predicate p1 = Cb.like (root.get ("name"). As (String.class), "%" +um.getname () + "%"); predicate P2 = cb.equal (Root.get ("UUID"). As (Integer.class), Um.getuuid ()); predicate p3 = cb.gt (Root.get ("age"). As (Integer.class), Um.getage ()); Apply predicate to Criteriaquery, because you can also add other functions to criteriaquery, such as sorting, grouping what Query.where (Cb.and (p3,cb.or)); Add Sort function Query.orderby (cb.desC (Root.get ("UUID"). As (Integer.class))); return Query.getrestriction (); } }; Multiple table joins n multi-table connection query a little bit of a hassle, here's a demonstration of the common 1:m, incidentally 1:1n using the criteria query to implement 1-to-many queries 1: First to add a solid object Depmodel, and set a good usermodel and its 1-to-many relationship, As follows: @Entity @table (name= "Tbl_user") public class Usermodel {@Idprivate integer uuid;private String name;private integer Age; @OneToMany (Mappedby = "um", fetch = Fetchtype. LAZY, cascade = {Cascadetype. All}) Private set<depmodel> setdep;//omit Getter/setter} @Entity @table (name= "TBL_DEP") public class Depmodel {@ Idprivate Integer uuid;private String name, @ManyToOne () @JoinColumn (name = "USER_ID", Nullable = False)//indicates that there is a US in TBL_DEP er_id fields Private Usermodel um = new Usermodel ();//Omit Getter/setter} 2: After configuring the model and its relationships, you can use it when building specification, Example below:specification<usermodel> spec = new specification<usermodel> () {public predicate topredicate (Root <UserModel> root, criteriaquery<?> query, Criteriabuilder CB) {predicate p1 = Cb.like (root.get ("name"). As ( String.class), "%" +um.GetName () + "%"); predicate P2 = cb.equal (Root.get ("UUID"). As (Integer.class), Um.getuuid ()); predicate p3 = cb.gt (Root.get ("age"). As (Integer.class), Um.getage ()); setjoin<usermodel,depmodel> Depjoin = Root.join (Root.getmodel (). Getset ("SETDEP", Depmodel.class), Jointype.left); predicate P4 = cb.equal (Depjoin.get ("name"). As (String.class), "ddd");//apply predicate to Criteriaquery, Because you can also add other functions to criteriaquery, such as sorting, grouping what Query.where (Cb.and (p3,cb.or (P1,P2)), p4), or add grouping of the function Query.orderby ( Cb.desc (Root.get ("UUID"). As (Integer.class)); return query.getrestriction ();}}; N Take a look at the criteria query to implement 1:1 of the query 1: Remove the SETDEP property and its configuration in Usermodel, and then add the following properties and configuration: @OneToOne () @JoinColumn (name = "Depuuid") Private Depmodel dep;public Depmodel getdep () {return DEP;} public void Setdep (Depmodel dep) {THIS.DEP = dep; }2: The annotation configuration on the UM attribute in Depmodel is removed and replaced with the following configuration: @OneToOne (mappedby = "dep", Fetch = Fetchtype. EAGER, cascade = {Cascadetype. All}) 3: In specification implementation, replace Setjoin's sentence with the following statement:join<usermodel,depmodel> Depjoin =root.join (root.getmodeL (). Getsingularattribute ("DEP", Depmodel.class), jointype.left);//root.join ("Dep", Jointype.left); This sentence is as simple as the function of the above sentence.
Spring Data JPA