EJB3 QL

1.Entity 获取 find()或 getReference()

           1)如果知道 Entity的唯一标示符,我们可以用 find()或 getReference()方法来获得 Entity。

           2)当在数据库中没有找到记录时,getReference()和 find()是有区别的,find()方法会返回 null,而 getReference()方法会抛出 javax.persistence.EntityNotFoundException 例外,另外 getReference()方法不保证实体 Bean 已被初始化。
如果传递进 getReference()或 find()方法的参数不是实体 Bean,都会引发 IllegalArgumentException 例外。

           3)还可以通过JPQL得到实体Bean。要执行 JPQL语句,你必须通过 EntityManager 的 createQuery()或 createNamedQuery()方法创建一个 Query对象。也会抛javax.persistence.EntityNotFoundException

有时我们不喜欢异常,需要null,          find() method is very useful.

2.em.remove(entity), 删除的是受控的实体,所以在删除前确保实体是受控的,如果不是,还需要处理下。

public void removeCabin(int id) {

   Cabin cabin = entityManager.find(Cabin.class, id);

   entityManager.remove(cabin);

}

级联

Refresh与merge相似。唯一的区别是,它只在EntityManager.refresh()被调用的时候才起作用。当刷新一个对

象时,与之关联的对象也会被刷新。

如果发现当前受托管的实体并非数据库中的最新数据,你可以调用EntityManager. refresh()方法。refresh()方法会根据数据库的情况刷新内存中实体的状态,同时覆盖对实体所做的任何修改。当entity bean有一些成员属性,其取值要由数据库来生成时,refresh()方法就非常有用了。

refresh()

@PersistenceContext EntityManager entityManager;

@TransactionAttribute(REQUIRED)

public void refreshCabin(int id) {

   Cabin cabin = entityManager.find(Cabin.class, id);

   entityManager.refresh(cabin);

}

如果entity bean有关联实体,那么根据在实体映射元数据中设置的级联策略,那些关联实体也会被相应刷新。

contains() and clear()

contains()方法接受实体实例作为参数,如果该对象实例目前正受persistence context管理,则返回true。若该参数并非实体类型,则会抛出IllegalArgumentException异常。

你可以使用EntityManager.clear()方法将persistence context中所有的托管实体都变成游离对象需要注意的是,一旦你调用了clear()方法,对实体所做的任何修改都将被丢弃。因此,使用clear()时需要格外小心。在调用clear()之前,先调用flush()方法以免丢失更改实为明智之举。

flush() and FlushModeType

flush()则是将持久化上下文中所有实体的状态同步到数据库中。

缺省情况下,flush操作会在相关查询执行之前和事务提交之时自动执行,但与一般查询不同,调用find()和

getReference()方法并不会引起flush。这是因为通过主键来查询实体是不会受任何更新操作的影响的。
FlushModeType.COMMIT仅当事务提交时才对更改做flush操作,而在任何查询之前都不会引发flush操作。

尽管如此,出于性能的考虑,FlushModeType.COMMIT也是有用武之地的。数据库应用调优的最好办法就是减少不必要的数据库访问。

Java EE环境中,EntityManager的persistence context通常是由JTA事务管理的。但在非Java EE环境中是无法使用JTA事务的,

3.
查询中使用构造器(Constructor)(笔者项目中用到此法,非常适合多表查询)
//我们把需要的两个属性作为SimplePerson的构造器参数,并使用new函数。
Query query = em.createQuery("select new com.foshanshop.ejb3.bean.SimplePerson(p.name,p.sex)
from Person p order by p.personid desc");
//集合中的元素是SimplePerson对象

4.聚合查询(Aggregation)
   1). AVG()
   2). SUM()
   3). COUNT()
   4). MAX()
   5). MIN()

5. Group by 应该包含select语句中除了聚合函数外的所有属性,

HAVING子句必须针对GROUP BY中的参数或其他聚合函数给定限制条件。

6.关联(join)
inner join要求右边的表达式必须返回Entities。

left out join/left join等,都是允许符合条件的右边表达式中的Entiies 为空。

left/left out/inner join fetch提供了一种灵活的查询加载方式来提高查询的性能。在默认的查询中,Entity中的集合
属性默认不会被关联,集合属性默认是缓加载( lazy-load )

// 默认EJB3 QL编译后不关联集合属性变量(orderItems)对应的表
select o from Order o inner join o.orderItems where o.ower.age=26
order by o.orderid");

当执行到Set<OrderItem> list = order.getOrderItems();时才会执行一条SQL语句来加载属于当前Order 的OrderItems;

这样的查询性能上有不足的地方。为了查询N 个Order,我们需要一条SQL语句获得所有的Order 的原始对象属性, 但需要另外N 条语句获得每个Order orderItems 集合属性。

为了避免N+1的性能问题,我们可以利用join fetch一次过用一条SQL语句把Order 的所有信息查询出来

7.比较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);

8.使用操作符NOT
"select o from Order o where not(o.ower =?1) order by o.orderid" ;

9.使用操作符IS NULL


10.使用操作符IS EMPTY
IS EMPTY 是针对集合属性(Collection)的操作符

11.使用操作符EXISTS
EXISTS需要和子查询配合使用。

12.字符串函数
    1). CONCAT 字符串拼接 concat(p.name, '_foshan')
    2). SUBSTRING 字符串截取 substring(p.name,1,3)
    3). TRIM 去掉空格
    4). LOWER 转换成小写
    5). UPPER 装换成大写
    6). LENGTH 字符串长度
    7). LOCATE 字符串定位

13.计算函数
   ABS 绝对值
   SQRT 平方根
   MOD 取余数
   SIZE 取集合的数量

14.子查询
子查询可以用于WHERE和HAVING 条件语句中

15.结果集分页
List list = query.setMaxResults(max).
setFirstResult(index).
getResultList();
em.clear();//分离内存中受EntityManager管理的实体bean,让VM进行垃圾回收
如果我们需要显示大量的实体Bean,假如记录成千上万,通过简单的循环处理,我们将很快消耗完内存,为此我
们需要在显示了一部分实体bean之后调用EntityManager.clear()及时把这些实体bean从EntityManager 分离出来,
让Java VM 对他们进行垃圾回收。

6.9 调用存储过程

要调用存储过程,我们可以通过EntityManager 对象的createNativeQuery()方法执行SQL 语句

(注意:这里说的是SQL语句,不是EJB3 QL), 调用存储过程的SQL格式如下:
{call 存储过程名称(参数1, 参数2, …)}
在EJB3 中你可以调用的存储过程有两种
1.无返回值的存储过程。
2.返回值为ResultSet(以select形式返回的值)的存储过程,EJB3 不能调用以OUT参数返回值的存储过程。


1)调用返回单值的存储过程
2)调用返回表全部列的存储过程
3)调用返回部分列的存储过程
CREATE PROCEDURE `GetPersonPartProperties`()
NOT DETERMINISTIC
SQL SECURITY DEFINER
COMMENT ''
BEGIN
SELECT personid, personname from person;
END;


Query query = em.createNativeQuery("{call GetPersonPartProperties()}");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值