一、基本介绍
1、它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm(对象关系映射)框架,hibernate可以自动生成SQL语句,自动执行; Hibernate可以应用在任何使用JDBC的场合。
2、持久化层:处理关系型数据库(数据存储层)和模型对象(object,业务逻辑模型)的映射关系的代码方法(ORM)
3、Hibernate是一个基于JDBC的主流持久化框架,对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码,是一个优秀的ORM实现,它很大程度的简化了dao层编码工作。
4、下载地址:http://www.hibernate.org/downloads
5、新建hibernate.cfg.xml或 hibernate.properties,放在项目根目录,用于配置数据库的相关信息;xlm头文件信息可在hibernate-core-5.3.0.Final.jar中的dtd文件中找到,同时一个类对象的映射xml文件的头也可以在这个jar包的dtd文件中找到;
二、Hibernate的API
一共有6个,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。通过这些接口,可以对持久化对象进行存取、事务控制。
1、使用示例:
// 使用Hibernate的API来完成将Customer信息保存到mysql数据库中的操作
Configuration config = new Configuration().configure(); // Hibernate框架加载hibernate.cfg.xml文件
SessionFactory sessionFactory = config.buildSessionFactory();//据库存储源。根据Hibernate配置文件创建对应的数据库存储源。SessionFactory对象创建后,和Configuration对象再无关联。
Session session = sessionFactory.openSession(); // 相当于得到一个Connection
// 开启事务
session.beginTransaction(); // 用户自己的操作,常用的还有update(),delete(),load(),get()后两个都是查询,get()是直接发送sql语句查询,load是使用代理技术,当要查询时,代理调用Hiberate查询数据库,并初始化其他属性;createQuery()可执行自定sql语句,但是使用的变量名是object里边的,具体待查;也可以使用SQLQuery对象来执行原生的sql语句;
session.save(obj); // 事务提交
session.getTransaction().commit();
session.close();
sessionFactory.close();
2、session对象方法:
Transaction beginTransaction() 开始工作单位,并返回关联事务对象。
void cancelQuery() 取消当前的查询执行。
void clear() 完全清除该会话。
Connection close() 通过释放和清理 JDBC 连接以结束该会话。
Criteria createCriteria(Class persistentClass) 为给定的实体类或实体类的超类创建一个新的 Criteria 实例。
Criteria createCriteria(String entityName) 为给定的实体名称创建一个新的 Criteria 实例。
Serializable getIdentifier(Object object) 返回与给定实体相关联的会话的标识符值。
Query createFilter(Object collection, String queryString) 为给定的集合和过滤字符创建查询的新实例。
Query createQuery(String queryString) 为给定的 HQL 查询字符创建查询的新实例。
SQLQuery createSQLQuery(String queryString) 为给定的 SQL 查询字符串创建 SQLQuery 的新实例。
void delete(Object object) 从数据存储中删除持久化实例。
void delete(String entityName, Object object) 从数据存储中删除持久化实例。
Session get(String entityName, Serializable id) 返回给定命名的且带有给定标识符或 null 的持久化实例(若无该种持久化实例)。
SessionFactory getSessionFactory() 获取创建该会话的 session 工厂。
void refresh(Object object) 从基本数据库中重新读取给定实例的状态。
Transaction getTransaction() 获取与该 session 关联的事务实例。
boolean isConnected() 检查当前 session 是否连接。
boolean isDirty() 该 session 中是否包含必须与数据库同步的变化?
boolean isOpen() 检查该 session 是否仍处于开启状态。
Serializable save(Object object) 先分配一个生成的标识,以保持给定的瞬时状态实例。
void saveOrUpdate(Object object) 保存(对象)或更新(对象)给定的实例。
void update(Object object) 更新带有标识符且是给定的处于脱管状态的实例的持久化实例。
void update(String entityName, Object object) 更新带有标识符且是给定的处于脱管状态的实例的持久化实例。
3、Transaction对象的使用:
封装了事务的操作。我们做增删改查等操作时,必须开启事务.因为session是线程不安全的,这样主要是为了线程安全。保证数据的正确性。
开启事务: Transaction ts=session.beginTransaction();
提交事务:ts.commit();
回滚事务:ts.rollback();
当通过getCurrentSession获取当前线程绑定的Session时,事务关闭时,会自动把Session关闭并删除。
4、xxx类的映射文件xxx.hbm.xml配置示例(这些都可以通过注解实现):
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<!--定义从一个 Java 类到数据库表的特定映射-->
<class name="Employee" table="EMPLOYEE">
<!--可选-->
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<!--主键,其中generator标签可自动生成主键值-->
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<!--其他普通的值,name是对象中属性名字,column是数据库的对应的名字-->
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>
5、Hibernate 注解
使用环境:需要安装 Hibernate 3.x 注释包,从 Hibernate 注释发布中拷贝 hibernate-annotations.jar, lib/hibernate-comons-annotations.jar 和 lib/ejb3-persistence.jar 到你的 CLASSPATH。
@Entity 志着一个类为一个实体 bean
@table 注释提供了四个属性,允许您覆盖的表的名称,目录及其模式,在表中可以对列制定独特的约束
@Id 主键;
@Column 指定某一列与某一个字段或是属性映射的细节信息,常用属性有:name,length,nullable,unique;
6、Hibernate中持久化类编写规范;
1)、必须提供无参数的默认构造方法。因为程序运行时,Hibernate会运用java的反射机制,创建实体类的实例。
2)、所有属性必须提供public访问控制符的set get方法
3)、属性应尽量使用基本数据类型的包装类型(如Integer)
基本数据类型无法表达null值,所有基本数据类型的默认值都不是null,这样就有很大的缺陷。
例如有一个score属性,表示学生分数,如果为0,那么是表示该学生未参加考试还是说该学生成绩为0呢?
这时候如果用包装类型,就可以使用null来表示空值,学生未参加考试等等。
4)、不要用final修饰实体(将无法生成代理对象进行优化)
三、查询语句
1、HQL
面向对象的类似sql的语句;
1)、基础示例;
String hql = "FROM Employee"; //查询这个Employee类的所有数据库数据,类名前也可以使用完成的包路径;
Query query = session.createQuery(hql);
List results = query.list();
其他语法:
FROM Employee AS E 给类创建别名
SELECT E.firstName FROM Employee E 只查询特定项的数据;
FROM Employee E WHERE E.id = 10 条件查询,类似的使用还有ORDER BY ,GROUP BY,UPDATE,DELETE,INSERT,SUM,MAX,MIN,COUNT,AVG,DISTINCT等
2)、传参数示例:
String hql = "FROM Employee E WHERE E.id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id",10);
List results = query.list();
3)、分页
query.setFirstResult(int startPosition) 表示结果中的第几行,从 0 行开始。
query.setMaxResults(int maxResult) 最大检索结果数量;
2、标准查询(Criteria)
当使用标准查询时返回一个持久化对象类的实例
1)基础示例:
Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq("salary", 2000)); //查询所有salary=2000的结果,也可以不要此行,则查询数据库中所有数据;类似的条件还有gt,lt,like,ilike,between,isNull,isEmpty,isNotEmpty(以上都是替换eq来进行相同的用法)
List results = cr.list();
2)逻辑条件示例:
Criteria cr = session.createCriteria(Employee.class); Criterion salary = Restrictions.gt("salary", 2000);
Criterion name = Restrictions.ilike("firstNname","zara%"); // 或(or),与(and)
LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp ); List results = cr.list();
3)分页
public Criteria setFirstResult(int firstResult);
public Criteria setMaxResults(int maxResults);
3、原始SQL语句查询
基础示例:
String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);//返回的是实体对象,如果setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)则返回原始的数据;
query.setParameter("employee_id", 10);
List results = query.list();
四、其他扩展
1、Hiberate能实现一对一、一对多、多对一、多对多的映射;
2、Hiberate的缓存机制,批处理方法和拦截器的使用方法;
3、附:Hiberate从实体到数据库的类型自动映射;