久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    JPA 各種基本用法

     moonboat 2014-07-07
    JPQL就是一種查詢語言,具有與 SQL 相類似的特征, JPQL 是完全面向對象的,具備繼承、多態和關聯等特性,和hibernate HQL很相似。
     
    查詢語句的參數
    JPQL 語句支持兩種方式的參數定義方式 : 命名參數和位置參數 。在同一個查詢語句中只允許使用一種參數定義方式。
     
    命令參數的格式為:“ : + 參數名”
    例:
    Query query = em.createQuery("select p from Person p where p.personid=:Id ");
    query.setParameter("Id",new Integer(1));
     
    位置參數的格式為“ ?+ 位置編號”
    例:
    Query query = em.createQuery("select p from Person p where p.personid=?1 ");
    query.setParameter(1,new Integer(1));
     
     
    如果你需要傳遞 java.util.Date java.util.Calendar 參數進一個參數查詢 你需要使用一個特殊的 setParameter() 方法 ,相關的 setParameter 方法定義如下:
     
    public interface Query
    {
    // 命名參數查詢時使用,參數類型為 java.util.Date
    Query setParameter(String name, java.util.Date value, TemporalType temporalType);
    // 命名參數查詢時使用,參數類型為 java.util.Calendar
    Query setParameter(String name, Calendar value, TemporalType temporalType);
    // 位置參數查詢時使用,參數類型為 java.util.Date
    Query setParameter(int position, Date value, TemporalType temporalType);
    // 位置參數查詢時使用,參數類型為 java.util.Calendar
    Query setParameter(int position, Calendar value, TemporalType temporalType);
    }
     
    因為一個 Date Calendar 對象能夠描述一個真實的日期、時間或時間戳 . 所以我們需要告訴 Query 對象怎么使用這些參數,我們 javax.persistence.TemporalType 作為參數傳遞進 setParameter 方法,告訴查詢接口在轉換 java.util.Date java.util.Calendar 參數到本地 SQL 時使用什么數據庫類型
     
    下面通過實例來學習JPQL語句,例子的entity Bean Person, Order, OrderItem 他們之間的關系是:一個 Person 有多個 Order, 一個 Order 有多個 OrderItem
     
    JPQL語句的大小寫敏感性:除了 Java 類和屬性名稱外,查詢都是大小寫不敏感的 。所以, SeLeCT sELEct 以及 SELECT 相同的,但是 com.foshanshop.ejb3.bean.Person com.foshanshop.ejb3.bean.PERSon 是不同的, person.name person.NAME 也是不同的。
     
     
    命名查詢
    可以在實體 bean 通過 @NamedQuery or @NamedQueries 預先定義一個或多個查詢語句,減少每次因書寫錯誤而引起的 BUG 。通常把經常使用的查詢語句定義成命名查詢
     
    定義單個命名查詢:
    @NamedQuery (name= "getPerson" , query= "FROM Person WHERE personid=?1" )
    @Entity
    public class Person implements Serializable{
     
    如果要定義多個命名查詢,應在 @javax.persistence.NamedQueries里定義 @NamedQuery
    @NamedQueries ({
    @NamedQuery (name= "getPerson" , query= "FROM Person WHERE personid=?1" ),
    @NamedQuery (name= "getPersonList" , query= "FROM Person WHERE age>?1" )
    })
    @Entity
    public class Person implements Serializable{
     
    當命名查詢定義好了之后,我們就可以通過名稱執行其查詢。代碼如下:
    Query query = em . createNamedQuery("getPerson") ;
    query.setParameter(1, 1);
     
     
    排序 (order by)
    "ASC" "DESC" 分別為升序和降序, JPQL 中默認為 asc 升序
    例:
    // 先按年齡降序排序,然后按出生日期升序排序
    Query query = em.createQuery("select p from Person p order by p.age desc, p.birthday asc ");
     
    查詢部分屬性
    通常來說,都是針對 Entity 類的查詢,返回的也是被查詢的 Entity 類的實體。J P QL 也允許我們直接查詢返回我們需要的屬性,而不是返回整個 Entity 在一些 Entity 中屬性特別多的情況,這樣的查詢可以提高性能
    例:
    // 查詢我們感興趣的屬性 ( )
    Query query=em.createQuery("select p.personid, p.name from Person p order by p.personid desc ");
    // 集合中的元素不再是 Person, 而是一個 Object[] 對象數組
    List result = query.getResultList();
    if (result!=null){
    Iterator iterator = result.iterator();
    while( iterator.hasNext() ){
    Object[] row = ( Object[]) iterator.next();
    int personid = Integer.parseInt(row[0].toString());
    String PersonName = row[1].toString();
    。。。。
    }
    }
     
    查詢中使用構造器 (Constructor)
    JPQL 支持將查詢的屬性結果直接作為一個 java class 的構造器參數,并產生實體作為結果返回 例如上面的例子只獲取 person entity bean的name and personid屬性,我們不希望返回的集合的元素是object[],而希望用一個類來包裝它。就要用到使用構造器
    例:
    public class SimplePerson {
     private Integer personid;
    private String name ;
       。。。。
    public SimplePerson() {
    }
    public SimplePerson(Integer personid, String name) {
    this . name = name;
    this . personid = personid;
    }
    }
     
    查詢代碼為:
    // 我們把需要的兩個屬性作為 SimplePerson 的構造器參數,并使用 new 函數。
    Query query = em.createQuery(" select new com.foshanshop.ejb3.bean.SimplePerson(p. personid, p.name) from Person p order by p.personid desc ");
    // 集合中的元素是 SimplePerson 對象
    List result = query.getResultList();
    if (result!=null){
    Iterator iterator = result.iterator();
    while( iterator.hasNext() ){
    SimplePerson simpleperson = (SimplePerson) iterator.next();
    。。。。
    }
    }
     
    聚合查詢 (Aggregation)
    JPQL 支持的聚合函數 包括:
    1. AVG()
    2. SUM()
    3. COUNT() 返回類型為 Long ,注意 count(*) 語法在 hibernate 中可用,但在 toplink 其它產品中并不可用
    4. MAX()
    5. MIN()
     
    例:
    // 獲取最大年齡
    Query query = em.createQuery("select max(p.age) from Person p");
    Object result = query.getSingleResult();
    String maxAge = result.toString();
    // 獲取平均年齡
    query = em.createQuery("select avg(p.age) from Person p");
    // 獲取最小年齡
    query = em.createQuery("select min(p.age) from Person p");
    // 獲取總人數
    query = em.createQuery("select count(p) from Person p");
    // 獲取年齡總和
    query = em.createQuery("select sum(p.age) from Person p");
     
    如果聚合函數不是 select...from 的唯一一個返回列,需要使用 "GROUP BY" 語句 "GROUP BY" 應該包含 select 語句中除了聚合函數外的所有屬性。
    例:
    // 返回男女生各自的總人數
    Query query = em.createQuery(" select p.sex, count(p) from Person p group by p.sex ");
    // 集合中的元素不再是 Person, 而是一個 Object[] 對象數組
    List result = query.getResultList();
     
    如果還需要加上查詢條件,需要使用 "HAVING" 條件語句而不是 "WHERE" 語句
    例:
    // 返回人數超過 1 人的性別
    Query query = em.createQuery("select p.sex, count(p) from Person p group by p.sex having count(*) >?1");
    // 設置查詢中的參數
    query.setParameter(1, new Long(1));
    // 集合中的元素不再是 Person, 而是一個 Object[] 對象數組
    List result = query.getResultList();
    關聯 (join)
    JPQL 仍然支持和 SQL 中類似的關聯語法:
    left out join/left join
    inner join
    left join fetch/inner join fetch
     
     
    left out join/left join 等,都是允許符合條件的右邊表達式中的 Entiies 為空( 需要顯式使用 left join/left outer join 的情況會比較少。
    例:
    // 獲取 26 歲人的訂單 , 不管 Order 中是否有 OrderItem
    select o from Order o left join o.orderItems where o.ower.age=26 order by o.orderid
     
     
    inner join 要求右邊的表達式必須返回 Entities
    例:
    // 獲取 26 歲人的訂單 ,Order 中必須要有 OrderItem
    select o from Order o inner join o.orderItems where o.ower.age=26 order by o.orderid
     
     
    !!重要知識點 在默認的查詢中, Entity 中的集合屬性默認不會被關聯,集合屬性默認是延遲加載 ( lazy-load ) 。那么, left fetch/left out fetch/inner join fetch 提供了一種靈活的查詢加載方式來提高查詢的性能。
    例:
    private String QueryInnerJoinLazyLoad(){
    // 默認不關聯集合屬性變量 (orderItems) 對應的表
    Query query = em.createQuery("select o from Order o inner join o.orderItems where o.ower.age=26 order by o.orderid");
    List result = query.getResultList();
    if (result!=null && result.size()>0){
    // 這時獲得 Order 實體中 orderItems( 集合屬性變量 ) 為空
    Order order = (Order) result.get(0);
    // 當需要時, EJB3 Runtime 才會執行一條 SQL 語句來加載屬于當前 Order
    //OrderItems
    Set<OrderItem> list = order.getOrderItems ();
    Iterator<OrderItem> iterator = list.iterator();
    if (iterator.hasNext()){
    OrderItem orderItem =iterator.next();
    System.out.println (" 訂購產品名: "+ orderItem.getProductname());
    }
    }
     
    上面代碼在執行 "select o from Order o inner join o.orderItems where o.ower.age=26 order by o.orderid" 時編譯成的 SQL 如下( 他不包含集合屬性變量 (orderItems) 對應表的字段
    select order0_.orderid as orderid6_, order0_.amount as amount6_, order0_.person_id as
    person4_6_, order0_.createdate as createdate6_ from Orders order0_ inner join OrderItems
    orderitems1_ on order0_.orderid=orderitems1_.order_id, Person person2_ where
    order0_.person_id=person2_.personid and person2_.age=26 order by order0_.orderid
     
     
    上面代碼當執行到 Set<OrderItem> list = order.getOrderItems(); 才會執行一條 SQL 語句來加載 屬于當前 Order OrderItems ,編譯成的 SQL 如下
    select orderitems0_.order_id as order4_1_, orderitems0_.id as id1_, orderitems0_.id as id7_0_,
    orderitems0_.order_id as order4_7_0_, orderitems0_.productname as productn2_7_0_,
    orderitems0_.price as price7_0_ from OrderItems orderitems0_ where orderitems0_.order_id=?
    order by orderitems0_.id ASC
     
    這樣的查詢性能上有不足的地方 。為了查詢 N Order ,我們需要一條 SQL 語句獲得所有的 Order 的原始對象屬性,但需要另外 N 條語句獲得每個 Order orderItems 集合屬性。為了避免 N+1 的性能問題,我們可以利用 join fetch 一次過用一條 SQL 語句把 Order 的所有信息查詢出來
     
    例子
    // 獲取 26 歲人的訂單 ,Order 中必須要有 OrderItem
    Query query = em.createQuery("select o from Order o inner join fetch o.orderItems where
    o.ower.age=26 order by o.orderid");
     
    上面這句HPQL編譯成以下的 SQL
    select order0_.orderid as orderid18_0_, orderitems1_.id as id19_1_, order0_.amount as
    amount18_0_,order0_.person_id as person4_18_0_, order0_.createdate as createdate18_0_,
    orderitems1_.order_id as order4_19_1_, orderitems1_.productname as productn2_19_1_,
    orderitems1_.price as price19_1_, orderitems1_.order_id as order4_0__, orderitems1_.id as id0__
    from Orders order0_ inner join OrderItems orderitems1_ on
    order0_.orderid=orderitems1_.order_id, Person person2_ where
    order0_.person_id=person2_.personid and person2_.age=26 order by order0_.orderid,
    orderitems1_.id ASC
     
    上面由于使用了 fetch, 這個查詢只會產生一條 SQL 語句,比原來需要 N+1 SQL 語句在性能上有了極大的提升
     
     
    排除相同的記錄 DISTINCT
    使用關聯查詢,我們很經常得到重復的對象,如下面語句:
    " select o from Order o inner join fetch o.orderItems order by o.orderid "
    當有 N orderItem 時就會產生 N Order, 而有些 Order 對象往往是相同的,這時我們需要使用 DISTINCT 關鍵字來排除掉相同的對象
    例:
    select DISTINCT o from Order o inner join fetch o.orderItems order by o.orderid
     
     
     
    比較 Entity
    在查詢中使用參數查詢時 ,參數類型除了 String, 原始數據類型 ( int, double ) 和它們的對象類型 ( Integer, Double ), 可以是 Entity 的實例
    例:
    // 查詢某人的所有訂單
    Query query = em.createQuery("select o from Order o where o.ower =?1 order by o.orderid");
    Person person = new Person();
    person.setPersonid(new Integer(1));
    // 設置查詢中的參數
    query.setParameter(1,person);
     
     
    批量更新 (Batch Update)
    HPQL支持批量更新
    例:
    // 把所有訂單的金額加 10
    Query query = em.createQuery(" update Order as o set o.amount=o.amount+10 ");
    //update 的記錄數
    int result = query. executeUpdate ();
     
     
    批量刪除 (Batch Remove)
    例:
    // 把金額小于100的訂單刪除,先刪除訂單子項, 再刪除訂單
    Query query = em .createQuery( "delete from OrderItem item where item.order in(from Order as o where o.amount<100)" );
    query. executeUpdate();
    query = em .createQuery( "delete from Order as o where o.amount<100" );
    query.executeUpdate(); //delete 的記錄數
     
     
    使用操作符 NOT
    // 查詢除了指定人之外的所有訂單
    Query query = em.createQuery("select o from Order o where not(o.ower =?1) order by o.orderid");
    Person person = new Person();
    person.setPersonid(new Integer(2));
    // 設置查詢中的參數
    query.setParameter(1,person);
     
     
    使用操作符 BETWEEN
    select o from Order as o where o.amount between 300 and 1000
     
    使用操作符 IN
    // 查找年齡為 26,21 Person
    select p from Person as p where p.age in(26,21)
     
    使用操作符 LIKE
    // 查找以字符串 "li" 開頭的 Person
    select p from Person as p where p.name like 'li%'
     
    使用操作符 IS NULL
    // 查詢含有購買者的所有 Order
    select o from Order as o where o.ower is [not] null
     
    使用操作符 IS EMPTY
    IS EMPTY 是針對集合屬性 (Collection) 的操作符 。可以和 NOT 一起使用 注:低版權的 Mysql 不支持 IS EMPTY
    // 查詢含有訂單項的所有 Order
    select o from Order as o where o.orderItems is [not] empty
     
    使用操作符 EXISTS
    [NOT]EXISTS 需要和子查詢配合使用 。注:低版權的 Mysql 不支持 EXISTS
    // 如果存在訂單號為 1 的訂單,就獲取所有 OrderItem
    select oi from OrderItem as oi where exists (select o from Order o where o.orderid=1)
    // 如果不存在訂單號為 10 的訂單,就獲取 id 1 OrderItem
    select oi from OrderItem as oi where oi.id=1 and not exists (select o from Order o where o.orderid=10)
     
     
    字符串函數
    JPQL 定義了內置函數方便使用。這些函數的使用方法和 SQL 中相應的函數方法類似。包括:
    1. CONCAT 字符串拼接
    2. SUBSTRING 字符串截取
    3. TRIM 去掉空格
    4. LOWER 轉換成小寫
    5. UPPER 裝換成大寫
    6. LENGTH 字符串長度
    7. LOCATE 字符串定位
     
    例:
    // 查詢所有人員,并在姓名后面加上字符串 "_foshan"
    select p.personid, concat(p.name, '_foshan') from Person as p
    // 查詢所有人員 , 只取姓名的前三個字符
    select p.personid, substring (p.name,1,3) from Person as p
     
    計算函數
    HPQL 定義的計算函數包括:
    ABS 絕對值
    SQRT 平方根
    MOD 取余數
    SIZE 取集合的數量
     
    例:
    // 查詢所有 Order 的訂單號及其訂單項的數量
    select o.orderid, size (o.orderItems) from Order as o group by o.orderid
    // 查詢所有 Order 的訂單號及其總金額 /10 的余數
    select o.orderid, mod (o.amount, 10) from Order as o
     
     
    子查詢
    子查詢可以用于 WHERE HAVING 條件語句中
    例:
    // 查詢年齡為 26 歲的購買者的所有 Order
    select o from Order as o where o.ower in(select p from Person as p where p.age =26)
     
     
    結果集分頁
    有些時候當執行一個查詢會返回成千上萬條記錄,事實上我們只需要顯示一部分數據。這時我們需要對結果集進行分頁 QueryAPI 有兩個接口方法可以解決這個問題: setMaxResults( ) setFirstResult( )
     
    setMaxResults 方法設置獲取多少條記錄
    setFirstResult 方法設置從結果集中的那個索引開始獲取 (假如返回的記錄有 3 條,容器會自動為記錄編上索引,索引從 0 開始,依次為 0 1 2
     
    例:
    public List getPersonList( int max, int whichpage) {
    try {
    int index = (whichpage-1) * max;
    Query query = em .createQuery( "from Person p order by personid asc" );
    List list = query. setMaxResults(max) .
    setFirstResult(index) .
    getResultList();
    em .clear(); // 分離內存中受EntityManager管理的實體bean,讓VM進行垃圾回收
    return list;
    }

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 特级毛片A级毛片免费播放| 高清看男人插曲女人视频 | 国产很色很黄很大爽的视频| 奇米影视7777狠狠狠狠色| 国产一区二区三区在线观看免费| 色爱综合激情五月激情| 国产果冻豆传媒麻婆精东| 熟女一区二区中文字幕| H无码动漫在线观看| 99久久er热在这里只有精品99| 国产成熟妇女性视频电影| 宅男在线永久免费观看网| 少妇办公室好紧好爽再浪一点| 97久久天天综合色天天综合色HD| 天天做天天爱夜夜爽导航 | 人妻丝袜无码专区视频网站| 一級特黃色毛片免費看| 丝袜人妻一区二区三区网站| 亚洲第一极品精品无码| 日韩精品有码中文字幕| 爱情岛亚洲论坛成人网站| 偷拍精品一区二区三区| 无码精品一区二区三区在线| 欧美熟妇性XXXX欧美熟人多毛| 国产偷窥熟女高潮精品视频| 日韩在线看片免费观看软件| 日本深夜福利在线观看| 精品久久香蕉国产线看观看亚洲| 成人网站免费观看永久视频下载| 国产精品国产三级国产AV中文| 少妇太爽了在线观看免费视频| 欧美福利电影A在线播放| 中文字幕AV无码人妻| 狠狠色丁香婷婷综合尤物| 中文字幕人妻日韩精品| 亚洲成AV人片不卡无码手机版 | 真实国产老熟女无套中出| 欧美牲交a欧美牲交aⅴ图片| 日本XXXX色视频在线观看免费| 亚洲 制服 丝袜 无码| 亚洲精品日韩在线观看|