1 Hibernate的查询方式
1.1 Hibernate的查询方式
- 在Hibernate中有提供了很多种的查询方式。
- OID查询。
- 对象导航查询。
- HQL查询。
- QBC查询。
- SQL查询。
Hibernate一共提供了5种查询方式:
1.2 OID查询
- OID检索:HIbernate根据对象的OID(主键)查询。例如:使用get或load方法查询对象。
1.3 对象导航查询
- Hibernate根据一个已经查询到的对象,获取其关联对象的一种查询方式。例如:先查询到了联系人的信息,然后通过联系人对象获取对应的客户信息。
1.4 HQL查询
- HQL:Hibernate查询语言,是一种面向对象的方式的查询语言,语法类似SQL。通过session.createQuery(),用于接收一个HQL进行查询的方式。
1.4.1 搭建环境并进行数据初始化
- Customer.java
package com.xuweiwei.hibernate; import java.util.HashSet; import java.util.Set; /** * 客户 * * @author 许威威 */ public class Customer { /** * 客户编号(主键) */ private Long id; /** * 客户名称(公司名称) */ private String name; /** * 客户信息来源 */ private String source; /** * 客户所属行业 */ private String industry; /** * 客户级别 */ private String level; /** * 固定电话 */ private String phone; /** * 移动电话 */ private String mobile; //一个客户有多个联系人 private Set<LinkMan> linkMans = new HashSet<>(); public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } public String getIndustry() { return industry; } public void setIndustry(String industry) { this.industry = industry; } public String getLevel() { return level; } public void setLevel(String level) { this.level = level; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public Set<LinkMan> getLinkMans() { return linkMans; } public void setLinkMans(Set<LinkMan> linkMans) { this.linkMans = linkMans; } }
- LinkMan.java
package com.xuweiwei.hibernate; /** * 联系人 * * @author 许威威 */ public class LinkMan { /** * 主键 */ private Long id; /** * 联系人姓名 */ private String name; /** * 联系人性别 */ private Character gender; /** * 联系人办公电话 */ private String phone; /** * 联系人手机 */ private String mobile; /** * 联系人邮箱 */ private String email; /** * 联系人QQ */ private String qq; /** * 联系人职位 */ private String position; /** * 联系人备注 */ private String memo; //一个联系人属于一个客户 private Customer customer; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Character getGender() { return gender; } public void setGender(Character gender) { this.gender = gender; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } public String getMemo() { return memo; } public void setMemo(String memo) { this.memo = memo; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } }
- Customer.hbm.xml
<?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"> <hibernate-mapping> <!-- 建立类与表的映射 --> <class name="com.xuweiwei.hibernate.Customer" table="customer"> <!-- 建立类中的属性与表中的主键对应 --> <id name="id" column="id"> <generator class="native"></generator> </id> <!-- 建立类中的普通的属性和表的字段的对应 --> <property name="name" column="name"/> <property name="source" column="source"/> <property name="industry" column="industry"/> <property name="level" column="level"/> <property name="phone" column="phone"/> <property name="mobile" column="mobile"/> <set name="linkMans"> <key column="customer_id"></key> <one-to-many class="com.xuweiwei.hibernate.LinkMan"/> </set> </class> </hibernate-mapping>
- LinkMan.hbm.xml
<?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"> <hibernate-mapping> <!-- 建立类与表的映射 --> <class name="com.xuweiwei.hibernate.LinkMan" table="linkMan"> <!-- 建立类中的属性与表中的主键对应 --> <id name="id" column="id"> <generator class="native"></generator> </id> <!-- 建立类中的普通的属性和表的字段的对应 --> <property name="name" column="name"/> <property name="gender" column="gender"/> <property name="phone" column="phone"/> <property name="mobile" column="mobile"/> <property name="email" column="email"/> <property name="qq" column="qq"/> <property name="position" column="position"/> <property name="memo" column="memo"/> <many-to-one name="customer" class="com.xuweiwei.hibernate.Customer" column="customer_id"/> </class> </hibernate-mapping>
- hibernate.cfg.xml
<?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> <!-- 连接数据库的基本参数 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property> <!-- 配置Hibernate的方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 可选配置================ --> <!-- 打印SQL --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.format_sql">true</property> <!-- 自动创建表 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 加载映射文件 --> <mapping resource="com/xuweiwei/hibernate/Customer.hbm.xml"/> <mapping resource="com/xuweiwei/hibernate/LinkMan.hbm.xml"/> </session-factory> </hibernate-configuration>
- log4j.properties
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c\:mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change ‘info‘ to ‘debug‘ ### # error warn info debug trace log4j.rootLogger= info, stdout
- 初始化数据
//初始化数据 @Test public void test() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Customer customer1 = new Customer(); customer1.setName("张无忌"); Customer customer2 = new Customer(); customer2.setName("张三丰"); for (int i = 0; i < 10; i++) { LinkMan linkMan = new LinkMan(); linkMan.setName("赵敏" + (i+1)); customer1.getLinkMans().add(linkMan); linkMan.setCustomer(customer1); session.save(linkMan); } for (int i = 0; i < 10; i++) { LinkMan linkMan = new LinkMan(); linkMan.setName("郭襄" + (i+1)); customer2.getLinkMans().add(linkMan); linkMan.setCustomer(customer2); session.save(linkMan); } session.save(customer1); session.save(customer2); transaction.commit(); session.close(); }
1.4.2 HQL的简单查询
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 Query query = session.createQuery(" from Customer "); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); session.close(); }
- 示例:别名查询
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 Query query = session.createQuery(" from Customer c"); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); session.close(); }
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 Query query = session.createQuery("select c from Customer c"); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); session.close(); }
1.4.3 HQL的排序查询
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 //默认情况下,是升序 Query query = session.createQuery("select c from Customer c order by id"); List<Customer> list = query.list(); System.out.println(list); transaction.commit(); session.close(); }
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 //默认情况下,是升序 Query query = session.createQuery(" select c from Customer c order by c.id desc "); List<Customer> list = query.list(); System.out.println(list); transaction.commit(); session.close(); }
1.4.4 条件查询
- 示例:按位置绑定:和JDBC一样,只不多Hibernate的位置是从0开始的。
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 Query query = session.createQuery(" select c from Customer c where c.id = ? "); query.setParameter(0,1L); List<Customer> list = query.list(); System.out.println(list); transaction.commit(); session.close(); }
- 示例:按名称绑定
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 Query query = session.createQuery(" select c from Customer c where c.id = :id "); query.setParameter("id",1L); List<Customer> list = query.list(); System.out.println(list); transaction.commit(); session.close(); }
1.4.5 HQL的投影查询
- 投影查询:查询某个对象的某个属性或部分属性。
- 示例:查询所有客户的名称
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 Query query = session.createQuery(" select c.name from Customer c "); List<Object> list = query.list(); System.out.println(list); transaction.commit(); session.close(); }
- 示例:查询所有客户的编号和名称
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //SQL中支持*的写法,但是HQL不支持 Query query = session.createQuery(" select c.id,c.name from Customer c "); List<Object[]> list = query.list(); for (Object[] objects : list) { System.out.println(Arrays.asList(objects)); } transaction.commit(); session.close(); }
1.4.5 HQL的分组统计查询
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); //根据姓名分组 Query query = session.createQuery("select l.name,count(l.id) from LinkMan l group by l.name "); List<Object[]> list = query.list(); for (Object[] objects : list) { System.out.println(Arrays.asList(objects)); } transaction.commit(); session.close(); }
1.4.6 HQL的分页查询
- 示例:分页显示联系人
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Integer pageNo = 1; Integer pageSize = 5; Query query = session.createQuery(" from LinkMan "); query.setFirstResult((pageNo - 1) * pageSize); query.setMaxResults(pageSize); List<LinkMan> list = query.list(); System.out.println(list); transaction.commit(); session.close(); }
1.4.7 多表查询
- HQL支持的多表查询有:交叉连接、内连接(显示内连接,隐式内连接,迫切内连接)、外连接(左外连接、右外连接、迫切左外连接)。
- 所谓的迫切连接,就是在join后面添加一个关键字fetch。目的是通知Hibernate将另一个对象的数据封装到该对象中。
- 示例:内连接
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Query query = session.createQuery(" from Customer c inner join c.linkMans "); List<Object[]> list = query.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } transaction.commit(); session.close(); }
- 示例:迫切内连接
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Query query = session.createQuery(" select distinct c from Customer c inner join fetch c.linkMans "); List<Customer> list = query.list(); list.forEach(System.out::println); transaction.commit(); session.close(); }
1.5 QBC查询
- QBC:条件查询。是一种更加面向对象化的查询方式。
1.5.1 简单查询
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Customer.class); List<Customer> list = criteria.list(); System.out.println(list); transaction.commit(); session.close(); }
1.5.2 排序查询
- 示例:根据id降序
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Customer.class); List<Customer> list = criteria.addOrder(Order.desc("id")).list(); System.out.println(list); transaction.commit(); session.close(); }
1.5.3 分页查询
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Integer pageNo = 1; Integer pageSize = 5; Criteria criteria = session.createCriteria(LinkMan.class); criteria.setFirstResult((pageNo - 1) * pageSize); criteria.setMaxResults(pageSize); List<LinkMan> list = criteria.list(); System.out.println(list); transaction.commit(); session.close(); }
1.5.4 条件查询
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Customer.class); criteria.add(Restrictions.like("name","张", MatchMode.ANYWHERE)); List<Customer> list = criteria.list(); System.out.println(list); transaction.commit(); session.close(); }
1.5.5 统计查询
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Customer.class); criteria.setProjection(Projections.rowCount()); Object o = criteria.uniqueResult(); System.out.println(o); transaction.commit(); session.close(); }
1.6 SQL查询
- 示例:
@Test public void test1() { Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); SQLQuery sqlQuery = session.createSQLQuery(" select * from customer ").addEntity(Customer.class); List<Customer> list = sqlQuery.list(); System.out.println(list); transaction.commit(); session.close(); }
2 Hibernate的抓取策略
原文地址:https://www.cnblogs.com/xuweiweiwoaini/p/9941179.html
时间: 2024-10-27 16:40:33