Hibernate表单映射_学习笔记

来源:互联网 发布:android手机刷linux 编辑:程序博客网 时间:2024/05/16 07:58

第一天

一。Hibernate认识

ORM(Object/Relationship Mapping):对象/关系映射。
Hibernate就是一种开源的ORM框架技术。
Hibernate对JDBC进行了非常轻量级的封装。
Hibernate通常在业务逻辑层和数据库层中间是持久化层

二。开发前准备
开发工具:Eclipse
插件:Hibernate Tools for Eclipse Plugins              -------------------------可以自动生成配置文档
Hibernate Tools是由JBoss推出的一个Eclipse综合开发工具插件,主要是简化Hibernate的开发。

安装Hibernate Tools插件


重启Eclipse后

File-->New-->Other-->Hibernate出现一下画面,证明装成功



新建工程
导入Hibernate必须的jar包
hibernate-release-4.2.4.Final\lib\required
导入mysql的jdbc驱动
mysql-connector-java-5.1.7-bin.jar
导入Junit4的jar包-------单元测试使用
junit-4.1.0.jar


1.新建一个普通的java项目



2.导入所需的jar包

把需要使用的jar包放入mylib目录下

打开Eclipse----->Window------>Preferences


添加三个用户自定义类库


在新建的工程中导入这些jar包

右键 项目名称hibernate_w_01----->Properties

三。Hibernate例子(版本使用HIBERNATE4.2.4+ MySQL6.0)
1.创建Hibernate配置文件---hibernate.cfg.xml    -------->使用到上边安装的插件


配置文档代码:

<?xml version="1.0" encoding="UTF-8"?><!--  <!DOCTYPE hibernate-configuration PUBLIC        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">--><!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="connection.driver_class">com.mysql.jdbc.Driver</property>        <!-- 指定连接数据库的url -->        <property name="connection.url">jdbc:mysql:///hibernate?useUnicode=true&amp;characterEncoding=UTF-8</property>        <!-- 指定数据库的方言 -->        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>        <!-- 指定连接数据库的用户名 -->        <property name="connection.username">root</property>        <!-- 指定连接数据库的密码 -->        <property name="connection.password">123456</property>        <property name="show_sql">true</property>        <property name="format_sql">true</property>        <!-- 指定数据库生成策略 -->        <property name="hbm2ddl.auto">create</property>                <mapping resource="students.hbm.xml"/>     </session-factory></hibernate-configuration>

2.创建持久化类

在src目录下创建一个名为:Students.java的学生类

package hibernate_w_01;import java.sql.Date;//学生类public class Students {// javaBeans设计原则// 1.共有的类// 2.提供共有的不带参数的默认的构造方法// 3.属性私有// 4.属性setter/getter封装private int sid;// 学号private String sname;// 姓名private String gender;// 性别private Date birthday;// 出生日期private String address;// 地址public Students() {}public Students(int sid, String sname, String gender, Date birthday,String address) {// super();this.sid = sid;this.sname = sname;this.gender = gender;this.birthday = birthday;this.address = address;}public int getSid() {return sid;}public void setSid(int sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public String toString() {return "Students [sid=" + sid + ", sname=" + sname + ", gender="+ gender + ", birthday=" + birthday + ", address=" + address+ "]";}}


3.创建对象-关系映射文件

在src下新建

在hibernate.cfg.xml文件中添加一段<mapping resourse="students.hbm.xml"/>   

<?xml version="1.0"?><!--  <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">--><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><!-- Generated 2017-7-5 12:46:30 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping>    <class name="Students" table="STUDENTS">        <id name="sid" type="int">            <column name="SID" />            <generator class="assigned" />        </id>        <property name="sname" type="java.lang.String">            <column name="SNAME" />        </property>        <property name="gender" type="java.lang.String">            <column name="GENDER" />        </property>        <property name="birthday" type="java.sql.Date">            <column name="BIRTHDAY" />        </property>        <property name="address" type="java.lang.String">            <column name="ADDRESS" />        </property>    </class></hibernate-mapping>


使用Junit进行单元测试


新建一个源文件夹

选中项目hibernate_w_01--------New------>Source Folder


使用navicat连接MySQL建立一个新数据库





4.通过Hibernate API编写访问数据库的代码

在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;//测试类public class StudentsTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic 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();}@Afterpublic void destory() {//提交事务transaction.commit();//关闭会话session.close();//关闭会话工厂sessionFactory.close();}@Testpublic void testSaveStudents() {Students s = new Students(1, "张三", "男", new Date(), "老君山");//保存对象进入数据库session.save(s);}}

运行结果:




第二天

1.hibernate.cfg.xml常用配置

属性名称含义hibernate.show_sql是否把hibernate运行时的SQL语句输出到控制台,编码阶段便于测试。hibernate.format_sql输出到控制台的SQL语句是否进行排版,便于阅读。建议设置为true。hbm2ddl.auto可以帮助由java代码生成数据库脚本,进而生成具体的表结构。create | update | create-drop | validatehibernate.default_schema 默认的数据库(在数据库前边加前缀)hibernate.dialect配置Hibernate数据库方言,Hibernate可针对特殊的数据库进行优化hibernate.dialect的前缀可以省略,即:hibernate.dialect等同于dialcet

2.session简介

hibernate的执行流程

seeeion和JDBC中的connection作用雷同,可以把session理解为操作数据库的对象。

session与connection,是多对一关系,每个session都有一个与之对应的connection,一个connection不同时刻可以提供多个session使用。

把对象保存在关系数据库中需要调用session的各种方法,如:save(),update(),delete(),createQuery()等。

3.transaction简介


hibernate对数据的操作都是封装在事务当中,并且默认是非自动提交的方式。所以用session保存对象,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中。


如果想让hibernate想jdbc那样自动提交事务,必须调用session对象的doWork()方法,获得jdbc的connection后,设置其为自动提交事务模式(通常不这样做)。

@Testpublic void testSaveStudents() {Students s = new Students(1, "张三", "男", new Date(), "老君山");session.doWork(new Work(){@Overridepublic void execute(Connection arg0) throws SQLException {// TODO Auto-generated method stubarg0.setAutoCommit(true);}});// 保存对象进入数据库session.save(s);session.flush();}


4.session详解

获得session对象的方法

  • openSession
  • getCurrentSession

这两种方法都来自SessionFactory


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

如果是本地事务(jdbc事务)

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

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

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

例子:

import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.Test;public class SessionTest {@Testpublic void testOpenSession() {// 获得配置对象Configuration config = new Configuration().configure();// 获得服务注册对象ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();// 获得sessionFactory对象SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);// 获得session对象Session session = sessionFactory.openSession();if (session != null) {System.out.println("session创建成功!");} else {System.out.println("session创建失败!");}}@Testpublic void testGetCurrentSession() {// 获得配置对象Configuration config = new Configuration().configure();// 获得服务注册对象ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();// 获得sessionFactory对象SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);// 获得session对象Session session = sessionFactory.getCurrentSession();if (session != null) {System.out.println("session创建成功!");} else {System.out.println("session创建失败!");}}}
testGetCurrentSession()测试方法必须要在hhibernate.cfg.xml中添加一句

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


openSession与getCurrentSession的区别

  • getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession需要手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。
  • openSession每次创建新的session对象,getCurrentSession使用现有的session对象。


5.对象关系映射常用配置

<hibernate-mapping schema="schemaName"                         //设置模式名子catalog="catalogName"//设置目录名称default-cascade="cascade_style"   //级联风格default-access="field|property|ClassName"   //访问策略default-lazy="true|false"                   //加载策略package="packagename"                       //默认包名/>

<classname="ClassName"table="tableName"batch-size="N"               //抓取策略,一次可以抓取的记录条数where="condition" //抓取条件entity-name="EntityName"     //支持一个类映射成多个表/>

<id   //用id标签代表的是主键name="propertyName"type="tpename"column="column_name"  //表中字段名称length="length"<generator class="genertorClass"/>  //主键生成策略/>

主键生成策略
标识符生成器描述increment(常用)适用于代理主键。由Hibernate自动以递增方式生成。identity(常用)适用于代理主键。由底层数据库生成据标识符。sequence(常用)适用于代理主键。Hibernate根据底层数据库的序列生成标识符,这要求底层数据库支持序列hilo适用于代理主键。Hibernate分局hight/low算法生成表示符seqhilo适用于代理主键。使用一个高/低位算法来搞笑的生成long,short或者int类型的标识符native(最常用)适用于代理主键。根据底层数据库对自动生成标识符的方式,自动选择identity,sequence或hilo。uuid.hex适用于代理主键。Hibernate采用128位的UUID算法生成标识符。uuid.string适用于代理主键。UUID被编码成一个16字符长的字符串。assigned(最常用)适用于自然主键。有Java用用程序负责生成标识符。foreign适用于代理主键。使用灵位一个相关联的对象的标识符。

第三天:Hibernate单表操作

1.单一主键

由一列充当主键。


以MySQL为例

  • assigned 由java应用程序负责生成(手工赋值)。
  • native 由底层数据库自动生成标识符,如果是MySQL就是increment,如果是Oracle就是sequence,等等。

2.基本类型

Hibernate映射类型java类型标准SQL类型大小integer/intjava.lang.Integer/intINTEGER4字节longjava.lang.Long/longBIGINT8字节shortjava.lang.Short/shortSMALLINT2字节bytejava.lang.Byte/byteTINYINT1字节floatjava.lang.Float/floatFLOAT4字节doublejava.lang.Double/doubleDOUBLE8字节big_decimaljava.math.BigDecimalNUMERIC characterjava.lang.Character/java.lang.String/charCHAR(1)定长字符stringjava.lang.StringVARCHAR变长字符boolean/ yes_no/true_falsejava.lang.Bolean/BooleanBIT布尔类型datejava.util.Date/java.sql.DateDATE代表日期:yyyy-MM-ddtimejava.util.Date/java.sql.TimeTIME代表时间:hh:mi:sstimestampjava.util.Date/java.util.TimestampTIMESTAMP代表时间和日期:yyyymmddhhmisscalendarjava.util.CalendarTIMESTAMP同上calendar_datejava.util.CalendarDATE日期:yyyy-MM-dd

3.对象类型

映射类型Java类型标准SQL类型MYSQL类型Oracle类型binarybyte[]VARCHAR(或BLOB)BLOBBLOBtextjava.lang.StringCLOBTEXTCLOBcolbjava.sql.ClobCLOBTEXTCLOBblobjava.sql.BlobBLOBBLOBBLOB

Mysql不支持标准SQL的CLOB类型,在Mysql中,用TEXT,MEDIUMTEXT及LONGTEXT类型来表示长度超过255的长文本数据。

private Blob picture;//照片        public Blob getPicture() {return picture;}public void setPicture(Blob picture) {this.picture = picture;}

import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.sql.Blob;import java.sql.SQLException;import java.util.Date;import org.hibernate.Hibernate;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;//测试类public class StudentsTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic 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();}@Afterpublic void destory() {// 提交事务transaction.commit();// 关闭会话session.close();// 关闭会话工厂sessionFactory.close();}@Testpublic void testSaveStudents() {Students s = new Students(1, "张三", "男", new Date(), "老君山");// 保存对象进入数据库session.save(s);}@Testpublic void testWriteBlob() throws IOException{Students s = new Students(1, "张三", "男", new Date(), "老君山");//先获得照片文件File.separator为路径分割符File f=new File("e:"+File.separator+"1.jpg");//获得照片文件输入流InputStream input =new FileInputStream(f);//创建一个Blob对象Blob image=Hibernate.getLobCreator(session).createBlob(input,input.available());//设置中照片属性s.setPicture(image);//保存学生session.save(s);}@Testpublic void testReadBlob() throws SQLException, IOException{Students s=(Students) session.get(Students.class, 1);//获得Blob对象Blob image=s.getPicture();//获得照片输入流InputStream input =image.getBinaryStream();//创建输出流File f=new File("d:"+File.separator+"dest.jpg");//获得输出流OutputStream output=new FileOutputStream(f);//创建缓冲区byte[] buff=new byte[input.available()];input.read(buff);output.write(buff);input.close();output.close();}}

4.组件属性

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

如配置文档中的:name="address"就是一个组件属性。

<component name="address" class="Address"><property name="postcode" column="POSTCODE"></property><property name="phone" column="PHONE"></property><property name="address" column="ADDRESS"></property></component>


5.单表操作CRUD实例

  • save (保存)
  • update(修改)
  • delete(删除)
  • get/oad(查询单个记录)

@Testpublic void testGetStudents(){Students s=(Students) session.get(Students.class, 1);System.out.println(s);}@Testpublic void testLoadStudent(){Students s=(Students) session.load(Students.class, 1);System.out.println(s);}@Testpublic void testUpdateStudents(){Students s=(Students) session.get(Students.class, 1);s.setGender("女");session.update(s);}@Testpublic void testDeleteStudents(){Students s=(Students) session.get(Students.class, 1);session.delete(s);}


get与load的区别


在不考虑缓存的情况下,get方法会在调用之后立即向数据库发出sql语句,返回返回持久化对象。

load方法会在调用后返回一个代理对象。

该代理对象只保存了实体对象的id,直到使用对象的非主键属性时才会发出sql语句。


查询数据库中不存在的数据时,get方法返回null,

load方法抛出异常org.hibernate.ObjectNotFoundException。











原创粉丝点击