Hibernate架构与入门
一、O/R Mapping
对象关系映射技术。使用对象之间的关系描述数据库表之间的关联。将Java程序中的对象自动持久化到关系数据库中。
内存中对象之间的关系:
1、关联
2、继承
对象-关系映射存在的形式:中间件。
Hibernate解决的问题:
1、解决并体现表中主键列和其他列地位上的不一样,有效标识数据库表的记录。
2、解决表与表之间的联系,如一对多,多对一等,解决主键、外键之间的关联关系。
二、Hibernate体系结构与入门示例:
使用数据库和配置信息来为运用程序提供持久化服务。数据库信息存储于配置文件中。
示例一:
进行如下配置和编写代码前,还有查看前面篇的配置一:(具体请看博客园:https://www.cnblogs.com/ciscolee/p/10942389.html)
1、src下新建文件夹resource,再新建hibernation.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> <!-- 配置文件标签顺序property*,mapping*,(class-cache|collection-cache),event,listener* --> <session-factory> <!-- 设置访问mysql数据库的驱动描述 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 设置数据库的url --> <property name="connection.url">jdbc:mysql://127.0.0.1:3306/test</property> <!-- 指定登录数据库用户账户 --> <property name="connection.username">root</property> <!-- 指定登录数据库用户密码 --> <property name="connection.password">123456</property> <!-- 设置访问数据库的方言,提高数据库访问性能 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 设置ddl --> <!-- <property name="hbm2ddl.auto">auto</property> --> <!-- 指出映射文件 --> <mapping resource="resource/Customer.hbm.xml"/> </session-factory> </hibernate-configuration>
2、src下新建Customer.hbm.xml,是java类与数据库映射的文件:
<?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 package="bean" auto-import="false"> <!-- POJO类映射表及某表的关系--> <class name="bean.Customer" table="customers" catalog="test"> <id name="customerID" type="java.lang.String"> <column name="customerID" length="8"/> <generator class="assigned"></generator> </id> <!-- 映射表中name字段 --> <property name="name" type="java.lang.String"> <column name="name" length="40"/> </property> <!-- 映射表中phone字段 --> <property name="phone" type="java.lang.String"> <column name="phone" length="16"/> </property> </class> </hibernate-mapping>
3、新建映射表类:
package bean; public class Customer { private String customerID,name,phone; public String getCustomerID() { return customerID; } public void setCustomerID(String customerID) { this.customerID = customerID; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
4、HibernateSessionFactory 类,用于对会话操作,即数据库连接等存放的会话。
package hibernate.factory; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import bean.Customer; public class HibernateSessionFactory { private static String configfile = "resource/hibernate.cfg.xml"; /**ThreadLocal是一个本地线程**/ private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration config; private static SessionFactory sessionFactory; /**读取配置文件,创建一个工厂会话,这段代码为静态块,编译后已经运行**/ static{ try { config = new Configuration().configure(configfile); sessionFactory = config.buildSessionFactory(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } /**通过会话工厂打开会话,就可以访问数据库了**/ public static Session getSession(){ Session session = (Session)threadLocal.get(); if (session==null||!session.isOpen()) { if (sessionFactory==null) { rebuildSessionFactory(); } session = (sessionFactory!=null)?sessionFactory.openSession():null; } return session; } /**重新创建一个会话工厂**/ public static void rebuildSessionFactory() { try { config.configure(configfile); sessionFactory = config.buildSessionFactory(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } /**关闭与数据库的会话**/ public static void closeSession() { Session session = (Session)threadLocal.get(); threadLocal.set(null); if (session!=null) { session.close(); } } }
5、测试类:
package bean; import java.util.List; import hibernate.factory.HibernateSessionFactory; import org.hibernate.Session; import org.hibernate.query.Query; public class Test { @SuppressWarnings("rawtypes") public static void main(String[] args) { /**由会话工厂类创建一个会话Session对象**/ Session session = HibernateSessionFactory.getSession(); /**由会话session对象创建一个查询对象**/ Query query = session.createQuery("from bean.Customer"); List list = query.list(); for (int i = 0; i < list.size(); i++) { Customer customer = (Customer)list.get(i); System.out.println(customer.getCustomerID()+customer.getName()+customer.getPhone()); } HibernateSessionFactory.closeSession(); } }
三、Hibernate核心接口
1、Configuration接口
负责管理Hibernate的配置信息。为了能够连接上数据库必须配置一些属性,这些属性包括:
数据库URL、数据库用户、数据库用户密码、数据库JDBC驱动类、数据库dialect,用于对特定数据库提供支持,其中包含了对特定数据库特性的实现。
/**创建一个配置对象,读取配置文件**/
Configuration config = new Configuration();
Config.configure(“resource/hibernate.cfg.xml”);
2、SessionFactory
运用程序从会话工厂里面获得会话实例,这里用到了一个设计模式,工厂模式。
用户程序从工厂类SessionFactory中取得Session实例。SessionFactory不是轻量级的,他占用的资源比较多,所以他应该能在整个程序中共享。一个项目通常只需要一个SessionFactory就够了,但当项目需要操作多个数据库时,必须为每个数据库指定一个SessionFactory。
会话工厂缓存了生成SQL语句和Hibernate在运行时使用的映射元数据。它也保存了在一个工作单元中读入的数据并且可能在以后的工作中被重用(只有类和集合映射指定了使用这种二级缓存时才会如此)Session类。
/**通过配置对象产生一个会话工厂**/
SessionFactory factory = config.buildSessionFactory();
3、Session接口
该接口是Hibernate使用最多的接口。Session不是线程安全的,他代表与数据库之间的一次操作。Session是持久层操作的基础,相当于JDBC中的Connection。然而在Hibernate中,实例化的Session是一个轻量级的类,创建和销毁都不会占用很多资源。Session通过SessionFactory打开,在所有的工作完成后,需要关闭。但如果在程序中,不断地创建以及销毁Session对象,会给系统带来不良影响,所以有时需要考虑Session的管理合理的创建、合理的销毁。
/**通过工厂产生一个会话**/
Session session = factory.openSession();
4、Query类
使用Query类可以很方便地对数据库及持久层对象进行查询,它可以有两种方式:
查询语句使用HQL或者本地数据库SQL语句编写。
/**通过会话产生一个查询对象**/
Query query = session.createQuery("from bean.Customer");
//通过查询对象查询数据库,返回集合
List list = query.list();
for (int i = 0; i < list.size(); i++) {
Customer customer = (Customer)list.get(i);
System.out.println(customer.getCustomerID()+customer.getName()+customer.getPhone());
5、Transaction接口
如果向数据库增加数据或修改数据,就需要使用事务处理,这时便需要该接口。
Transaction接口是对实际事务实现的一个抽象,该接口可以实现JDBC的事务、JTA中的UserTransaction,甚至可以是CORBA事务等跨容器的事务。之所以这样设计是让开发者能够使用一个统一事务的操作,使得自己的项目在不同的环境和容器之间可以方便地移植。
示例二:
****************配置文件同实例一
Hibernate编程思路:
package bean; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.query.Query; public class Hibernate基本编程思路 { public static void main(String[] args) { /**创建一个配置对象,读取配置文件**/ String configfile = "resource/hibernate.cfg.xml"; Configuration config = new Configuration(); config.configure(configfile); /**通过配置对象产生一个会话工厂类**/ SessionFactory sessionFactory = config.buildSessionFactory(); /**通过会话工厂类产生一个会话实例**/ Session session = sessionFactory.openSession(); /**通过会话产生一个查询对象Query**/ Query query = session.createQuery("from bean.Customer"); /**进行查询返回一个集合list**/ List<Customer> cuslist = query.list(); for (Customer cus:cuslist) { System.out.println("id="+cus.getCustomerID()+",name="+cus.getName()+",phone="+cus.getPhone()); } } }
最后,总结,如重新配置,请参考前一篇配置xml文档,将dtd文档配置进环境。