多表HQL
private static void innerJoin(){ //sql内连接 隐式内连接 select * from A,B where b.aid = a.id // 显示内连接 select * from A inner join B on b.aid = a.id //hql内连接 =>类似原生sql 返回合并的 Query query = session.createQuery("from Category c inner join c.products"); List<Object> objs = query.list(); for(Object o : objs){ System.out.println(o); } } private static void innerJoinfetch(){ //迫切hql内连接 =>帮我进行封装 Query query = session.createQuery("from Category c inner join fetch c.products"); List<Category> categorys = query.list(); for(Category o : categorys){ System.out.println(o.getCname()); for(Product p : o.getProducts()){ System.out.println(p.getPname()); } } } private static void leftJoin(){ //外连接 左外连接 select * from A left [outer] join B on b.aid = a.id //hql 左连接 Query query = session.createQuery("from Category c left join c.products"); List<Object> objs = query.list(); for(Object o : objs){ System.out.println(o); } } private static void leftJoinfetch(){ //hql 左连接 迫切 Query query = session.createQuery("from Category c left join fetch c.products"); List<Category> categorys = query.list(); for(Category o : categorys){ System.out.println(o.getCname()); for(Product p : o.getProducts()){ System.out.println(p.getPname()); } } } private static void rightJoin(){ //外连接 右外连接 select * from A right [outer] join B on b.aid = a.id //hql右连接 Query query = session.createQuery("from Category c right join c.products"); List<Object> objs = query.list(); for(Object o : objs){ System.out.println(o); } } private static void rightJoinfetch(){ //外连接 右外连接 select * from A right [outer] join B on b.aid = a.id //hql右连接 迫切 Query query = session.createQuery("from Category c right join fetch c.products"); List<Category> categorys = query.list(); for(Category o : categorys){ System.out.println(o.getCname()); for(Product p : o.getProducts()){ System.out.println(p.getPname()); } } }
Criteria(QBC)离线查询对象
//传统criteria是依赖于session的 Criteria criteria = session.createCriteria(Category.class); criteria.add(Restrictions.eq("cid",1)); Category c = (Category) criteria.uniqueResult(); System.out.println(c.getCname()); //离线的criteria 凭空创建 //service/web层 DetachedCriteria dc = DetachedCriteria.forClass(Category.class); dc.add(Restrictions.gt("cid",0)); //dao层 Criteria criter = dc.getExecutableCriteria(session); List<Category> categories = criteria.list(); for(Category ca : categories){ System.out.println(ca.getCname()); for(Product p : ca.getProducts()){ System.out.println(p.getPname()); } }
查询优化策略
懒加载(延迟加载):使用hibernate查询一个对象的时候,查询其关联对象,应该如何查询。是hibernate的一种优化手段。
类级别查询
session对象的load方法默认就是延迟加载, 可以在对象对应的配置文件中 class节点中配置lazy属性控制是否启用。如果false则会跟get没有任何区别。
public static void main(String[] args) { Session session = HibernateUtils.openSession(); //get方法:立即加载,执行时立即发送sql语句 Category c = session.get(Category.class,1); System.out.println(c); //延迟加载:仅仅获得没有使用,不会查询 返回代理对象 Category c1 = session.load(Category.class,2); //在使用对象的属性时才会进行查询 System.out.println(c1.getCname()); }
关联级别查询
集合关联级别
public static void main(String[] args) { Session session = HibernateUtils.openSession(); //只返回Category表 Category c = session.get(Category.class,1); System.out.println(c.getCname()); //懒加载 与此Category表相关联的Product表 使用时 才去加载 Set<Product> ps = c.getProducts(); //集合关联级别 for(Product p : ps){ System.out.println(p.getPname()); } }
附上配置文件Category.hbm.xml
<hibernate-mapping package="com.hibernate.domain"> <class name="Category" table="Category" lazy="true"> <id name="cid" column="cid"> <generator class="native"/> </id> <property name="cname"/> <!--lazy:集合关联级别 是否懒加载 true(默认) false extra(极其懒惰-如果只获得集合的size,他会用count去查询) fetch(加载策略-使用什么类型的sql语句加载集合数据): select(默认):单表查询加载 join:使用多表查询加载集合(无论是否启用懒加载,都一下多表查询回来) subselect:使用子查询加载集合(调用集合时,使用子查询语句) --> <set name="products" inverse="true" lazy="true" fetch="select"> <key column="cpid"></key> <one-to-many class="Product"></one-to-many> </set> </class> </hibernate-mapping>
关联属性级别
public static void main(String[] args) { Session session = HibernateUtils.openSession(); Product p = session.get(Product.class,1); //根据产品去获得分类信息 执行如下时才会去数据库获取 Category c = p.getCategory(); //属性关联级别 System.out.println(c.getCname()); }
配置xml解析
<hibernate-mapping package="com.hibernate.domain"> <class name="Product" table="Product"> <id name="pid"> <generator class="native"/> </id> <property name="pname"/> <!--fetch(加载的sql语句): select(默认):使用单表查询 join:使用多表查询 lazy(加载时机): proxy(默认):由Category的类级别加载策略(Category中 class元素中 lazy)决定 false:立即加载 --> <many-to-one name="category" class="Category" column="cpid" fetch="" lazy=""></many-to-one> </class> </hibernate-mapping>
批量抓取
public static void main(String[] args) { Session session = HibernateUtils.openSession(); Query query = session.createQuery("from Category"); List<Category> categories = query.list(); for(Category c : categories){ for(Product p : c.getProducts()){ //categories数量为几 这里就要执行几次sql查询c.getProducts() System.out.println(p.getPname()); } } }
category.hbm.xml
<hibernate-mapping package="com.hibernate.domain"> <class name="Category" table="Category" lazy="true"> <id name="cid" column="cid"> <generator class="native"/> </id> <property name="cname"/> <!--batch-size:查询集合时一次查询多少个 默认1个 所以每次都会生成sql语句 --> <set name="products" inverse="true" lazy="true" fetch="select" batch-size="10"> <key column="cpid"></key> <one-to-many class="Product"></one-to-many> </set> </class> </hibernate-mapping>