hibernate

hibernate是什么

框架是什么

  • 框架是用来提高效率的
  • 封装好了一些功能,我们需要使用这些功能时调用即可,不需要再手动实现。
  • 所以框架可以理解成是一个半成品项目,只要懂得如何驾驭这些功能即可

hibernate框架是什么

  • hibernate是帮我们完成数据库操作的orm(对象关系映射)框架,属于Dao层。

hibernate框架的好处

  • 让我们以面向对象的方式操作数据库,甚至不用写sql语句

hibernate框架的搭建

  1. hibernate框架包和驱动包
  2. 创建数据库(也可以不创建数据库,hibernate将会自动生成数据库和表),准备实体类
  3. 书写orm元数据(对象与表的配置文件)
  4. orm元数据的命名规范:对应实体类名.hbm.xml(放置在对应类的包中)
  5. orm配置文件的书写
  • 导入约束

  • 书写元素
//package属性(可写可不写)若写了则在其子标签中,需要写完整类名的地方只需写其简单类名即可,简化操作

/*
    class元素配置实体与表的对应关系
    name属性:对应实体的完整类名
    table属性:对应数据库的表名
*/

    
    //name属性:填写实体中id对应的属性名,column属性(可选属性,一般不写):填写数据库id对应的列名
        
            //generator属性:主键生成策略,native: 根据所选数据库三选一(开发中就用native就行)
            
        
    /*
        property元素:除id之外的普通属性映射
        not-null属性:指定该属性值是否不能为空,默认为false
        length:配置数据库中对应列的长度
        type:配置数据库中对应列的数据类型(建议不写,hibernate将会自动匹配)
    */
        
        
    

  • hibernate主配置文件(放置在src下)
  • 导入约束

  • 书写元素

    
         
		com.mysql.jdbc.Driver
		 
		jdbc:mysql:///hibernate
		 
		root
		 
		123456
		
		org.hibernate.dialect.MySQLDialect
		 
		 
		 true
		true
		
		update
	
		
    

hibernate API介绍

  1. Configuration对象(加载配置文件):Configuration cfg= new Configuration().configure();
  2. SessionFactory(Session工厂):SessionFactory factory= cfg.buildSessionFactory();
  • SessionFactory:负责保存和使用所有配置信息,消耗内存非常大
  • SessionFactory属于线程安全对象
  • 保证在一个web项目中只创建一个
  1. Session(相当于jdbc中的Connection对象):Session session=factory.openSession();
    factory.getCurrentSession()获得的是与线程绑定的Session对象,若要使用此方法获得Session对象,就必须在主配置文件中添加配置:
thread
  1. Transaction(事物操作对象):Transaction tx = session.beginTransaction()
  • 若是factory.openSession()方法产生的session,事物操作完成后,需要关闭调用close()方法关闭session,若是factory.getCurrentSession()方法产生的session对象不需要手动关闭session

#hibernate中实体的规则

  1. 实体类创建的注意事项:
  • 必须提供无参的构造方法
  • 成员变量需私有,并且提供get和set方法
  • 不能用final修饰Class(因为hibernate使用cglib代理来生成代理对象的,而cglib代理是使用继承来实现的)
  • 所有成员变量的类型最好使用对应的包装类
  • 持久化类中提供的对应属性应与数据库中的对应列同名
  1. 主键类型一般采用代理主键,并且主键生成方式选择native
    #hibernate中对象的三种状态

  2. 瞬时状态:没有id,没有与session建立关联

  3. 持久化状态:有id,与session建立了关联

  4. 游离状态或托管状态:有id,没有与session建立关联

  • new出来的对象为瞬时状态,get得到的对象为持久化状态,session关闭后,持久化状态的对象就变为游离状态,update方法可以将游离状态的对象转化为持久化状态

#hibernate中一级缓存

  • 作用:提高开效率

hibernate批量查询

HQL查询(多表查询,但不复杂时使用)

//基本查询
String hql="from Customer";
Query query=session.createQuery(hql);
List list=query.list();

//?占位符,条件查询
String hql="from Customer where id=?";
Query query=session.createQuery(hql);
query.setParameter(0,1l);
Customer c=query.uniqueResult();

//冒号占位符,条件查询
String hql="from Customer where id=id";
Query query =session.createQuery(hql);
query.setParameter("id",1);
Customer c=query.uniqueResult();

//hql统计查询
String hql="select new Customer(id,name) from Customer"
Query query=session.createQuery(hql);
Customer c=query.list(); 

//分页查询
String hql="from Customer"
Query query =session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(2);
List list=query.list();

//计数查询
String hql1 = "select count(*) from Customer";
//求和
String hql2 = "select sum(cust_id) from Customer";
//平均数
String hql3 = "select avg(cust_id) from Customer";
//最大值
String hql4= "select max(cust_id) from Customer";
//最小值查询
String hql5 = "select min(cust_id) from Customer";

Query query = session.createQuery(hql4);

Number number = (Number)query.uniqueResult();

Criteria查询

//基本查询
Criteria criteria=session.createCriteria(Customer.class);
List list=criteria.list();

//条件查询
Criteria criteria=session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("cust_id", 16l));
Customer c=(Customer)criteria.uniqueResult();

//分页查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(0);
criteria.setMaxResults(2);
List list = criteria.list();

//总记录数查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.setProjection(Projections.rowCount());
Long count = (Long) criteria.uniqueResult();

原生sql查询(复杂查询)

//基本查询
String sql="select * from t_customer";
SQLQuery sq=session.createSQLQuery(sql);
//将结果集封装到指定的实体类中
sq.addEntity(Customer.class);
List list=sq.list();

//条件查询
String sql="select * from t_customer where id=?";
SQLQuery sq=session.createSQLQuery(sql);
sq.setParameter(0,10);
sq.addEntity(Customer.class);
Customer c = (Customer) sq.uniqueResult();

//分页查询
String sql="select * from t_customer limit ?,?";
SQLQuery sq=session.createSQLQuery(sql);
//将结果集封装到指定的实体类中
sq.setParamerter(0,0);
sq.setParamerter(1,3);
sq.addEntity(Customer.class);
List list=sq.list();

hibernate中的关系表达

一对多,多对多关系表达

一的一方

  • 在一的一方的实体中创建一个HashSet集合对象,用此集合来存储多的一方的实体变量
  • 然后在一的一方的配置文件中加入如下配置
/*
    name属性:填写一的一方的实例中与多的一方表达关系的集合属性名称

    casecade属性:级联操作,有三个值:update、delete、all(save-update+save-delete),直接选用upda
                  te即可,级联保存更新
    key元素中column属性填写对应数据库中外键列名
    one-to-many中的class属性填写对应多的一方的全类名
*/

    
    

多的一方

  • 在多的一方的实体中创建一个一的一方的实例变量,用此变量来表达与一的对应关系
  • 然后在多的一方的配置文件中加入如下配置
/*
    name属性:填写多的一方的实例中与一的一方表达关系的实例变量名
    column属性:填写数据库中对应的外键列名
    class属性:填写对应一的一方的全类名
*/

如何用代码表示一对多,多对一的关系:

Customer c = new Customer()
c.setCust_name("百度公司");

LinkMan l1 =new LinkMan();
l1.setLkm_name("黎活明");
LinkMan l2= new LinkMan();
l2.setLkm_name("刘跃东");

//表达客户和联系人的关系
c.getLinkMens().add(l1);
c.getLinkMens().add(l2);

//表达联系人和客户的关系
l1.setcustomer(c);
l2.setCustomer(c);

//将Customer对象和LinkMan对象转化为持久化状态,将数据同步到数据库中
  • 注意:LinkMan这一方(即多的一方)执行插入操作时,就已经维护了表之间的关系(即外键),此时hibernate默认Customer(即一的一方)也会维护外键关系,这时就会发现一的一方维护外键关系的sql语句多余了,会降低程序的执行效率,所以此时最好在Customer的orm元数据配置中的set元素中加入inverse属性并将其值设置为true,放弃Customer(即一的一方)关系的维护,多的一方一定不能放弃关系的维护。
  • 代码:

    
    

多对多关系的表达

  • 在两个对应实体类中分别创建两个集合,用来保存对方的实体对象,用此集合来在java类中表示关系的维护。
  • 还需要在各自实体类中加入如下配置:
/*
    name属性:填写实体类中对应的集合变量名
    table属性:中间表名
    column属性填写本表中的id名(即中间表中外键名)
    class属性:与本类构成多表关系的类的完全类名
    many-to-many元素中的column属性:填写class属性中对应类所对应表中的id名
*/

	
	

  • 在多对多关系中,必须有一方要放弃关系的维护,否则双方都会维护中间表的外键关系,会导致向中间表插入记录重复而报错。而且在选择放弃维护关系时,应该视关系情况而定,如员工和职务之间的关系,是由员工维护的,要选择放弃职务对第三张表的维护
  • 如何用代码表示多对多的关系
User u1= new User();
u1.setName("张三");
User u2= new User();
u2.setName("李四");

Role r1 = new Role();
r1.setRo_name("保洁");
Role r1 = new Role();
r1.setRo_name("保安");

//角色表达和职务的关系
u1.getRoles().add(r1);
u1.getRoles().add(r2);
u2.getRoles().add(r1);
u2.getRoles().add(r2);

//职务表达和角色的关系
r1.getRoles().add(u1);
r1.getRoles().add(u2);
r2.getRoles().add(u1);
r2.getRoles().add(u2);

//将关系持久化到数据库中
u1.save();
u2.save();
r1.save();
r2.save();

// **此时一定注意要在orm元数据中放弃其中一方关系的维护**

查询优化

  • get方式查询:立即调用数据库查询,加载数据
  • load方式查询:应用类级别加载策略,而且返回的是代理对象(采用cglib代理)
/*
    lazy:
        true:默认取值,它的意思是只有在调用这个集合获取里面的元素对象时,才发出查询语句,加载其 
            集合元素的数据 
        false:取消懒加载特性,即在加载对象的同时,就发出第二条查询语句加载其关联集合的数据 
        extra:一种比较聪明的懒加载策略,即调用集合的size/contains等方法的时候,hibernate并不会去加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据    
*/

  • 注意:使用懒加载时应确保调用属性加载数据时session是打开的,否则会抛出异常
  • no-session问题解决:
  • 在filter中处理session事务
//在开发时lazy和fetch都选择默认值即可
//batch-size属性:设置每次查询时抓取几条数据

你可能感兴趣的:(java,持久层框架,后端,框架)