JPA -施用JPQL语句进行查询
JPA --------使用JPQL语句进行查询查询语言(JPQL) ???? 这是持久化操作中很重要的一个方面,通过面向对象而
JPA --------使用JPQL语句进行查询
查询语言(JPQL)
???? 这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
PersonTest.java
package?junit.test; ????import?java.util.List; ?? import?javax.persistence.EntityManager; ?? import?javax.persistence.EntityManagerFactory; ?? import?javax.persistence.Persistence; ?? import?javax.persistence.Query; ?? import?org.junit.BeforeClass; ?? import?org.junit.Test; ?? import?cn.itcast.bean.Person; ?? ??public?class?PersonTest?{ ?? ??????@BeforeClass?? ????public?static?void?setUpBeforeClass()?throws?Exception?{ ?? ????} ????????@Test?? ????public?void?save()?{ ?? ????????//?对实体bean进行操作,第一步应该获取什么对象啊??SessionFactory对象。 ?? ????????//?这里用获取的EntityManagerFactory对象,这可以把它看成跟Hibernate的SessionFactory对象差不多的东西。 ?? ????????EntityManagerFactory?factory?=?Persistence ??????????????????.createEntityManagerFactory("itcast"); ?? ????????EntityManager?em?=?factory.createEntityManager(); ??????????em.getTransaction().begin();????//?开启事务。 ?? ????????em.persist(new?Person("中信软件")); ?? ????????em.getTransaction().commit(); ??????????em.close(); ??????????factory.close(); ????????????//?SessionFactory?-->?Session?-->?begin事务 ?? ????} ????????/* ??????session.save(obj); ??????persist这方法在Hibernate里也存在,Hibernate的作者已经不太推荐大家用save方法,而是推荐大家用persist方法。 ??????why??首先并不是代码上的问题,主要是这个名字上的问题,因为我们把这个ORM技术叫做持久化产品,那么我们对某个对象持久化,应该叫持久化,而不应该叫保存,所以后来Hibernate的作者推荐用persist方法,这并不是功能的问题,主要是取名的问题,所以用推荐用persist方法。 ??????*/????????@Test?? ????public?void?query1()?{ ?? ????????EntityManagerFactory?factory?=?Persistence ??????????????????.createEntityManagerFactory("itcast"); ?? ????????EntityManager?em?=?factory.createEntityManager(); ??????????//?只是想获取数据,那么创建的查询语句可以不在事务里创建,不需要开启事务。 ?? ????????//?但是如果想通过语句去更新数据库的话,就必须要打开事务了,否则不会保存成功。 ?? ????????Query?query?=?em.createQuery("select?o?from?Person?o?where?o.id?=??1");??//?1采用位置参数查询,?1表示一个参数。 ?? ????????//?和Hibernate一样,都是面向对象的语句,不是sql语句。?里面出现的都是实体的名称和实体的属性。 ?? ????????//?1表示第一个参数,后面可以用Query对象的setParameter方法设置这个参数的内容。参数可以不用从1开始,可以从2等其他数字开始。 ?? ????????//?JPA规范的写法前面是要加"select?o"的(o是起的别名,名字可以任意),而Hibernate是可以省略的,但是如果你选用的JPA实现产品是Hibernate的话,不写也不会出错。但是可能移植到别的可持久化实现产品中就有可能出错,所以我们应该严格按照JPA规范来编写代码。 ?? ????????query.setParameter(1,?1);??//设置第一个参数的值为1。 ?? ????????/* ??????????不要直接在上面的语句里写值,因为如果你用JDBC的话就会存在一个问题:注入sql工具,注入sql工具在ASP年代(00-03年),sql工具是个高峰期,就因为我们的开发人员把从请求参数里面得到参数值后,直接赋进去,那么这时候就可能有问题,如果别人输入的是正确的,那当然好咯,如果输入错误的,比如?String?name?=?request.getParameter("name");?假如name=";delete?from?Person"的话,那么sql语句会变成select?o?from?Person?o?where?o.id?=;delete?from?Person,?这样在sql?server数据库里面,必然会把数据表里面的数据全部删除掉,所以我们一定要注意sql工具,在开发应用时也要注意,所以在写参数的时候,不要把参数直接写进去,也不要采用字符串组拼的方式来使用,而是应该采用命名参数查询,或者位置参数查询,JPA里面也提供了两种,命名参数查询(:id)和位置参数查询(?);?JPA里面提供了更方便的实现,可以给?编号,就是?后面跟数字。 ??????????*/???????????//防sql注入其实就是参数设置的地方只能允许设置为一个参数,并且参数设置的方法还会去检查参数设置的合理性。如果是字符串拼接等方法就存在安全问题了。 ?? ????????Person?person?=?(Person)?query.getSingleResult(); ??????????//?getSingleResult方法相当于Hibernate里的Session.createQuery("").uniqueResult(); ?? ????????//?使用getSingleResult方法的前提是必须保证记录存在,如果记录不存在,那么会出错的。这个方法还需要query对象里的记录是唯一的,有多个记录也会出错。 ?? ????????System.out.println(person.getName()); ??????????em.close(); ??????????factory.close(); ??????} ????????@Test?? ????public?void?query2()?{ ?? ????????EntityManagerFactory?factory?=?Persistence ??????????????????.createEntityManagerFactory("itcast"); ?? ????????EntityManager?em?=?factory.createEntityManager(); ??????????Query?query?=?em.createQuery("select?o?from?Person?o?where?o.id?=??1"); ?? ????????query.setParameter(1,?1); ?? ????????List<Person>?persons?=?query.getResultList();??//返回的是一个list,这里指定了list的泛型是Person类型的。 ?? ???????? ??????????for?(Person?person?:?persons)?{ ?? ????????????System.out.println(person.getName()); ??????????} ??????????em.close(); ??????????factory.close(); ??????} ????????@Test?? ????public?void?deleteQuery()?{ ?? ????????EntityManagerFactory?factory?=?Persistence ??????????????????.createEntityManagerFactory("itcast"); ?? ????????EntityManager?em?=?factory.createEntityManager(); ??????????em.getTransaction().begin();????//?进行数据的更改操作,必须开启事务。 ?? ????????Query?query?=?em.createQuery("delete?from?Person?o?where?o.id?=??1"); ?? ????????query.setParameter(1,?1); ?? ????????query.executeUpdate(); ??????????em.getTransaction().commit(); ??????????em.close(); ??????????factory.close(); ??????} ????????@Test?? ????public?void?updateQuery()?{ ?? ????????EntityManagerFactory?factory?=?Persistence ??????????????????.createEntityManagerFactory("itcast"); ?? ????????EntityManager?em?=?factory.createEntityManager(); ??????????em.getTransaction().begin();????//?开启事务。 ?? ????????Query?query?=?em.createQuery("update?Person?o?set?o.name?=?:name?where?o.id?=?:id");????//?采用命名参数查询。 ?? ????????query.setParameter("name",?"xxx"); ?? ????????query.setParameter("id",?2); ?? ????????query.executeUpdate(); ??????????em.getTransaction().commit(); ??????????em.close(); ??????????factory.close(); ??????} ??}??