JPA -施用JPQL语句进行查询

JPA --------使用JPQL语句进行查询

查询语言(JPQL)
     这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

PersonTest.java

Java代码 JPA -施用JPQL语句进行查询
  1. package junit.test;   
  2.   
  3. import java.util.List;   
  4. import javax.persistence.EntityManager;   
  5. import javax.persistence.EntityManagerFactory;   
  6. import javax.persistence.Persistence;   
  7. import javax.persistence.Query;   
  8. import org.junit.BeforeClass;   
  9. import org.junit.Test;   
  10. import cn.itcast.bean.Person;   
  11.   
  12. public class PersonTest {   
  13.   
  14.     @BeforeClass  
  15.     public static void setUpBeforeClass() throws Exception {   
  16.     }   
  17.   
  18.     @Test  
  19.     public void save() {   
  20.         // 对实体bean进行操作,第一步应该获取什么对象啊? SessionFactory对象。   
  21.         // 这里用获取的EntityManagerFactory对象,这可以把它看成跟Hibernate的SessionFactory对象差不多的东西。   
  22.         EntityManagerFactory factory = Persistence   
  23.                 .createEntityManagerFactory("itcast");   
  24.         EntityManager em = factory.createEntityManager();   
  25.         em.getTransaction().begin();    // 开启事务。   
  26.         em.persist(new Person("中信软件"));   
  27.         em.getTransaction().commit();   
  28.         em.close();   
  29.         factory.close();   
  30.   
  31.         // SessionFactory --> Session --> begin事务   
  32.     }   
  33.   
  34.     /*  
  35.      session.save(obj);  
  36.      persist这方法在Hibernate里也存在,Hibernate的作者已经不太推荐大家用save方法,而是推荐大家用persist方法。  
  37.      why? 首先并不是代码上的问题,主要是这个名字上的问题,因为我们把这个ORM技术叫做持久化产品,那么我们对某个对象持久化,应该叫持久化,而不应该叫保存,所以后来Hibernate的作者推荐用persist方法,这并不是功能的问题,主要是取名的问题,所以用推荐用persist方法。  
  38.      */  
  39.   
  40.     @Test  
  41.     public void query1() {   
  42.         EntityManagerFactory factory = Persistence   
  43.                 .createEntityManagerFactory("itcast");   
  44.         EntityManager em = factory.createEntityManager();   
  45.         // 只是想获取数据,那么创建的查询语句可以不在事务里创建,不需要开启事务。   
  46.         // 但是如果想通过语句去更新数据库的话,就必须要打开事务了,否则不会保存成功。   
  47.         Query query = em.createQuery("select o from Person o where o.id = ?1");  //?1采用位置参数查询,?1表示一个参数。   
  48.         // 和Hibernate一样,都是面向对象的语句,不是sql语句。 里面出现的都是实体的名称和实体的属性。   
  49.         //?1表示第一个参数,后面可以用Query对象的setParameter方法设置这个参数的内容。参数可以不用从1开始,可以从2等其他数字开始。   
  50.         // JPA规范的写法前面是要加"select o"的(o是起的别名,名字可以任意),而Hibernate是可以省略的,但是如果你选用的JPA实现产品是Hibernate的话,不写也不会出错。但是可能移植到别的可持久化实现产品中就有可能出错,所以我们应该严格按照JPA规范来编写代码。   
  51.         query.setParameter(11);  //设置第一个参数的值为1。   
  52.         /*  
  53.          不要直接在上面的语句里写值,因为如果你用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里面提供了更方便的实现,可以给?编号,就是?后面跟数字。  
  54.          */  
  55.          //防sql注入其实就是参数设置的地方只能允许设置为一个参数,并且参数设置的方法还会去检查参数设置的合理性。如果是字符串拼接等方法就存在安全问题了。   
  56.         Person person = (Person) query.getSingleResult();   
  57.         // getSingleResult方法相当于Hibernate里的Session.createQuery("").uniqueResult();   
  58.         // 使用getSingleResult方法的前提是必须保证记录存在,如果记录不存在,那么会出错的。这个方法还需要query对象里的记录是唯一的,有多个记录也会出错。   
  59.         System.out.println(person.getName());   
  60.         em.close();   
  61.         factory.close();   
  62.     }   
  63.   
  64.     @Test  
  65.     public void query2() {   
  66.         EntityManagerFactory factory = Persistence   
  67.                 .createEntityManagerFactory("itcast");   
  68.         EntityManager em = factory.createEntityManager();   
  69.         Query query = em.createQuery("select o from Person o where o.id = ?1");   
  70.         query.setParameter(11);   
  71.         List<Person> persons = query.getResultList();  //返回的是一个list,这里指定了list的泛型是Person类型的。   
  72.            
  73.         for (Person person : persons) {   
  74.             System.out.println(person.getName());   
  75.         }   
  76.         em.close();   
  77.         factory.close();   
  78.     }   
  79.   
  80.     @Test  
  81.     public void deleteQuery() {   
  82.         EntityManagerFactory factory = Persistence   
  83.                 .createEntityManagerFactory("itcast");   
  84.         EntityManager em = factory.createEntityManager();   
  85.         em.getTransaction().begin();    // 进行数据的更改操作,必须开启事务。   
  86.         Query query = em.createQuery("delete from Person o where o.id = ?1");   
  87.         query.setParameter(11);   
  88.         query.executeUpdate();   
  89.         em.getTransaction().commit();   
  90.         em.close();   
  91.         factory.close();   
  92.     }   
  93.   
  94.     @Test  
  95.     public void updateQuery() {   
  96.         EntityManagerFactory factory = Persistence   
  97.                 .createEntityManagerFactory("itcast");   
  98.         EntityManager em = factory.createEntityManager();   
  99.         em.getTransaction().begin();    // 开启事务。   
  100.         Query query = em.createQuery("update Person o set o.name = :name where o.id = :id");    // 采用命名参数查询。   
  101.         query.setParameter("name""xxx");   
  102.         query.setParameter("id"2);   
  103.         query.executeUpdate();   
  104.         em.getTransaction().commit();   
  105.         em.close();   
  106.         factory.close();   
  107.     }   
  108. }