Hibernate开发
在Java应用中使用Hibernate的步骤
1.创建Hibernate的配置文件
2.创建持久化类
3.创建对象-关系映射文件
4.通过Hibernate API编写访问数据库的代码
1.创建hibernate.cfg.xml的配置文件(参照hibernate.properties)
把hibernate.cfg.xml文件放置在classpath路径下
<!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="connection.url">
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
</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="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hbm2ddl.auto">update</property>
<property name="format_sql">true</property>
<property name="show_sql">true</property>
<mapping resource="完整包名(用/分隔)/Customer.hbm.xml" />
</session-factory>
</hibernate-configuration>
2. 创建持久化类
A: Hibernate要求持久化类必须提供一个不带参数的默认构造方法(必须)
B: 持久化类有一个id属性,用来惟一标识Customer类的每个对象。在面向对象术语中,这 个id属性被称为对象标识符(可选)
C: 持久化类符合JavaBean的规范,以及与之对应的getXXX()和setXXX()方法(可选)。
D: 如果是集合类型的属性,它的类型必须定义为集合的接口。例如:List、Set。
3. 创建对象-关系映射文件
Hibernate映射文件知道怎样去加载(load)和存储(store)我们的持久化类的对象。配置文件结构
<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mappingPUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
[. . . . . .]
</hibernate-mapping>
<id>元素映射
<property>元素映射值类型属性
name属性:指定持久化类的属性的名字。
type属性:指定Hibernate映射类型。Hibernate映射类型是Java类型与SQL类型的桥梁。
column属性:指定与类的属性映射的表的字段名。
Java类型、Hibernate映射类型以及SQL类型之间的对应关系
Configuration
概述:Configuration类负责管理Hibernate的配置信息。它包括如下内容:
1.Hibernate运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数据库Dialect,数据库连接池等。
2.加载Hibernate映射文件(*.hbm.xml)。
Hibernate配置的两种方法:
属性文件(hibernate.properties)。
调用代码:Configuration cfg = new Configuration();
Xml文件(hibernate.cfg.xml)。
调用代码:Configuration cfg = new Configuration().configure();
SessionFactory
概述:应用程序从SessionFactory(会话工厂)里获得Session(会话)实例。它在多个应用线程间进行共享。通常情况下,整个应用只有唯一的一个会话工厂——例如在应用初始化时被创建。然而,如果你使用Hibernate访问多个数据库,你需要对每一个数据库使用一个会话工厂。
会话工厂缓存了生成的SQL语句和Hibernate在运行时使用的映射元数据。
调用代码:
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session(会话)
概述:
Session不是线程安全的,它代表与数据库之间的一次操作,它的概念介于Connection和Transaction之间。
Session也称为持久化管理器,因为它是与持久化有关的操作接口。
Session通过SessionFactory打开,在所有的工作完成后,需要关闭。
调用代码
Session session = sessionFactory.openSession();
Session的几个主要方法
1.save,persist保存数据,persist在事务外不会产生insert语句。
2.delete,删除对象
3.update,更新对象,如果数据库中没有记录,会出现异常。
4.get,根据ID查,会立刻访问数据库。
5.Load,根据ID查,(返回的是代理,不会立即访问数据库)。
6.saveOrUpdate,merge(根据ID和version的值来确定是save或update),调用merge你的对象还是托管的。
7.lock(把对象变成持久对象,但不会同步对象的状态)。
Transaction(事务)
概述:
它将应用代码从底层的事务实现中抽象出来——这可能是一个JDBC事务,一个JTA用户事务或者甚至是一个公共对象请求代理结构(CORBA)——允许应用通过一组一致的API控制事务边界。这有助于保持Hibernate应用在不同类型的执行环境或容器中的可移植性。
调用代码:
Transaction tx = session.beginTransaction();
注:使用Hibernate进行操作时(增、删、改)必须显示的调用Transaction(默认:autoCommit=false)。
Query
概述:
Query(查询)接口允许你在数据库上执行查询并控制查询如何执行。查询语句使用HQL或者本地数据库的SQL方言编写。
调用代码:
Query query = session.createQuery(“from User”);
对象状态
l 瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来且与session没有关联的对象。
l 持久(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能检测到)。
l 脱管(detached):数据库中有数据与之对应,但当前没有session与之关联;托管对象状态发生改变,hibernate不能检测到。
Hibernate语言查询(Hibernate Query Language,HQL)
HQL(Hibernate Query Language)
面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类和属性其他部分不区分大小写);HQL中查的是对象而不是和表,并且支持多态;HQL主要通过Query来操作,Query的创建方式:
Query query = session.createQuery(hql);
l from Person
l from User user where user.name=:name
l from User user where user.name=:name and user.birthday < :birthday
Hibernate分页
query.setFirstResult(1);
query.setMaxResults(10);
Criteria
Criteria是一种比HQL更面向对象的查询方式;Criteria的创建方式:
Criteria crit = session.createCriteria(DomainClass.class);
简单属性条件如:criteria.add(Restrictions.eq(propertyName, value)),
criteria.add(Restrictions.eqProperty(propertyName,otherPropertyName))
Hibernate操作例子
l 保存用户:session.save(user);
l 修改用户:session.update(user);
l 保存或修改用户:session.saveOrUpdate(user);
l 删除用户:session.delete(user);
l 删除所有用户:session.delete(“from User ”);
l 查询用户名为“test”的用户:
l Query query = session.createQuery("from User where user.name = :name");
l query.setParameter(“test",user.getName());
l query = session.createQuery("from User user where user.name like 'J%'");
l User findUser = (User) query.list().get(0);
List users = query.list();