日期:2014-05-16  浏览次数:20601 次

oracle 绑定变量&&hibernate应用
oracle 中,对于一个提交的sql语句,存在两种可选的解析过程, 一种叫做硬解析,一种叫做软解析.
一个硬解析需要经解析,制定执行路径,优化访问计划等许多的步骤.硬解释不仅仅耗费大量的cpu,更重要的是会占据重要的们闩(latch)资源,严重的影响系统的规模的扩大(即限制了系统的并发行),而且引起的问题不能通过增加内存条和cpu的数量来解决。
之所以这样是因为门闩是为了顺序访问以及修改一些内存区域而设置的,这些内存区域是不能被同时修改。当一个sql语句提交后,oracle会首先检查一下共享缓冲池(shared pool)里有没有与之完全相同的语句,如果有的话只须执行软分析即可,否则就得进行硬分析。
而唯一使得oracle 能够重复利用执行计划的方法就是采用绑定变量。绑定变量的实质就是用于替代sql语句中的常量的替代变量。绑定变量能够使得每次提交的sql语句都完全一样。
普通sql语句:

SELECT fname, lname, pcode FROM cust WHERE id = 674;
SELECT fname, lname, pcode FROM cust WHERE id = 234;
SELECT fname, lname, pcode FROM cust WHERE id = 332;
含绑定变量的sql 语句:
SELECT fname, lname, pcode FROM cust WHERE id = :cust_no;

Sql*plus 中使用绑定变量:
sql> variable x number;
sql> exec := 123;
sql> SELECT fname, lname, pcode FROM cust WHERE id =:x;

pl/sql
pl/sql很多时候都会自动绑定变量而无需编程人员操心,即很多你写得sql语句都会自动利用绑定变量,如下例所示:

create or replace procedure dsal(p_empno in number)
as
begin
update emp
set sal=sal*2
where empno = p_empno;
commit;
end;
/


也许此时你会想要利用绑定变量来替代p_empno,但是这是完全没有必要的,因为在pl/sql中,引用变量即是引用绑定变量。
但是在pl/sql中动态sql并不是这样。
在vb,java以及其他应用程序中都得显式地利用绑定变量。
对于绑定变量的支持不仅仅限于oracle,其他RDBMS向SQLSERVER也支持这一特性。
但是并不是任何情况下都需要使用绑定变量, 下面是两种例外情况:
1.对于隔相当一段时间才执行一次的sql语句,这是利用绑定变量的好处会被不能有效利用优化器而抵消
2.数据仓库的情况下。


####################################################

hibernate绑定参数类型
hibernate绑定参数类型

(1)使用 ? 指定参数
...
Query query = session.createQuery("from Student s where 
              s.age > ? and s.name like ? ");
query.setInteger(0,18);
query.setString(1,"%abc%");
...

(2)使用 : 后跟变量的方法设置参数
...
Query query = session.createQuery("from Student s where 
              s.age > :minAge and s.name like :likeName ");
query.setInteger("minAge",18);
query.setString("likeName","%ABC%");
...


(3)setEntity()方法

setEntity()方法把参数与一个持久类的实例绑定,例如下面的示例
...
Team team = (Team)session.get(Team.class,"5f45saf45sdf456f");
Query query = session.createQuery("from Student s where s.team = :team");
query.setEntity("team",team);  //设置参数为team实例
...

注:上述的team对象可以是持久对象也可以是脱管对象

(4)setParameter()方法

setParameter()方法的全称是setParameter(String paraName,实例,实例类型),这个方法
可以绑定任何类型的参数.其中第三个参数可以省略,hibernate要以根据实例推断出绝大部分
对应的映射类型.
下面将(3)中的代码做一下改动
query.setParameter("team",team,Hibernate.entity(Team.class)).
或者query.setparameter("team",team).

(5)setPorperties()方法

该方法的全称是setProperties(类实例).它将类实例的属性名与参数值相对应
...
Student student = new Student();
student.setAge("18");
Query query = sesion.createQuery("from Student s where s.age = :age");
query.setProperties(student);  //设置参数为student对象
...

注意:HQL语句中的变量age必须和student的属性age同名,否则会出错.