Hibernate框架自学笔记

来源:互联网 发布:流量软件哪个好 编辑:程序博客网 时间:2024/05/18 19:43

Hibernate

在创建Hibernate项目时,先导入相应的包,然后编写配置文档,在src目录下的hibernate.cfg.xml文档。在相应的表结构里面创建单个表单映射。如Student.hbm.xml

一.hibernate.cfg.xml常用配置

1)hibernate.show_sql 编码阶段便于测试

2)hibernate.format_sql 排版问题,建议设置为true

3)hbm2ddl.auto 可以帮助由 java代码生成数据库脚本,进而生成具体的表结构。create/update/create- drop/validatereate(重新改变结构,原来的所有记录都不见了:先drop,再create)/update(检查schema是否一致,如果不一致会做scheme更新)/create-drop(先create,在系统关闭前执行drop)/validate(验证现有schema与你配置的hibernate是否一致,如果不一致就抛出异常,并不做更新)

4)hiberante.default_schema 默认的数据库

5)hibernate.dialect 配置Hibernate数据库方言

 

hiberante的前缀可以省略,即:hibernate.dialect等同于dialect

在创建

结构如下:

 

 

配置文档(我自己定义的数据库如下):

<!DOCTYPE hibernate-configuration PUBLIC

        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

 

<hibernate-configuration>

    <session-factory>

        <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>

        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

        <property name="hibernate.connection.username">WUYI</property>

        <property name="hibernate.connection.password">Wuyi1482675166</property>

        <property name="hibernate.connection.url">

         <![CDATA[

         jdbc:oracle:thin:@localhost:1521:orcl

         ]]>

        </property>

        <property name="show_sql">true</property>

        <property name="hbm2ddl.auto">update</property>

    

     <!-- 指定映射文件的路径 -->

     <mapping resource="eneity/Grade.hbm.xml"/>

     <mapping resource="eneity/Student.hbm.xml"/>

    </session-factory>

</hibernate-configuration>

二.Student.hbm.xml的配置

完成hibernate.cfg.xml配置文件后,要新建Studnet.java这个类,要求如下

创建持久化类的设计原则:

javabeans封装的四个原则

1.公有的类

2.无参公有默认的构造方法

3.属性私有

4.setget方法

如新建的Student.java类要映射到ORacle数据库中的时候必须满足以上几点要求

然后在该文件夹下新建Student.hbm.xml这个配置文件,目的是映射表单,

文件配置内容如下:<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="eneity.Student" table="student">

<id name="sid" type="java.lang.Integer">

<column name="sid"></column>

<generator class="increment"></generator>

</id>

<property name="sname" type="java.lang.String" >

<column name="sname" length="20" not-null="true"></column>

</property>

<property name="gender" type="java.lang.String">

<column name="sex"></column>

</property>

<property name="birthday" type="java.util.Date">

<column name="birthday"></column>

</property>

<property name="address" type="java.lang.String">

<column name="address"></column>

</property>

</class>

</hibernate-mapping>

三.Junit进行测试

Junit测试主要有@Before @After @Test三个方法

测试类:import java.util.Date;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.service.ServiceRegistryBuilder;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

import eneity.Student;

 

//测试类

public class StudentsTest {

private SessionFactory sessionFactory;

private Session session;

private Transaction transaction;

@Before

public void init(){

//创建配置对象

Configuration config=new Configuration().configure();

//创建服务注册对象

ServiceRegistry serviceRegistry =new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();

//创建会话工厂对象

sessionFactory=config.buildSessionFactory(serviceRegistry);

//会话对象

session=sessionFactory.openSession();

//开启事务

transaction=session.beginTransaction();

}

@After

public void after(){

transaction.commit();//提交事物

session.close();//关闭会话

sessionFactory.close();//关闭会话工厂

}

@Test

public void testSaveStudents(){

Student s=new Student(1,"wuyi","",new Date(),"武汉");

session.save(s);//保存对象到数据库

}

}

 

 

 

 

四.Session详解

openSession 每次使用都是打开一个新的session,使用完需要调用close方法关闭session

getCurrentSession 是获取当前session对象,连续使用多次时,得到的session都是同一个对象,这就是与openSession的区别之一 ;

一般在实际开发中,往往使用getCurrentSession多,因为一般是处理同一个事务,所以在一般情况下比较少使用openSession

 

如何获得session对象???

1openSessionion

2getCurrentSession

如果使用getCurrentSession需要在hibernate.cfg.xml文件中进行配置:

如果是本地事务(jdbc事务)(常用的是本地事务)

<property name="hibernate.current_session_context_class">thread</property>

如果是全局事务(jta事务)

<property name="hibernate.current_session_context_class">jta</property>

 

openSessiongetCurrentSession的区别:

1getCurrentSession在事务提交或者回滚之后会自动关闭,而openSesssion需要你手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出!

2openSession每次创建新的session对象,getCurrentSession使用现有的session对象

 

openSessiongetCurrentSession

openSession 每次使用都是打开一个新的session,使用完需要调用close方法关闭session

getCurrentSession 是获取当前session对象,连续使用多次时,得到的session都是同一个对象,这就是与openSession的区别之一 ;

一般在实际开发中,往往使用getCurrentSession多,因为一般是处理同一个事务,所以在一般情况下比较少使用openSession

五.Hibernate单表操作

组件属性:实体类中的某个属性属于用户自定义类的对象;

作用:将两个实体类合并在一起组建成一个表

hbm.xml文件中配置:

格式:

<component name="取的名字" class="类名">

<property name="类中属性" column="对应生成数据库中列属性名">

</component>

 

单表操作CRUD实例

1save

                //生成学生对象

student s=new student( 0, "你的傻儿子", "", new Date());

Address address =new Address("342400","789456132","赣州市");

s.setAddress(address);

session.save(s);//保存对象进数据库

System.out.println(s);

2update

        student s=(student) session.get(student.class,0);

s.setSname("而今打海盗");

System.out.println(s);

3delete

        student s=(student) session.get(student.class,0);

session.delete(s);

4get/load(查询单个记录)

        1.get:    student s=(student) session.get(student.class,0);

  System.out.println(s);

         

        2.load:   student s=(student) session.load(student.class,0);

  System.out.println(s);

                 

getload区别:

1.get()调用后立即发出sql语句,并返回持久化对象;load()使用对象时才发出sql语句,返回的是代理对象

2.当查询到数据为空时,get返回nullload抛出objectNotFound异常

 

六.Hibernate单向一对多关联 和多对一关联

创建持久化类和映射文件并配置单向一对多关系

a.持久化类

1.创建学生持久化类

2.创建班级持久化类(在一方定义一个多方集合)

b.配置映射文件

//班级映射文件

 <class name="com.entity.Grade" table="grade">

      <id name="gid" column="gid" type="java.lang.Integer">

      <generator class="increment"></generator>

      </id>

      <property name="gname" type="java.lang.String">

      <column name="gname" not-null="true" length="20"></column>

      </property>

      <property name="gdesc" type="java.lang.String">

      <column name="gdesc"></column>

      </property>

      <!-- 配置单向一对多关系 -->

      <set name="一方实体类定义的多方的引用,即多方属性Students" table="多方的表名Students">

        <key column="关联外键的列gid"></key>

        <one-to-many class="多方实体类的全类名com.entity.Student"></one>

      </set>

   </class>

//学生映射文件(同上略)

 

//hibernate.cfg.xml中配置

    <!-- 指定映射文件 -->

    <mapping resource="com/entity/Grade.hbm.xml"></mapping>

    <mapping resource="com/entity/Student.hbm.xml"></mapping>

 

多对一关联:

单向多对一的配置:

1.在多方持久类定义一方的引用

private Grade grade;gettersetter

2.在多方的映射文件中添加

<many-to-one name="指定对一方的引用,即一方引用所定义的属性grade" class="一方对应的持久化类,即关联实体类com.imooc.entity.Grade" cloumn="外键的列名gid" ></many-to-one>

测试代码如下:

public static void save(){

Grade g=new Grade("Java一班", "Java软件开发一班");

Student s1=new Student("小米", "");

Student s2=new Student("小明","");

//创建多对一的配置

s1.setGrade(g);

s2.setGrade(g);

Session session=HibernateUtil.getSession();

Transaction transaction=session.beginTransaction();

session.save(g);

session.save(s1);

session.save(s2);

transaction.commit();

HibernateUtil.closeSession(session);

 

一、单向多对一关联

1)简介

1.在己方(多方)表中的一个外键参照另一个表的主键

2.通过在多方持有一方的引用实现,需要在多方配置<many-to-one>

2)配置

1.在多方持久类定义一方的引用

private Grade grade;getter,setter

2.在多方的映射文件中添加

<many-to-one name="指定对一方的引用,即一方引用所定义的属性grade" class="一方对应的持久化类,即关联实体类com.imooc.entity.Grade" cloumn="外键的列名gid" ></many-to-one>

3)测试

public static void save(){

Grade g=new Grade("Java一班", "Java软件开发一班");

Student s1=new Student("小米", "");

Student s2=new Student("小明","");

//创建多对一的配置

s1.setGrade(g);

s2.setGrade(g);

Session s=HibernateUtil.getSession();

Transaction t=s.beginTransaction();

s.save(g);

s.save(s1);

s.save(s2);

t.commit();

HibernateUtil.closeSession(s);

}

 

二、双向多对一关联

1)分别在持久化类中定义另一方的引用;

一方:private Set<Student>students=new HashSet<Student>();setter,getter

多方:private Grade grade;setter,getter;

2)关联关系配置

//一方

<set name="一方实体类定义的多方的引用,即多方属性Students" table="多方的表名Students">

  <key column="关联外键的列gid"></key>

  <one-to-many class="多方实体类的全类名com.imooc.entity.Student" ></one>

</set>

//多方(同上略)

 

(3)测试(同上略

 

七.inverse和cascade属性 

对于inverse属性的说明;set里面的inverse属性的默认值是false,表示不反转,由one方进行维护。这样对性能有影响。

设置为true,由many方进行维护,one方就不再进行关联关系的维护,可以提高性能。

1、一方的hbm.xml文件的<set>节点的inverse属性指定了关联关系的控制方向,默认由one方来维护;

2、关联关系中,inverse="false"则为主动方,由主动方负责维护关联关系;

3、在一对多关联中,设置one方的inversetrue,这将有助于性能的改善。

 

cascade属性设为all时,所有操作都级联;

设为save-update时,在保存和更新时级联;

设为delete时,在删除时级联;

设为none时,所有操作都不级联。

 

nversecascade属性

 

一、inverse属性

1、一方的hbm.xml文件的<set>节点的inverse属性指定了关联关系的控制方向,默认由one方来维护;

2、关联关系中,inverse="false"则为主动方,由主动方负责维护关联关系;

3、在一对多关联中,设置one方的inversetrue,这将有助于性能的改善。

 

二、级联(cascade)属性

配置映射文件:

//grade映射文件

      <!-- 配置单向一对多关系;设置inversetrue,有多方进行关联关系的维护;当保存和更新时自动进行级联操作-->

      <set name="stu" table="stu" inverse="true" cascade="save-update">

        <!-- 指定关联的外键列 -->

        <key column="gid"></key>

        <one-to-many class="com.entity.Student"/>

      </set>

 

//student映射文件

<many-to-one name="grade" class="com.entity.Grade" column="gid" cascade="all"></many-to-one>

 

三、测试---信息查询

public static void findGradeByStudent(){

Session session=Hibernate

Util.getSession();

Student s1=(Student)session.get(Student.class, 2);

System.out.println(s1.getSid()+","+s1.getSname()+","+s1.getSex());

Grade g=s1.getGrade();

System.out.println(g.getGid()+","+g.getGname()+","+g.getGdesc());

HibernateUtil.closeSession(session);

}