A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

先简单给大家介绍下关于hibernate重点额检索方式吧~
整体是分为5种方式,分别为
1.oid检索
2.导航对象检索
3.本地sql
4.qbc
5.hql
其中HQL在实际开发中比较常用,所以先给大家整理一份关于HQL的相关资料吧~
其实关于HQL,我是基于下面3个方向来演示
1.标准hql
2.hql命名检索
3.hql多表

ok.话不多说,往下看吧~

首先我们要玩转hibernate,那么核心的对象就是SessionFactory对象了~
那么关于HQL使用步骤呢?我整理了下,大概可以分为5步:
        a)通过SessionFactory获取session对象
        b)编写HQL语句
        c)通过session.createQuery(hql)获取一个query对象
        d)为query对象设置参数
        e)执行对应方法        query.list()返回一个集合/query.uniqueResult()返回一个结果


1.标准HQL

        1)基本检索   from 类名
        eg:
[Java] 纯文本查看 复制代码
		//关键字不区分大小写,类名区分
		String hql = "from Customer"; 
		Query query = session.createQuery(hql).list();

               
        2)排序检索        from 类名 order by 属性 asc/desc
        eg:

[Java] 纯文本查看 复制代码
		String hql = "from Order order by money desc"; // desc 降序 默认是asc 升序
		List<Order> list = session.createQuery(hql).list();

               
        3)条件检索  
       
                方式一:from 类名 where 属性=? and 属性=?
                eg:
[AppleScript] 纯文本查看 复制代码
			 String hql = "from Order where money>? and name=?"; 
			 List<Order> list = session.createQuery(hql)
										.setParameter(0,2000)
										.setParameter(1,"张三")
										.list();

                                                                               
                方式二:from 类名 where 属性 = :名称
                注意:名称随意,要和后面setParameter中的key对应起来
                eg:
[Java] 纯文本查看 复制代码
			 String hql = "from Order where money>:mmmoney and name=:nnname"; 
			 List<Order> list = session.createQuery(hql)
										.setParameter("mmmoney",2000)
										.setParameter("nnname","张三")
										.list();


        4)分页检索                query.setFirstResult(开始位置)和query.setMaxResults(多少条)
        eg:
[Java] 纯文本查看 复制代码
		Query query = session.createQuery("from Order");
		// 每页显示6条件 ,我们要得到第二页数据
		query.setFirstResult((2 - 1) * 6); // 设定开始位置
		query.setMaxResults(6); // 设置条数
		List<Order> list = query.list();

               
        5)分组统计检索       
               
                统计:  select 统计函数(属性) from 类名
                eg:
[Java] 纯文本查看 复制代码
			String hql="select count(*) from Order";
			Object count = session.createQuery(hql).uniqueResult();

                       
                分组:  select 统计函数(属性) from 类名 group by 属性
                eg:
[Java] 纯文本查看 复制代码
			String hql="select count(*) from Order group by mCostomer";
			Object count = session.createQuery(hql).uniqueResult();


        6)投影检索(将查询结果封装到po中)         select new 类名(属性1,属性2) from 类名
               
                eg:
[Java] 纯文本查看 复制代码
		//必须在PO类中提供无参和对应参数的构造方法
		String hql = "select new Customer(id,name) from Customer";
		List<Customer> cs = session.createQuery(hql).list();


2.hql命名检索

方式一:        XXX.hbm.xml文件配置hql命名

        a)定义Order实体类
       
[Java] 纯文本查看 复制代码
		public class Order {
			private Integer id;
			private Double money;//金额			
			private String receiverInfo; // 收货地址			
			private Customer mCustomer;// 订单与客户关联

			//省略get/set方法
			......
		}

               
        b)定义Order.hbm.xml

[Java] 纯文本查看 复制代码
		<?xml version="1.0" encoding="UTF-8"?>
		<!DOCTYPE hibernate-mapping PUBLIC 
			"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
			"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
		<!-- package属性代表javabean所在的包 -->
		<hibernate-mapping package="com.b3a4a.domain">
			<class name="Order" table="t_order" catalog="db_hibernate_study">
				<id name="id" column="id"> 
					<generator class="native"></generator>
				</id>
				<property name="name" column="name" length="20"></property>
				......
			</class>
			<query name="HQL名称 (eg:findOrderByCustomer)">
				HQL语句  (eg: from Order where mCustomer:mmmmmCustomer)
			</query>
		</hibernate-mapping> 

               
        c)配置核心文件hibernate.cfg.xml
       
[Java] 纯文本查看 复制代码
<?xml version="1.0" encoding="UTF-8"?>
		<!DOCTYPE hibernate-configuration PUBLIC
			"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
			"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
		<hibernate-configuration>
			<session-factory>
				......
				<mapping resource="com/b3a4a/domain/Order.hbm.xml" />
			</session-factory>
		</hibernate-configuration>	
       
        d)测试用例
       
[Java] 纯文本查看 复制代码
		@Test
		public void test() {
			Session mSession = new Configuration().configure()
											.buildSessionFactory()
											.openSession();
			mSession.beginTransaction();
			
			//----------------关键代码----------------
			// 1.我要查询张三这个客户的订单
			Customer c = mSession.get(Customer.class, 1);
			Query query = mSession.getNamedQuery("findOrderByCustomer"); // from Order  where c=:c
			// 2.现在hql它的参数是一个实体
			List<Order> list = query.setEntity("mmmmmCustomer", c).list();
			//----------------------------------------
			
			mSession.getTransaction().commit();
			mSession.close();
		}




方式二:        PO注解配置hql命名

        a)定义Order实体类,使用注解配置hql命名
       
[Java] 纯文本查看 复制代码
		@Entity
		@Table(name = "t_order")
		//name:HQL名称
		//query:HQL语句
		@NamedQuery(name="findOrderByCustomer",query="from Order where mCustomer=:mmmmmCustomer")
		public class Order {
			@Id
			@GeneratedValue(strategy = GenerationType.IDENTITY)
			private Integer id;//主键
			
			private Double money;//金额
			
			private String receiverInfo; // 收货地址
			
			@ManyToOne(targetEntity = Customer.class)
			@JoinColumn(name = "c_customer_id")
			@Cascade(CascadeType.SAVE_UPDATE)
			private Customer mCustomer;// 订单与客户关联

			//省略get/set方法
			......
		}

               
        b)测试用例
       
[Java] 纯文本查看 复制代码
		@Test
		public void test() {
			Session mSession = new Configuration().configure()
											.buildSessionFactory()
											.openSession();
			mSession.beginTransaction();
			
			//----------------关键代码----------------
			// 1.我要查询张三这个客户的订单
			Customer c = mSession.get(Customer.class, 1);
			Query query = mSession.getNamedQuery("findOrderByCustomer"); // from Order  where c=:c
			// 2.现在hql它的参数是一个实体
			List<Order> list = query.setEntity("mmmmmCustomer", c).list();
			//----------------------------------------
			
			mSession.getTransaction().commit();
			mSession.close();
		}


               


3.hql多表

hql多表常用的方式分为内连接,外链接

注意:
a)HQL中with就相当于SQL中的on
b)fetch不可以与单独条件的with一起使用



内链接
        显式内链接:         from 类名 别名 inner join 别名.从表对象 where 条件 (with 条件)
        eg:
       
[Java] 纯文本查看 复制代码
// sql连接 select * from t_customer inner join t_order on 条件 
		String hql = "from Customer c inner join c.orders with c.id=1";
		Query query = session.createQuery(hql);
		// Object[]中装入的是Customer与Order对象。
		List<Object[]> list = query.list(); 
                                                                                       
       
        隐式内链接:   from 类名 别名 where 别名.从表对象.从表属性 = 条件
        eg:
       
[Java] 纯文本查看 复制代码
		// sql连接 select * from t_customer,t_order where 条件
		String hql = "from Order o where o.c.id=1";
		
		Query query = session.createQuery(hql);
		List list = query.list();

               
               
        迫切内链接:                from 类名 别名 inner join fetch 别名.从表对象 where 条件
        eg:
       
[Java] 纯文本查看 复制代码
		// 迫切内连接 inner join fetch 注意:使用迫切连接结果可能出现重复,所以要使用distinct来去重复
		String hql = "select distinct c from Customer c inner join fetch c.orders";
		// 底层也是执行的inner join 只不过结果封装到对象中。

		Query query = session.createQuery(hql);
		List<Customer> list = query.list();


外连接
        左外连接:        from 类名 别名 left outer join 别名.从表对象 where 条件
        eg:
       
[Java] 纯文本查看 复制代码
		List<Object[]> list = session
					.createQuery("from Customer c left outer join c.orders").list();

       
        右外连接
        迫切左外连接
        eg:
       
[Java] 纯文本查看 复制代码
		// 注意:fetch不可以与单独条件的with一起使用
		List<Customer> list = session
				.createQuery("select distinct c from Customer c left outer join fetch c.orders where c.id=1").list();



1 个回复

倒序浏览

回帖奖励 +1

加油加油
来自宇宙超级黑马专属安卓客户端来自宇宙超级黑马专属安卓客户端
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马