hibernate单表查询 关联映射 状态转换
hibernate简介
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
例子:
创建表和对应的javaBean文件
create table customer ( id int primary key, name varchar(12), age int, des varchar(100) ) |
public class Customer { private Integer id; private String name; private Integer age; private String des; } |
新建映射文件Customer.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="model.Customer" table="customer" > <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="assigned"></generator> </id> <property name="name" type="java.lang.String"> <column name="name" length="12" /> </property> <property name="age" type="java.lang.Integer"> <column name="age" /> </property> <property name="des" type="java.lang.String"> <column name="des" length="100" /> </property> </class> </hibernate-mapping> |
6种主键生成策略
assigned:主键的生成不用Hibernate管理了,必须手动设置主键 uuid:适用于char,varchar类型的作为主键,使用随机的字符串作为主键 increment:适用于short,int,long作为主键.不是使用的数据库自动增长机制,先进行查询 :select max(id) from user;再进行插入 :获得最大值+1作为新的记录的主键 identity:适用于short,int,long作为主键,但是这个必须使用在有自动增长数据库中(Mysql) sequence:适用于short,int,long作为主键.底层使用的是序列的增长方式(Oracle) native:根据底层的数据库不同,自动选择适用于该种数据库的生成策略.(short,int,long) 如果底层使用的MySQL数据库:相当于identity. 如果底层使用Oracle数据库:相当于sequence. |
新建核心配置文件hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="connection.url"> jdbc:mysql://127.0.0.1:3306/test </property> <property name="connection.username">root</property> <property name="connection.password">root</property> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="hibernate.show_sql">true</property> <mapping resource="Customer.hbm.xml" /> </session-factory> </hibernate-configuration> |
测试
public class HTest1PrimaryKey { Session session = getSession(); @Test public void testSave(){ Transaction ts = session.beginTransaction(); Customer custom = new Customer(null,"张三",20); session.save(custom); ts.commit(); } @Test public void testUpdate(){ Transaction ts = session.beginTransaction(); Customer custom = new Customer(1,"李四",25); session.update(custom); ts.commit(); } @Test public void testDelete(){ Transaction ts = session.beginTransaction(); Customer custom = new Customer(1,"李四",25); session.delete(custom); ts.commit(); } @Test public void testQuery(){ Customer cus = (Customer)session.get(Customer.class, 1); Customer cus2 = (Customer)session.get(Customer.class, 1); System.out.println(cus.getName()+"--"+cus.getAge()); } @Test public void testQuery2(){ Customer cus = (Customer)session.load(Customer.class, 1); Customer cus2 = (Customer)session.load(Customer.class, 1); System.out.println(cus.getName()+"--"+cus.getAge()); } /** * get load区别 * 1.当查询不到对象时 get返回null load抛出异常ObjectNotFoundException * 2.get直接从缓存或者数据库查询 load支持懒加载 * */ public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
3.单表查询
SQL(Structured Query Language) 结构化查询语言 HQL(Hibernate Query Lanaguage) HQL采用面向对象的查询方式 QBC(Query By Criteria) API提供了检索对象的另一种方式,它主要由Criteria接口、Criterion接口和Expresson类组成. QBC检索步骤: 1.调用Session的createCriteria()方法创建一个Criteria对象 2.设定查询条件. 3.调用Criteria的list()方法执行查询语句。 |
1.查询所有记录
public class HTest2selectAll { Session session = getSession(); @Test public void testSQL(){ String sql="select * from customer"; List<Customer> customers = session.createSQLQuery(sql).addEntity(Customer.class).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } @Test public void testHQL(){ //这个Customer是javabean对象 String hql="from Customer"; List<Customer> customers = session.createQuery(hql).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } @Test public void testQBC(){ List<Customer> customers = session.createCriteria(Customer.class).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
2.排序
public class HTest3orderBy { Session session = getSession(); @Test public void testSQL(){ String sql="select * from customer order by age desc"; List<Customer> customers = session.createSQLQuery(sql).addEntity(Customer.class).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } @Test public void testHQL(){ String hql="from Customer order by age desc"; List<Customer> customers = session.createQuery(hql).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } @Test public void testQBC(){ List<Customer> customers = session.createCriteria(Customer.class).addOrder(Order.desc("age")).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
3.动态参数绑定(可变参数)
public class HTest4dynamicParam { Session session = getSession(); @Test public void testSQL(){ String sql="select * from customer where age>?"; List<Customer> customers = session.createSQLQuery(sql).addEntity(Customer.class).setInteger(0, 22).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } @Test//setParameter不区分数据类型 public void testSQL2(){ String sql="select * from customer where age>?"; List<Customer> customers = session.createSQLQuery(sql).addEntity(Customer.class).setParameter(0, 22).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } @Test public void testHQL(){ String hql="from Customer where age>?"; List<Customer> customers = session.createQuery(hql).setInteger(0, 22).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } @Test public void testHQL2(){ String hql="from Customer where age>?"; List<Customer> customers = session.createQuery(hql).setParameter(0, 22).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } } public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
4.分页
public class HTest5limit { Session session = getSession();
@Test public void testSQL(){ String sql="select * from customer limit ?,?"; List<Customer> customers = session.createSQLQuery(sql).addEntity(Customer.class).setInteger(0, 1).setInteger(1, 2).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } }
@Test public void testHQL(){ String hql="from Customer"; List<Customer> customers = session.createQuery(hql).setFirstResult(1).setMaxResults(2).list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } }
public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
5.模糊查询
public class HTest6like { Session session = getSession(); @Test public void testSQL(){ String sql="select * from customer where name like ?"; List<Customer> customers = session.createSQLQuery(sql).addEntity(Customer.class).setString(0, "%李%").list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } }
@Test public void testHQL(){ String hql="from Customer where name like ?"; List<Customer> customers = session.createQuery(hql).setString(0, "%李%").list(); for(Customer cus:customers){ System.out.println(cus.getName()+"--"+cus.getAge()); } }
public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
6.唯一查询
public class HTest7unique { Session session = getSession(); @Test public void testSQL(){ String sql="select * from customer where id=?"; Customer cus = (Customer)session.createSQLQuery(sql).addEntity(Customer.class).setInteger(0, 1).uniqueResult(); System.out.println(cus.getName()+"--"+cus.getAge()); }
@Test public void testHQL(){ String hql="from Customer where id=?"; Customer cus = (Customer)session.createQuery(hql).setInteger(0, 1).uniqueResult(); System.out.println(cus.getName()+"--"+cus.getAge()); }
public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
7.聚合函数查询
public class HTest8juhe { Session session = getSession(); @Test public void testSQL(){ String sql="select count(id),sum(age) from customer "; Object[] obj = (Object[])session.createSQLQuery(sql).uniqueResult(); System.out.println(obj[0]); System.out.println(obj[1]); }
@Test public void testHQL(){ String hql="select count(id),sum(age) from Customer "; Object[] obj = (Object[])session.createQuery(hql).uniqueResult(); System.out.println(obj[0]); System.out.println(obj[1]); }
public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
8.投影查询(查询部分字段)
public class HTest9touying { Session session = getSession(); @Test public void testSQL(){ String sql="select id,name from customer "; List<Customer> customers = session.createSQLQuery(sql).setResultTransformer(Transformers.aliasToBean(Customer.class)).list(); for(Customer cus:customers){ System.out.println(cus); } }
@Test//使用构造方法 public void testHQL(){ String hql="select new Customer(id,name) from Customer "; List<Customer> customers = session.createQuery(hql).list(); for(Customer cus:customers){ System.out.println(cus); } }
public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
9.分组查询
public class HTest9touying { Session session = getSession(); @Test public void testSQL(){ String sql="select * from customer group by age"; List<Customer> customers = session.createSQLQuery(sql).addEntity(Customer.class).list(); for(Customer cus:customers){ System.out.println(cus); } }
@Test//使用构造方法 public void testHQL(){ String hql="from Customer group by age"; List<Customer> customers = session.createQuery(hql).list(); for(Customer cus:customers){ System.out.println(cus); } }
public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
注:分组后不加组函数,会自动显示每组的第一条
10.list() 和iterator()方法比较
public class HTest011iterator { Session session = getSession();
@Test//使用构造方法 public void testHQL(){ String hql="from Customer "; List<Customer> customers = session.createQuery(hql).list(); for(Customer cus:customers){ System.out.println(cus); } List<Customer> customers1 = session.createQuery(hql).list(); for(Customer cus:customers1){ System.out.println(cus); } } @Test//使用构造方法 public void testHQL2(){ String hql="from Customer "; Iterator customers = session.createQuery(hql).iterate(); while(customers.hasNext()){ System.out.println(customers.next());; } Iterator customers1 = session.createQuery(hql).iterate(); while(customers1.hasNext()){ System.out.println(customers1.next());; } } @Test//使用构造方法 public void testHQL3(){ String hql="from Customer "; List<Customer> customers = session.createQuery(hql).list(); for(Customer cus:customers){ System.out.println(cus); } Iterator customers1 = session.createQuery(hql).iterate(); while(customers1.hasNext()){ System.out.println(customers1.next());; } } public Session getSession(){ //1.加载主配置文件 Configuration cfg = new Configuration().configure(); //2.获取SessionFactory对象 SessionFactory sessionFactory = cfg. //获取Session对象 Session session = sessionFactory.openSession(); return session; } } |
总结:
list()每次都会直接查询数据库,iterator()会先到数据库中把id都取出来,然后真正要遍历某个对象的时候先到缓存中找,如果找不到,以id为条件再发一条sql到数据库,这样如果缓存中没有数据,则查询数据库的次数为n+1次
list()和iterate()一起使用会提高查询速度
4.关联映射
1.单向一对多
一个客户对应多个订单,既一对多
Customer
private Integer id; private String name; private Integer age; private String des; private Set<Order> orders=new HashSet<Order>(); |
Order
private Integer id; private String orderNumber; |
建表语句:
CREATE TABLE `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`orderNumber` varchar(12) DEFAULT NULL,
`cid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_customer_id` (`cid`),
CONSTRAINT `fk_customer_id` FOREIGN KEY (`cid`) REFERENCES `customer` (`id`)
)
<set name="orders" table="orders" cascade="save-update"> <key> <column name="cid"></column> </key> <one-to-many class="model.Order"/> </set> |
如果使用list,则没有级联。
Cascade 级联操作 none 不进行级联操作 save-update 新增或修改主表时级联对从表进行新增或修改 delete 删除主表时级联删除从表 all 新增、修改、删除时对从表都进行相关操作 |
2.单向多对一
Order
private Integer id; private String orderNumber; private Customer customer; |
Customer
private Integer id; private String name; private Integer age; private String des; |
<many-to-one name="customer" class="model.Customer" column="cid" cascade="save-update"/> |
3.hibernate状态转换
Hibernate中对象有三种状态: 临时状态(Transient)、持久状态(Persistent)、游离状态(Detached)。
临时状态:刚刚使用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。
持久化状态:已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。
游离状态:已经被持久化,但不处于session的缓存中。处于游离状态的Java对象被称为游离对象。
get、load、find: 方法的使用上较为类似.他们都是将数据库中对应Id的数据映射为Java对象,此时对象变为持久化状态。
save: 保存,此时Java对象已经与数据库记录建立的关系。将对象从临时状态的变为持久化状态或者将游离状态的数据变为持久状态。
saveOrUpdate: 保存或者更新,如果没有与数据库记录所对应的oid,则执行保存,如果有,则执行更新。将对象从临时状态的变为持久化状态或者将游离状态的数据变为持久状态。
delete: 删除对象,将对象从持久化状态或者游离状态变为临时状态。
close: 关闭session, 先将session清空,然后再关闭。将对象从持久状态变为临时状态。
clear: 清空session缓存。将对象从持久状态变为临时状态。
evict: 清除指定的对象。将对象从持久状态变为临时状态。
lock:把一个没有更改过的脱管状态的对象变成持久状态。
4.hibernate缓存
1级缓存 session级别的缓存 自动开启
2级缓存 SessionFactory级别的缓存需结合缓存框架ehcache进行设置
5.hibernate与mybatis的区别
hibernate | mybatis |
---|---|
全自动框架 | 半自动,需要手写sql语句 |
sql优化修改较复杂 | sql优化简单,修改简单 |
多表关联操作比较繁琐 | 多表操作简单 |
对第三方框架支持较好 | 对第三方框架支持弱 |
需求不怎么变化的企业级项目erp、crm、oa | 需求经常变化的互联网项目 |
不支持动态sql | 支持动态sql |
sql层次较混乱 | 集中管理sql语句 |