注意区分:
1.import org.hibernate.Query;
2.import javax.persistence.Query;
1是hibernate的query接口,后面是jpa的query,在使用hibernate的时候用前面。
1的query接口没有实现泛型,使用时必须强制转换
2的query支持泛型。
通过session可以创建一个Query对象。
Query q = session
.createQuery("from Category c where c.id > ? and c.id < ?");
q.setParameter(0, 2).setParameter(1, 8);
createQuery()方法支持这里?占位符,通过setParameter()方法设置占位符的值,此方法还是返回Query接口对象,注意这里的占位符序号从0开始,而JDBC中preparedStatement中的占位符序号从1开始。
createQuery()方法还是可以指定占位符的名称
Query q = session
.createQuery(
"from Category c where c.id > :min and c.id < :max")
.setInteger("min", 2).setInteger("max", 8);
通过:XXX设置占位符的名称
创建NativeSQL的方式:
@Test
public void testHQL_34() {
Session session = sf.openSession();
session.beginTransaction();
SQLQuery q = session.createSQLQuery(
"select * from category limit 2 offset 2").addEntity(
Category.class);
List<Category> categories = (List<Category>) q.list();
for (Category c : categories) {
System.out.println(c.getName());
}
session.getTransaction().commit();
session.close();
}
QBC:
@Test
public void testQBC() {
Session session = sf.openSession();
session.beginTransaction();
//criterion 标准/准则/约束
Criteria c = session.createCriteria(Topic.class) //from Topic
.add(Restrictions.gt("id", 2)) //greater than = id > 2
.add(Restrictions.lt("id", 8)) //little than = id < 8
.add(Restrictions.like("title", "t_"))
.createCriteria("category")
.add(Restrictions.between("id", 3, 5)) //category.id >= 3 and category.id <=5
;
//生成的sql语句
// Hibernate:
// select
// this_.id as id2_1_,
// this_.category_id as category4_2_1_,
// this_.createDate as createDate2_1_,
// this_.title as title2_1_,
// category1_.id as id0_0_,
// category1_.name as name0_0_
// from
// Topic this_
// inner join
// Category category1_
// on this_.category_id=category1_.id
// where
// this_.id>?
// and this_.id<?
// and this_.title like ?
// and category1_.id between ? and ?
//DetachedCriterea
for(Object o : c.list()) {
Topic t = (Topic)o;
System.out.println(t.getId() + "-" + t.getTitle());
}
session.getTransaction().commit();
session.close();
}
QBE:
@Test
public void testQBE() {
Session session = sf.openSession();
session.beginTransaction();
Topic tExample = new Topic();
tExample.setTitle("T_");
//QBE适合于这种场景,如在网页中根据过滤条件查询产品,只要new一个产品对象,然后将网页中拿到的值
//设置进去,然后直接用这个对象去匹配数据库中的记录,这样很方便。
Example e = Example.create(tExample)
.ignoreCase().enableLike();
Criteria c = session.createCriteria(Topic.class)
.add(Restrictions.gt("id", 2))
.add(Restrictions.lt("id", 8))
.add(e)
;
//生成的sql语句为:
// Hibernate:
// select
// this_.id as id2_0_,
// this_.category_id as category4_2_0_,
// this_.createDate as createDate2_0_,
// this_.title as title2_0_
// from
// Topic this_
// where
// this_.id>?
// and this_.id<?
// and (
// lower(this_.title) like ?
// )
for(Object o : c.list()) {
Topic t = (Topic)o;
System.out.println(t.getId() + "-" + t.getTitle());
}
session.getTransaction().commit();
session.close();
}
@JoinColumn(name="student_id")
public Student getStudent() {
return student;
}
表明在当前类中有一个字段叫student_id,参考了Student(由getXXX()中XXX部分决定)实体中的主键。
@JoinTable(
name="s_c",
joinColumns=
@JoinColumn(name="student_id"),
inverseJoinColumns=
@JoinColumn(name="course_id")
)
public Set<Course> getCourses() {
return courses;
}
表明产生一个中间表s_c,该表有两个字段,其中student_id参考了本类中的主键,course_id参考了Course中的主键
hibernate在关联关系映射下,如一对多与多对多的情况下,一个类中有另一个类的集合(Set),此时若从这个类对应表中get对象的时候,hibernate会自动的设置好这个集合的值。