Hibernate
- 框架,是对JDBC的轻量级封装,将程序对象存到数据库中。
- 用于将java对象与对象之间的关系映射到数据库中表与表之间关系。
- 原本对数据库的操作通过:①JDBC②配置③连接④select语句。
- 每次操作都要用select太麻烦,我们想直接通过一个类,定义成员变量与函数来操作关系数据库。
创建Hibernate程序
(1)准备数据库表
(2)定义可持久化类(PO)
- 可持久化类存储要与数据库交互的数据。
- 可持久化类符合javabeans规范,有一个默认构造函数,因为Hibernate将用反射机制创建对象,没有的话编译器将自动创建。要有一个标识属性,可以是任意类型,通常为主键对应的属性
持久化对象状态
- 临时态:对象通过new有值,但并未在Hibernate Session管理中,数据库中也无与之匹配数据
- 持久态:如执行session.save()后,对象在Hibernate Session管理中,数据库中也有与之匹配数据
- 托管态:关闭session后,对象不在Hibernate Session管理中,但数据库中有与之匹配数据
public class Emailtab extends AbstractEmailtab implements java.io.Serializable {
public Emailtab() { }
public Emailtab(String email) {
super(email);
}
public Emailtab(String email, String password) {
super(email, password);
}
}
会话工厂:
private HibernateSessionFactory() {
}
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession(): null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
public static Configuration getConfiguration() {
return configuration;
}
(3)定义Hibernate映射文件Student.hbm.xml
- 每个可持久化类有一个映射文件,用来定义持久化类与数据表之间的关系。
- 根元素:<hibernate-mapping>
它的子元素:
- <class>:<class name="Student" table="student">
- <id>:声明标识符属性(主键):id子元素generator指定标识符生成策略,mysql的生成器为identify
- <property>:映射普通属性:<property name="no" type="string" column="sno">
- 如果为一对一则加<one-to-one>,多对一<many-to-one>
<hibernate-mapping>
<class name="com.Emailtab" table="emailtab" catalog="mydatabase">
<id name="email" type="java.lang.String">
<column name="email" length="45" />
<generator class="assigned" />
</id>
<property name="password" type="java.lang.String">
<column name="password" length="45" />
</property>
</class>
</hibernate-mapping>
(4)编写配置文件hibernate.cfg.xml
- 指定连接那个数据库,用户名与密码等
- <session-factory>子元素用来定义会话工厂,若要连接多个数据库则要多个会话<session-factory>,通常放在多个配置文件中。
- <mapping>子元素指定持久化类映射文件相对地址
- <property>定义数据库连接信息
- dialect:方言
<hibernate-configuration>
<session-factory>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://127.0.0.1:3306/mydatabase
</property>
<property name="connection.username">root</property>
<property name="connection.password">11066</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver</property>
<property name="myeclipse.connection.profile">
mydatabase
</property>
<mapping resource="com/Emailtab.hbm.xml" />
</session-factory>
</hibernate-configuration>
(5)编写测试程序
用会话工厂创建org.hibernate.Session会话对象,再创建Transaction事务对象。对数据的操作在事务提交后同步到数据库。
删除指定ID元组:
org.hibernate.Session session =HibernateSessionFactory.getSession();
Transaction tx=null;
try {
tx=session.beginTransaction();
Emailtab email=(Emailtab)session.get(Emailtab.class, emailId);
session.delete(email);
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
request.setAttribute("msg", "删除记录失败");
if(tx!=null)
tx.rollback();
}finally{
session.close();
}
Hibernate核心组件
- Configuration:读取配置文件,可获得数据库URL等基本信息
- SessionFactory:创建Session对象
- Session接口:通 load(),get(),save(),update(),delete()实现对PO(persistant object)的操作。save()将数据从临时状态持久化到数据库
- Query接口:对数据库操作,Hibernate查询是对可持久化类查询,所以注意HQL:from 类名,要大写
Query query=session.createQuery("from Student" );
List list=query.list();//再遍历list
Query query=session.createQuery("delete from Student" );
query.executeUpdate();
myeclipse用hibernate操作数据库
- 用mysql建数据表(手动)
- 创建持久化类(自动,java类,有get/set方法),Student.java
- 定义映射文件:student.hbm.xml(自动),与student.java放在同一目录。每个可持久化类对应一个映射文件,命名前同类名,指定数据库连接参数,映射文件等
- 编写配置文件hibernate.cfg.xml(自动),放在源文件包同目录下,如与com文件夹同目录。
- 使用:测试代码
- 具体操作教程:https://blog.youkuaiyun.com/u012561176/article/details/45919751#
- 建一个java项目,右键add hibenate capability
- 建数据库,连接数据库
- 对于要操作的数据表,右键选择Hibernate Reverse Engineering,进行反向工程,建映射文件和可持久化对象
- 可以新建.java文件进行测试,此时对类的对象操作就会对数据表改变
//主函数通过HibernateSessionFactory类的getSession方法获得Session对象:
Session session=HibernateSessionFactory.getSession();
session.save(stu);
//开始事务
Transaction tx=session.beginTransaction();
//如果要插入:
Student info=new Student(3, 2019000003,"王五", 18, "计算机");//通过Stuinfo这个类的构造方法设置id、name、sex、age值
session.save(info);//通过session保存info对象
session.flush();//刷新session
session.save()返回一个序列化对象,即主键
tx.commit()//提交事务
关联映射
一对多关联
- 单向关联:只用在一个映射文件配置。可以从实体A导到实体B,反过来不能。
- 双向关联:在两个映射文件配置。
单向一对多关联
设为Department与Employee
- 在“一”的一方可持久化类Department添加Set<Employee>类型成员,并添加get/set方法、修改构造函数
- 在“一”的一方映射文件中<class>中添加:
<set name="students" inverse="true">
<key>
<column name="gid" />
</key>
<one-to-many class="com.entity.Employee" />
</set>
双向一对多关联
不仅“一”方要加,在“多”方中也添加一方类型变量(注意不是set)
同理定义映射文件,再在Student中添加<many-to-one>映射
一对一与多对多
都要在双方创建对方类型对象,不过后者为set类型
映射文件前者为<one-to-one>后者在<set>元素中定义<many-to-many>