Hibernate表单映射_学习笔记

第一天

一。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;

	@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 destory() {
		//提交事务
		transaction.commit();
		//关闭会话
		session.close();
		//关闭会话工厂
		sessionFactory.close();
	}

	@Test
	public 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 | validate
hibernate.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后,设置其为自动提交事务模式(通常不这样做)。

@Test
	public void testSaveStudents() {
		Students s = new Students(1, "张三", "男", new Date(), "老君山");
		session.doWork(new Work(){
			@Override
			public void execute(Connection arg0) throws SQLException {
				// TODO Auto-generated method stub
				arg0.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 {
	@Test
	public 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创建失败!");
		}
	}

	@Test
	public 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"                       //默认包名
/>

<class
	name="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-dd
timejava.util.Date/java.sql.TimeTIME代表时间:hh:mi:ss
timestampjava.util.Date/java.util.TimestampTIMESTAMP代表时间和日期:yyyymmddhhmiss
calendarjava.util.CalendarTIMESTAMP同上
calendar_datejava.util.CalendarDATE日期:yyyy-MM-dd

3.对象类型

映射类型Java类型标准SQL类型MYSQL类型Oracle类型
binarybyte[]VARCHAR(或BLOB)BLOBBLOB
textjava.lang.StringCLOBTEXTCLOB
colbjava.sql.ClobCLOBTEXTCLOB
blobjava.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;

	@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 destory() {
		// 提交事务
		transaction.commit();
		// 关闭会话
		session.close();
		// 关闭会话工厂
		sessionFactory.close();
	}

	@Test
	public void testSaveStudents() {
		Students s = new Students(1, "张三", "男", new Date(), "老君山");
		// 保存对象进入数据库
		session.save(s);
	}
	
	@Test
	public 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);
	}
	
	@Test
	public 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(查询单个记录)

@Test
	public void testGetStudents(){
		Students s=(Students) session.get(Students.class, 1);
		System.out.println(s);
	}
	@Test
	public void testLoadStudent(){
		Students s=(Students) session.load(Students.class, 1);
		System.out.println(s);
	}
	@Test
	public void testUpdateStudents(){
		Students s=(Students) session.get(Students.class, 1);
		s.setGender("女");
		session.update(s);
	}
	@Test
	public 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。











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值