多表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>