泉州优化怎么做seo,揭阳百度快照优化排名,个人博客网站建设,西安建网站公司哪家好jpa 查询 列表这一部分是该系列文章的第一部分 。 JPA#xff1a;NamedQuery#xff0c;使用日期查询#xff0c;有关getSingleResult方法的警告 为了避免重复查询代码#xff0c;提高性能并简化维护查询#xff0c;我们可以使用NamedQueries。 NamedQuery使用JPQL作为语… jpa 查询 列表 这一部分是该系列文章的第一部分 。 JPANamedQuery使用日期查询有关getSingleResult方法的警告 为了避免重复查询代码提高性能并简化维护查询我们可以使用NamedQueries。 NamedQuery使用JPQL作为语法并在实体类中声明。 类代码更新后更容易编辑查询。 如果要使用日期作为参数进行查询则只能发送日期对象也可以传递描述日期类型的枚举推荐。 在下面您将看到如何创建和使用NamedQuery以及如何使用日期查询 package com.model;import java.util.Date;import javax.persistence.*;Entity
NamedQuery(nameDog.FindByDateOfBirth, queryselect d from Dog d where d.dateOfBirth :dateOfBirth)
public class Dog {public static final String FIND_BY_DATE_OF_BIRTH Dog.FindByDateOfBirth;IdGeneratedValue(strategy GenerationType.AUTO)private int id;// get and set
}package com.model;import java.util.*;import javax.persistence.*;Entity
NamedQueries({NamedQuery(namePerson.findByName, queryselect p from Person p where p.name :name),NamedQuery(namePerson.findByAge, queryselect p from Person p where p.age :age)})
})
public class Person {public static final String FIND_BY_NAME Person.findByName;public static final String FIND_BY_AGE Person.findByAge;IdGeneratedValue(strategy GenerationType.AUTO)private int id;// get and set}package com.main;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TemporalType;import com.model.Dog;
import com.model.Person;public class Page07 {public static void main(String[] args) {CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em CodeGenerator.getEntityManager();int age 70;ListPerson personByAge getPersonByAge(em, 70);System.out.println(Found personByAge.size() person(s) with the age of: age);SimpleDateFormat formatter new SimpleDateFormat(dd/MM/yyyy);Date dateOfBirth null;try {dateOfBirth formatter.parse(10/1/1995);} catch (ParseException e) {e.printStackTrace();}ListDog dogsByDayOfBirth getDogsByDayOfBirth(em, dateOfBirth);System.out.println(Found dogsByDayOfBirth.size() dog with birth date of formatter.format(dateOfBirth));/** This queries will raise Runtime Exceptions** em.createQuery(select p from Person p).getSingleResult(); // NonUniqueResultException** em.createQuery(select p from Person p where p.name JJJJ).getSingleResult(); //NoResultException*/CodeGenerator.closeConnection();}SuppressWarnings(unchecked)private static ListDog getDogsByDayOfBirth(EntityManager em, Date dateOfBirth) {Query query em.createNamedQuery(Dog.FIND_BY_DATE_OF_BIRTH);query.setParameter(dateOfBirth, dateOfBirth, TemporalType.DATE);return query.getResultList();}SuppressWarnings(unchecked)private static ListPerson getPersonByAge(EntityManager em, int age) {Query query em.createNamedQuery(Person.FIND_BY_AGE);query.setParameter(age, age);return query.getResultList();}
} 关于上面的代码 如果只有一个查询则可以使用NamedQuery注释 如果您有多个查询则可以使用NamedQueries批注。 使用日期对象进行查询时还可以使用TemporalType枚举来详细说明日期的类型。 对于日期查询可以使用“ java.util.Date ”或“ java.util.GregorianCalendar ”。 getSingleResult 使用此方法时要小心。 它有一种特殊的方式来处理容易发生的两种行为并且两种行为都会引发异常 从查询结果中查找多个对象 NonUniqueResultException 找不到结果 NoResultException 您始终需要使用try / catch以避免在生产环境中引发这些异常。 如果您想实时查看此异常则在上面的代码中可以找到两个带注释的查询。 它将引发以下异常 Exception in thread main span styletext-decoration: underline;javax.persistence.NonUniqueResultException/span: result returns more than one elements
at org.hibernate.ejb.QueryImpl.getSingleResult(span styletext-decoration: underline;QueryImpl.java:287/span)
Exception in thread main span styletext-decoration: underline;javax.persistence.NoResultException/span: No entity found for query
at org.hibernate.ejb.QueryImpl.getSingleResult(span styletext-decoration: underline;QueryImpl.java:280/span) JPANativeQuery名为NativeQuery JPA使用的JPQL没有任何特定于数据库的功能。 当JPQL仅提供数据库之间的公用功能时如何进行查询以调用特定的数据库功能 “ 从人员p中选择p其中p.name〜*name ”该查询语法是对Postgres数据库的有效查询 如果尝试使用NamedQuery使用JPQL运行此查询则会看到以下异常 strongemERROR SessionFactoryImpl:422 - Error in named query: Person.FindByName/em/strong
strongemorg.hibernate.QueryException: unexpected char: ~ [select p from com.model.Person p where p.name ~* :name]/em/strong
strongemat org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:229)/em/strong
strongemat org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)/em/strong
strongemat org.hibernate.engine.query.HQLQueryPlan.init(HQLQueryPlan.java:101)/em/strong
strongemat org.hibernate.engine.query.HQLQueryPlan.init(HQLQueryPlan.java:80)/em/strong
strongemat org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)/em/strong
strongemat org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:547)/em/strong
strongemat org.hibernate.impl.SessionFactoryImpl.init(SessionFactoryImpl.java:411)/em/strong
strongemat org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1842)/em/strong
strongemat org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:902)/em/strong
strongemat org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57)/em/strong
strongemat javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)/em/strong
strongemat javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)/em/strong
strongemat com.main.CodeGenerator.startConnection(CodeGenerator.java:27)/em/strong
strongemat com.main.Page05.main(Page05.java:12)/em/strong
strongemException in thread “main” javax.persistence.PersistenceException: [PersistenceUnit: JpaQuery] Unable to build EntityManagerFactory/em/strong
strongemat org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:911)/em/strong
strongemat org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57)/em/strong
strongemat javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)/em/strong
strongemat javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)/em/strong
strongemat com.main.CodeGenerator.startConnection(CodeGenerator.java:27)/em/strong
strongemat com.main.Page05.main(Page05.java:12)/em/strong
strongemCaused by: org.hibernate.HibernateException: Errors in named queries: Person.FindByName/em/strong
strongemat org.hibernate.impl.SessionFactoryImpl.init(SessionFactoryImpl.java:424)/em/strong
strongemat org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1842)/em/strongstrongem /em/strong
strongemat org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:902)/em/strong
strongem ... 5 more/em/strong 解决这种情况的方法是使用不使用JPQL作为其语法的查询。 使用NativeQuery您将能够使用数据库语法进行查询。 您可以在下面的代码中看到如何使用NativeQueries package com.main;import javax.persistence.EntityManager;
import javax.persistence.Query;import com.model.Dog;public class Page08 {public static void main(String[] args) {CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em CodeGenerator.getEntityManager();String nameOfFirstPerson getFirstPersonName(em);System.out.println(nameOfFirstPerson);Dog dog getTopDogDescending(em);System.out.println(dog.getName());CodeGenerator.closeConnection();}/*** Returns the name of the first person using a native sql*/private static String getFirstPersonName(EntityManager em) {Query query em.createNativeQuery(select top 1 name from person);return (String) query.getSingleResult();}/*** Return an object using a native sql*/private static Dog getTopDogDescending(EntityManager em) {Query query em.createNativeQuery(select top 1 id, name, weight from dog order by id desc, Dog.class);return (Dog) query.getSingleResult();}
} 关于上面的代码 注意我们使用本机查询代替JPQL。 我们可以有一个实体作为本地查询的结果。 方法“ getTopDogDescending ”在本机查询调用之后返回Dog对象。 您还可以将本地查询创建为NamedNativeQuery。 NamedNativeQuery和NativeQuery之间的区别在于NamedNativeQuery是在其实体类上定义的并且您只能使用该名称类。 使用NamedNativeQuery的优点是 易于维护的代码每个查询都在该类上如果一个类更新属性则更新查询将变得更加容易。 帮助提高性能一旦声明了查询JPA将对其进行映射并将其语法保留在内存中。 JPA不需要在项目每次使用时都“解析”您的查询。 提升代码重用性声明NamedNativeQuery后必须为“ name”参数提供一个值并且该名称对于Persistence Unit范围必须是唯一的您在“ persistence.xml”中设置此值并由EntityManager。 您将在下面看到如何声明NamedNativeQuery package com.model;import java.util.*;import javax.persistence.*;Entity
NamedQueries({NamedQuery(namePerson.findByName, queryselect p from Person p where p.name :name),NamedQuery(namePerson.findByAge, queryselect p from Person p where p.age :age)
})NamedNativeQuery(namePerson.findByNameNative, queryselect id, name, age from person where name :name)
public class Person {public static final String FIND_BY_NAME Person.findByName;public static final String FIND_BY_AGE Person.findByAge;IdGeneratedValue(strategy GenerationType.AUTO)private int id;// get and set
} 您将可以使用NamedNativeQuery就像NativeQuery一样 em.createNamedQuery“ Person.findByNameNative”; ”。 这里有一些坏消息。 不幸的是Hibernate尚未实现NamedNativeQuery。 如果您尝试使用此批注运行代码则会看到以下异常 emCaused by: span styletext-decoration: underline;org.hibernate.cfg.NotYetImplementedException/span: Pure native scalar queries are not yet supported/em
emat org.hibernate.cfg.annotations.QueryBinder.bindNativeQuery(span styletext-decoration: underline;QueryBinder.java:140/span)/em
emat org.hibernate.cfg.AnnotationBinder.bindQueries(span styletext-decoration: underline;AnnotationBinder.java:339/span)/em
emat org.hibernate.cfg.AnnotationBinder.bindClass(span styletext-decoration: underline;AnnotationBinder.java:548/span)/em
emat org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(span styletext-decoration: underline;Configuration.java:3977/span)/em
emat org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(span styletext-decoration: underline;Configuration.java:3931/span)/em
emat org.hibernate.cfg.Configuration.secondPassCompile(span styletext-decoration: underline;Configuration.java:1368/span)/em
emat org.hibernate.cfg.Configuration.buildMappings(span styletext-decoration: underline;Configuration.java:1345/span)/em
emat org.hibernate.ejb.Ejb3Configuration.buildMappings(span styletext-decoration: underline;Ejb3Configuration.java:1477/span)/em
emat org.hibernate.ejb.EventListenerConfigurator.configure(span styletext-decoration: underline;EventListenerConfigurator.java:193/span)/em
emat org.hibernate.ejb.Ejb3Configuration.configure(span styletext-decoration: underline;Ejb3Configuration.java:1096/span)/em
emat org.hibernate.ejb.Ejb3Configuration.configure(span styletext-decoration: underline;Ejb3Configuration.java:278/span)/em
emat org.hibernate.ejb.Ejb3Configuration.configure(span styletext-decoration: underline;Ejb3Configuration.java:362/span)/em JPA复杂的本地查询 您将能够创建映射到NativeQuery的复合体。 此映射将返回多个类或值。 您可以在下面看到我们的类如何映射此复杂结果以及如何使用它执行查询 package com.model;import java.util.*;import javax.persistence.*;Entity
NamedQueries({NamedQuery(namePerson.findByName, queryselect p from Person p where p.name :name),NamedQuery(namePerson.findByAge, queryselect p from Person p where p.age :age)})
})
SqlResultSetMappings({SqlResultSetMapping(namepersonAndAdress,entities{EntityResult(entityClassPerson.class),EntityResult(entityClassAddress.class,fields{FieldResult(nameid, columnADDRESS_ID)})}),SqlResultSetMapping(namepersonWithDogAmount,entities{EntityResult(entityClassPerson.class)},columns{ColumnResult(namedogAmount)})
})
public class Person {public static final String FIND_BY_NAME Person.findByName;public static final String FIND_BY_AGE Person.findByAge;public static final String MAPPING_PERSON_AND_ADDRESS personAndAdress;public static final String MAPPING_DOG_AMOUNT personWithDogAmount;IdGeneratedValue(strategy GenerationType.AUTO)private int id;// get and set
}package com.main;import java.math.BigInteger;import javax.persistence.EntityManager;
import javax.persistence.Query;import com.model.Address;
import com.model.Person;public class Page09 {public static void main(String[] args) {CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em CodeGenerator.getEntityManager();Query query em.createNativeQuery(select id, name, age, a.id as ADDRESS_ID, houseNumber, streetName from person p join address a on a.id p.address_id where p.id 1,Person.MAPPING_PERSON_AND_ADDRESS);Object[] result (Object[]) query.getSingleResult();Person personWithAdress (Person) result[0];Address address (Address) result[1];System.out.println(personWithAdress.getName() lives at address.getStreetName());query em.createNativeQuery(select p.id, p.name, count(0) as dogAmount from person p join dog d on p.id d.person_id where name Mark group by p.id, p.name,Person.MAPPING_DOG_AMOUNT);result (Object[]) query.getSingleResult();Person person (Person) result[0];BigInteger total (BigInteger) result[1];System.out.println(person.getName() has total dogs);CodeGenerator.closeConnection();}
} 关于上面的代码 使用“ SqlResultSetMapping ”您将通知JPA我们想要哪个实体作为结果。 注意在映射“ personAndAdress ”中我们编写了将返回的类。 我们还使用了一个名为“ FieldResult ”的属性。 此属性将映射具有相同名称的查询字段在我们的查询中我们获得了人员ID和地址ID。 这就是为什么我们使用“ FieldResult ”来通知JPA将列ADDRESS_ID映射到Address类的ID属性的原因。 在“ dogAmount ”映射中我们设置“ ColumnResult”属性该属性通知JPA我们将在查询结果中包含一个“ 额外的列 ”并且此“ 额外的列 ”不属于任何类。 JPA使用EJB优化查询 每次在事务范围内执行查询时持久性上下文将使结果保持“ 附加 ”状态。 持久性上下文将“ 监视 ”该对象以防万一该“ 附加 ”对象中的任何对象收到任何更新。 所有“ 附加的 ”对象更新都将保留在数据库中。 PersistenceContext(unitName myPU)
private EntityManager em;TransactionAttribute(TransactionAttributeType.REQUIRED)
public void editPersonName(Integer personId, String personNewName){Person person em.find(Person.class, personId);person.setName(personNewName);
} 您可以在上面的代码中看到我们不需要调用“ em.merge ”来更新数据库中的人名。 当我们从数据库中带出一个集合通常要显示在数据表或报表上时所有这些对象都将附加到持久性上下文中。 制作此对象的过程将触发多个过程数据验证和同步。 当对象数越高时分配给查询结果的内存就越高而使所有这些对象保持“ 连接 ”状态的持久性上下文的工作就越高。 将所有这些对象的最终目的地发送到视图时将所有这些对象“附加”起来有什么意义 当对象离开EJB项目并转到视图项目时它们将被视为“分离的”。 在这种情况下我们无需进行不必要的工作即可从数据库中获取所有数据进行make而不是“附加”并将其发送到视图以使其“分离”。 有一种简单的方法可以使这些对象来自已经分离的数据库。 这种方法的优势在于持久性上下文将永远不会浪费时间并且容器处理器会尝试同步查询结果。 您可以在下面的代码中看到此解决方案的工作方式。 package com.main;import java.util.List;import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;import com.model.Person;Stateless
TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class PersonDAO {PersistenceContext(unitName myPU)private EntityManager em;TransactionAttribute(TransactionAttributeType.REQUIRED)public void editPersonName(Integer personId, String personNewName){Person person em.find(Person.class, personId);person.setName(personNewName);}SuppressWarnings(unchecked)public ListPerson listAll(){Query query em.createQuery(select p from Person p);return query.getResultList();}SuppressWarnings(unchecked)public ListPerson listAllWithoutDogs(){Query query em.createQuery(select p from Person p where p.dogs is empty);return query.getResultList();}
} 在上面的代码中我们获得了一个DAO类即EJB。 默认情况下我们的EJB缺少事务“ TransactionAttributeTransactionAttributeType.NOT_SUPPORTED ”使用这种事务持久性上下文将不会“ 附加 ”查询结果。 查询返回的对象将被视为“ 分离 ”。 请注意方法“ editPersonName ”的注释仍相同“ TransactionAttributeTransactionAttributeType.REQUIRED ”。 这种事务向EJB指示如果还没有启动任何新事务则应该启动一个新事务。 您可以为该类设置事务属性但是方法可以覆盖此属性就像我们在“ editPersonName ”中所做的一样 。 方法事务定义将优先于类事务定义。 JPA分页 如果要进行JPA分页请像下面的方法一样 package com.main;import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.Query;import com.model.Dog;public class Page11 {SuppressWarnings(unchecked)public static void main(String[] args) {CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em CodeGenerator.getEntityManager();Query query em.createQuery(select d from Dog d);ListDog dogs query.getResultList();System.out.println(Total of dogs found: dogs.size());query.setMaxResults(5);query.setFirstResult(0);ListDog fiveFirstDogs query.getResultList();System.out.print(Total of dogs found: fiveFirstDogs.size() );for (Dog dog : fiveFirstDogs) {System.out.print(dog.getName() );}System.out.println();query.setMaxResults(5);query.setFirstResult(5);ListDog fiveSecondDogs query.getResultList();System.out.print(Total of dogs found: fiveSecondDogs.size() );for (Dog dog : fiveSecondDogs) {System.out.print(dog.getName() );}CodeGenerator.closeConnection();}
} 关于上面的代码 方法“ setMaxResults ”将设置查询将返回的结果量。 方法“ setFirstResult ”将设置将要带来的第一行。 在第一个查询中我们搜索了数据库中的所有数据。 在第二个查询中我们从位置0开始获得了五个结果。 在上一个查询中我们再次获得了五个结果但是从位置5开始。 请记住第一个位置始终为零而不是一个。 JPA数据库提示 数据库供应商向我们提供了名为“提示”的特定功能。 这些提示非常有用因为它们可以优化查询并帮助我们完成其他任务。 每个数据库都有自己的提示并且这些值不可移植。 在下面您可以看到一些提示 SQLServerOPTIONOPTIMIZE FORname Markage UNKNOWN; Oracle选择/ * first_rows100* /名称 MySQL从人忽略索引中选择*col3_index 每个数据库供应商都将规则设置为其提示诸如语法和执行命令之类的规则。 有两种定义提示的方法 package com.main;import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.Query;import com.model.Dog;public class Page12 {SuppressWarnings(unchecked)public static void main(String[] args) {CodeGenerator.startConnection();CodeGenerator.generateData();EntityManager em CodeGenerator.getEntityManager();Query query em.createQuery(select d from Dog d);query.setHint(org.hibernate.timeout, 1000);ListDog dogs query.getResultList();System.out.println(Found dogs.size() dogs);CodeGenerator.closeConnection();}
}package com.model;import java.util.*;import javax.persistence.*;Entity
NamedQueries({NamedQuery(namePerson.findByName, queryselect p from Person p where p.name :name),NamedQuery(namePerson.findByAge, queryselect p from Person p where p.age :age, hints{QueryHint(nameorg.hibernate.timeout, value1000)})
})
SqlResultSetMappings({SqlResultSetMapping(namepersonAndAdress,entities{EntityResult(entityClassPerson.class),EntityResult(entityClassAddress.class,fields{FieldResult(nameid, columnADDRESS_ID)})}),SqlResultSetMapping(namepersonWithDogAmount,entities{EntityResult(entityClassPerson.class)},columns{ColumnResult(namedogAmount)})
})
public class Person {public static final String FIND_BY_NAME Person.findByName;public static final String FIND_BY_AGE Person.findByAge;public static final String MAPPING_PERSON_AND_ADDRESS personAndAdress;public static final String MAPPING_DOG_AMOUNT personWithDogAmount;IdGeneratedValue(strategy GenerationType.AUTO)private int id;// get and set
} 您可以在NamedQuery和直接在查询中设置提示。 您必须始终记住提示的缺点 。 在NamedQuery上设置提示后您的代码将无法移植到其他数据库供应商。 一种解决方案是仅使用查询而不是NamedQuery。 在将提示添加到查询之前您可以检查当前数据库是否支持该提示。 您可以使用属性文件来定义应用程序的当前数据库。 继续本系列的第三部分 参考 uaiHebert博客上来自JCG合作伙伴 Hebert Coelho的JPA查询和技巧 。 翻译自: https://www.javacodegeeks.com/2012/07/ultimate-jpa-queries-and-tips-list-part_09.htmljpa 查询 列表