多表HQLweb
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)离线查询对象sql
//传统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
类级别查询app
session对象的load方法默认就是延迟加载, 能够在对象对应的配置文件中 class节点中配置lazy属性控制是否启用。若是false则会跟get没有任何区别。dom
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()); }
关联级别查询fetch
集合关联级别优化
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.xmlspa
<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>
关联属性级别hibernate
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>