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 jobs Configuration and the MapReduce job of a POJO programming model key-value -integrates Redis and Riak to provide a simple package document-integrated documentation database: CouchDB and MongoDB and provides the base This configuration map and repository support Graph-integrated neo4j provides a powerful POJO-based programming model graph Roo Addon-roo support for neo4j JDBC Extensions-Supports Oracle RAD, high Level queue and Advanced data type Mapping-Grails-based provider object mapping framework supporting different database Examples-sample programs, documents, and graph databases Guidance-Advanced documentation What spring Data JPA is provided by spring is a The framework for simplifying JPA development nspring data JPA can greatly simplify the JPA notation, enabling access to 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, adding pagination and sorting functionality 4:jparepository: It's Pagingandsortingrepository's son.interface, added some useful functions, such as: batch operation. 5:jpaspecificationexecutor: Used to do query interface 6:specification: is a query specification provided by Spring Data JPA, to do complex queries, simply set the query criteria around this specification can be HelloWorld n Environment constructs 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. This is Spring-data-commons-1.5.0.release.jar and Spring-data-jpa-1.3.2.release.jar. 2: Add the Spring3.2.3 jar package to the project 3:JPA the implementation of the selection is Hibernate4.2.0, a total of additional to add the following 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-connectorThe-java-5.1.9.jar, Slf4j-api-1.7.3.jar N Entity object is the previous implementation @Entity @Table (name= "Tbl_user") public class Usermodel {@Id Private 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 take care of everything N write a Service for the logic layer, which is equivalent to the DAO client, which is used to test @Service @Transactional public class Client { @Autowired private userrepository ur; public void Testadd (Usermodel um) {ur.save (UM),} public static void main (string[] args) {Applicationcontex T ctx = new Classpathxmlapplicationcontext ("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); }} 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.xsd Http://www.springframework.org/schema/context Http://www.springframework.org/schema/context /spring-context-3.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/ Spring-aop-3.0.xsd Http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/ Spring-tx-3.0.xsd HTTP://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 profile--<tx:annotation-driven transaction-manager= " TransactionManager "proxy-target-class=" true "/> <jpa:repositories base-package= "Cn.javass" repository-impl-postfix= "Impl" entity-manager-factory-ref= "Entitymanagerfactory" transaction-manager-ref= "TransactionManager" > </JPA: repositories> <bean id= "Entitymanagerfactory" class= "Org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" > <property name= "DataSource" ref= "DataSource"/> <property name= "Packagestoscan" value= "Cn.javass"/> <property name= "Persistenceprovider" > <bean class= "org.hibernate.ejb.HibernatePersistence"/> </property> <property name= "Jpavendoradapter" > <bean class= " Org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter "> <property name= "Generateddl" value= "false"/> <property name= "Database" value = "MYSQL"/> < Property Name= "Databaseplatform" value= "orG.hibernate.dialect.mysql5innodbdialect "/> <property name= "Showsql" value= "true"/> </bean> </property> <property name= "Jpadialect" > <bean class= "Org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> </property> < Property name= "Jpapropertymap" > <map> <entry key= " Hibernate.query.substitutions "Value=" True 1, False 0 "/> <entry key= "hibernate.default_batch_fetch_size" value= "+"/> <entry key= "Hibernate.max_fetch_ Depth "value=" 2 "/> <entry key= "Hibernate.generate_statistics" value= "true"/> <entry key= "Hibernate.bytecode.use_reflection_optimizer" value= " True "/> <entry key= "Hibernate.cache.use_second_level_cache" value= "false"/> <entry key= "Hibernate.cache.use_query_cache" value= "false"/> </map> &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&Nbsp; </property> </bean> <!--transaction Manager configuration- <bean id= " TransactionManager "class=" Org.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 tables need to be prepared or in the <JPA :repositories> add filter below, Shape: <repositories base-package= "Com.acme.repositories" > <conteXt:exclude-filter type= "regex" expression= ". *somerepository"/> </repositories> Chapter II: Jparepository basic functions
The basic function of the
Jparepository demonstrates the specific code shown here: the implementation class of the Pageable interface is the implementation class of the Pagerequest,page interface is Pageimpl. Examples are as follows: Page<usermodel> P = ur.findall (new Pagerequest (0,2,new Sort (Direction. DESC, "uuid"))); System. Out.println ("list=" +p.getcontent ()); Chapter Three: Jparepository's query
Directly in the interface to define the query method, if it is compliant, you can not write the implementation, the currently supported keywords are as follows: Spring Data JPA Framework in the method name resolution, the method name of the redundant prefix is intercepted, 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 resolve the remaining attributes, assuming that the query entity is Doc 1: 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); can also use JPA namedqueries, as follows: 1: Use @namedquery on entity classes, as shown in the following example: @NamedQuery (name = "Usermodel.findbyage", query = " Select O from UserModel o where o.age >=? 1 ") 2: Define a method of the same name in the Repository interface of the DAO you implement, as shown in the following example: Public list<usermodel> findbyage (int.) ; 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, it is possible to pass the parameter value when you can not add '% ', of course, plus can not be wrong n also use @Query to specify a local query, as long as set Nativequery to True, such as: @Query (value= "SELECT * From Tbl_user where name is%?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 named parameters, using @param, such as: @Query (value= "Select O from Usermodel o where o.name like%:nn") pub Lic list<usermodel> findbyuuidorage (@Param ("nn") String name); Also support the Update Class Query statement, 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 (" NewName ") string newName); Note: 1: The return value of the method should be int, indicating the number of rows affected by the UPDATE statement 2: A transaction must be added where the call is made, no transaction is performed properly jparepository query function creates the order of queries Spring Data JPA When creating proxy objects for an interface If you find that there are multiple scenarios that are available, which strategy should it take precedence? <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 there is a named query that matches, or if the method passes the specified query statement @Query, the 3:use-declared-query is ignored: If the method specifies a query statement through @query, the statement is used to implement the query; Finds whether a named query that matches the criteria is defined, uses the named query if it is found, or throws an exception if neither is found fourth: Custom extension jparepository
If you do not want to expose so many methods, 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 their own needs Method 1: Write a class with the same name as the interface, The suffix is impl, which is configured in the previous XML and can be scanned automatically. This class does not need to implement any interfaces. 2: Add the method you need in the interface, for example: 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; }}
The fifth chapter: Specifications Query
Spring Data JPA supports the criteria query for JPA2.0, and 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 various parts of the query, such as SELECT, from, where, group by, order by, and so on 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 the construction of basic objects 1: Criteriabuilder can be obtained by the Getcriteriabuilder method of the Entitymanager Getcriteriabuilder or entitymanagerfactoryImage 2: You can get instance 3 of Criteriaquery by calling Criteriabuilder's CreateQuery or Createtuplequery method: You can get the root instance by calling the Criteriaquery from method Filter Condition 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 ()); predicate example of building a combination: predicate p = Cb.and (P3,cb.or (P1,P2)); Of course can also be shaped as the previous dynamic stitching query statements, such as:
Java code: View Copy to clipboard print specification<usermodel> spec = new specification<usermodel> () { Public predicate topredicate (root<usermodel> root, criteriaquery <?> query, Criteriabuilder CB) { list<predicate> List = new arraylist<predicate& gt; (); 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 ("UUID"). As ( Integer.class), Um.getuuid ())); } predicate[] p = new predicate[ List.size ()]; return Cb.and (List.toarray (p)); } };
can also use criteriaquery to come to the last predicate, examples are as follows: Java code: View Copy to clipboard print 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 ()); // Apply predicate to Criteriaquery, because you can also add other functions to criteriaquery, such as sorting, grouping Query.where (Cb.and (p3,cb.or (P1,P2)); //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 more hassle, here's a demonstration of the common 1:m, incidentally 1:1 n using the criteria query to implement 1-to-many queries 1: First to add a solid object Depmodel, and set the Usermodel and its 1-to-many relationship, as follows: @Entity @Table (name= "Tbl_user") public class Usermodel {@Id private integer uuid; private String name; private integer age; @OneToMany (Mappedby = "um", fetch = Fetcht Ype. LAZY, cascade = {Cascadetype. All}) private set<depmodel> SETDEP; Omit Getter/setter} @Entity @Table (name= "TBL_DEP") public class Depmodel {@Id private Integer uuid; private String Name @ManyToOne () @JoinColumn (name = "USER_ID", Nullable = False)//indicates a field with user_id in TBL_DEP private Usermodel um = new U Sermodel (); Omit Getter/setter} 2: Once you have configured the model and its relationships, you can use it when building the specification, as shown in the following example: specification<usermodel&Gt 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 (Cb.and (p3,cb.or)), P4)); Adds a grouped feature 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 the specification implementation, replace the setjoin 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.
Learn Spring Data JPA