查找和加载产品
查找和加载已经持久化的对象在Hibernate中非常简单。使用它的查询语言,我们可以很容易地通过ID、名称或其他属性获取一个对象(或对象集)。我们能够获取完整的对象或它的一部分属性。Hibernate将处理余下的工作,最后,我们将拥有相当有用的对象层次体系。我们来看一下test.FindProductByName类。
package test;
import java.util.List;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;
import test.hibernate.Product;
// 用法:
// java test.FindProductByName name
public class FindProductByName {
public static void main(String[] args) throws Exception {
// 执行的查询
String query =
"select product from product "
+ "in class test.hibernate.Product "
+ "where product.name=:name";
// 搜索的内容
String name = args[0];
// 初始化
Configuration cfg = new Configuration()
.addClass(Product.class);
SessionFactory sf = cfg.buildSessionFactory();
// 打开会话
Session sess = sf.openSession();
// 搜索并返回
List list = sess.find(query, name,
Hibernate.STRING);
if (list.size() == 0) {
System.out.println("No products named "
+ name);
System.exit(0);
}
Product p = (Product) list.get(0);
sess.close();
System.out.println("Found product: " + p);
}
}
在FindProductByName中有几点值得注意:
* 有一个具有where子句的query字符串,这与标准SQL语句很相似。
* 初始化Hibernate的方法与第一个示例中一样。这一次,我们有配置文件和映射文件。
* sess.find()执行查询,并将提供的产品名称设置为类型Hibernate.STRING的搜索参数。
* 作为结果,我们得到一个包含所找到的Product的java.util.List。
* 使用Product p = (Product) list.get(0); 我们用通常的类型转换方法获取找到的对象。
执行java test.FindProductByName Milk,查看显示在控制台中的内容。
注意:查询是区分大小写的,所以搜索小写的milk将不会返回任何结果。使用lower()或upper()SQL函数来启用不区分大小写的搜索。在这种情况下,我们会在查询字符串中使用where lower(product.name)=lower(:name)。关于查询的详细内容,请参见文档。此外,如果不希望显示所有的INFO日志信息,可以修改log4j.properties文件,将日志等级设置为warn。
更新和删除产品
到现在为止,您应该对Hibernate的工作方式有了一个基本的了解,因此我们将缩短冗长的示例,只显示重要的部分。
为了在单个事务中将所有产品的价格提高10%,我们可以编写如下的内容:
double percentage = Double.parseDouble(args[0])/100;
sess = sf.openSession();
Transaction t = sess.beginTransaction();
// 列表包含产品
Iterator iter = list.iterator();
while (iter.hasNext()) {
Product p = (Product) iter.next();
p.setPrice(p.getPrice() * (1 + percentage));
sess.saveOrUpdate(p);
}
t.commit();
sess.close();
最后,要删除Product,当然要调用sess.delete(product)。如果数据库关闭了autocommit,不要忘记调用commit()提交Transaction。
现在,我们已经完成了针对单个对象的所有基本操作——创建、读取、更新和删除。看上去相当有趣,但我们可以做得更好。现在我们来学习如何操纵对象集而不需要编写SQL语句。所有的魔法都通过映射文件实现。
