Hibernate

一、我们从三个角度理解一下Hibernate:

1、Hibernate是对JDBC进一步封装
原来没有使用Hiberante做持久层开发时,存在很多冗余,如:各种JDBC语句,connection的管理,所以出现了Hibernate把JDBC封装了一下,我们不用操作数据,直接操作它就行了。

2、从分层的角度来看
我们知道非常典型的三层架构:表示层,业务层,还有持久层。Hiberante也是持久层的框架,而且持久层的框架还有很多,比如:IBatis,Nhibernate,JDO,OJB,EJB等等。

3、Hibernate是开源的一个ORM(对象关系映射)框架。
ORM,即Object-Relational Mapping,它的作用就是在关系型数据库和对象之间做了一个映射。从对象(Object)映射到关系(Relation),再从关系映射到对象。这样,我们在操作数据库的时候,不需要再去和复杂SQL打交道,只要像操作对象一样操作它就可以了(把关系数据库的字段在内存中映射成对象的属性)。

二、Hibernate框架的组成架构图如下


从上图中,我们可以看出Hibernate六大核心接口,两个主要配置文件,以及他们直接的关系。Hibernate的所有内容都在这了。

1)Configuration接口:负责配置并启动Hibernate
2)SessionFactory接口:负责初始化Hibernate
3)Session接口:负责持久化对象的CRUD操作
4)Transaction接口:负责事务
5)Query接口和Criteria接口:负责执行各种数据库查询

注意:Configuration实例是一个启动期间的对象,一旦SessionFactory创建完成它就被丢弃了。

三、Hibernate的优/缺点:

1、优点:
1)更加对象化
以对象化的思维操作数据库,我们只需要操作对象就可以了,开发更加对象化。

2)移植性
因为Hibernate做了持久层的封装,你就不知道数据库,你写的所有的代码都具有可复用性。

3)Hibernate是一个没有侵入性的框架,没有侵入性的框架我们称为轻量级框架。
对比Struts的Action和ActionForm,都需要继承,离不开Struts。Hibernate不需要继承任何类,不需要实现任何接口。这样的对象叫POJO对象。

4)Hibernate代码测试方便。

5)提高效率,提高生产力。

2、缺点:
1)使用数据库特性的语句,将很难调优
2)对大批量数据更新存在问题
3)系统中存在大量的攻击查询功能

四、hibernate配置:

准备工作:下载hibernate,这里下的是4.3.11版本的;

1、添加jar包到工程中:


2、在src根目录下创建hibernate.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>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@172.16.130.35:1521:orcl</property>
        <property name="connection.username">wtyy1</property>
        <property name="connection.password">wtyy1</property>
        
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

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

    </session-factory>

</hibernate-configuration>
注意这一句
<property name="hbm2ddl.auto">update</property>
这一句非常重要,如果数据表不存在会自动创建,并且如果后来改了实体类(当然也改了映射)的话,这时候不需要手动去修改数据库,系统会自动更改数据库。
3、实体类:

Student.java:

package com.zt.domain;

import java.io.Serializable;

public class Student implements Serializable {
	private int id;
	private String name;
	private String sex;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

}

在实体类同级目录下创建映射文件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 package="com.zt.domain">
    <class name="Student" table="TB_STUDENT">
       <id name="id" column="ID" type="int">
          <generator class="native"></generator>
       </id>
       <property name="name" column="NAME"></property>
        <property name="sex" column="SEX"></property>
    </class>
</hibernate-mapping>

4、编写Util类获得SessionFactory:

package com.zt.util;

import org.hibernate.SessionFactory;


import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
   private static SessionFactory sessionFactory;
   static {
	   sessionFactory = new Configuration()
               .configure() // configures settings from hibernate.cfg.xml
               .buildSessionFactory();
   }
   public static SessionFactory getSessionFactory() {
     return sessionFactory;
   }
}


5、测试程序:

package com.zt.test;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.zt.domain.Student;
import com.zt.util.HibernateUtil;

public class StudentTest {
public static void main(String[] args) {
	Session session=HibernateUtil.getSessionFactory().openSession();
	Transaction ts=session.getTransaction();
	ts.begin();
	Student student=new Student();
	student.setId(3);//如果已设为自动增长序列,则手动指定的会被忽略
	student.setName("李四");
	student.setSex("男");
	session.save(student);
	ts.commit();
	session.close();
}
}

注意:这两个xml配置文件包括util类的编写方法(即SessionFactory的获取)在下载的hibernate里面都可以找到,并且不同的hibernate版本可能会有差异。


五、hibernate使用注解发方式完成实体类和数据表的映射:前面使用的是xml配置的方式,显得比较麻烦,下面使用注解发方式完成同样的功能:

package com.zt.domain;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name="student")
@SequenceGenerator(name="seq_stu")//主键生成
public class Student implements Serializable {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO,generator="seq_stu")
	private int id;
	private String name;
	private String sex;
	private String birthday;

	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

}
现在就可以把之前的Student.hbm.xml文件删掉,把hibernate.cfg.xml里面原来的映射配置

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

改成:

<mapping class="com.zt.domain.Student"/>

OK!

说明:(注解实际上是一个注释,用来标记对象(字段,type,方法),为特殊用途,给某些程序读取使用,target:标记目标,type field method。)

@Retention:状态持续的范围
@Entity,注册在类头上,将一个类声明为一个实体bean(即一个持久化POJO类) 。
@Table,注册在类头上,注解声明了该实体bean映射指定的表(table)。
@SequenceGenerator( name="SEQ_ID",sequenceName="my_sequence")
@Id用来标识主属性列,

标记主键生成策略
@GeneratedValue:@GeneratedValue(strategy=GenerationType.IDENTITY)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_ID")
@Column:标识列-属性,
@Transient用来注册不是数据库关联的属性
以上的@Id、@GeneratedValue、 @Column:可以写在属性也可写在属性对应的getter上。

@Transient注册在多余的属性上,在getter上时必须与以上的@Column等对应

@Column里面的属性
name="列名"
unique=false该列是否设置唯一 默认false
nullable 该列是否可为空 默认false
insertable :该列在生成的insert语句中的出现 默认 true
updatable :该列在生成的update语句中的出现 默认 true
length :长度 默认255

六、oracle特殊字段对应hibernate的注解:

1、CLOB类型:大数据文本,对应的pojo字段类型为String,同时需要有注解说明:

@Lob
	@Basic(fetch = FetchType.EAGER)
	@Column(columnDefinition = "CLOB")


如:

package com.iflytek.domain;

import java.io.Serializable;
import java.sql.Clob;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.springframework.stereotype.Component;

//通知公告
@Component
@Entity
@Table(name = "T_MZYW_TZGG")
@SequenceGenerator(name = "seq_tzgg", sequenceName = "seq_tzgg")
public class Notice implements Serializable{
	private String id;
	private String tzggbt;
	private String tzggzw;
	

	public void setId(String id) {
		this.id = id;
	}

	public void setTzggbt(String tzggbt) {
		this.tzggbt = tzggbt;
	}

	public void setTzggzw(String tzggzw) {
		this.tzggzw = tzggzw;
	}

	
	@Id
	@GeneratedValue(generator = "seq_tzgg")
	@GenericGenerator(name = "seq_tzgg", strategy = "uuid")
	public String getId() {
		return this.id;
	}

	public String getTzggbt() {
		return this.tzggbt;
	}

	@Lob
	  @Basic(fetch = FetchType.EAGER)
	  @Column(columnDefinition="CLOB")
	public String getTzggzw() {
		return this.tzggzw;
	}

	

	public String toString() {
		return "id=" + id + "tzggbt=" + tzggbt + "tzggzw=" + tzggzw + "tzggzt=" + tzggzt + "fbsj=" + fbsj + "fbcsbm="
				+ fbcsbm + "fbcsmc=" + fbcsmc + "yxbs=" + yxbs + "cjyhbm=" + cjyhbm + "cjyhmc=" + cjyhmc + "zhxgyhbm="
				+ zhxgyhbm + "zhxgyhmc=" + zhxgyhmc;
	}
}


2、BLOB类型:二进制文本,对应的pojo类型为byte[]即字符数组,同时需要的注解说明:

@Lob
@Basic(fetch = FetchType.LAZY)
@Column(columnDefinition = "BLOB")

如:

package com.iflytek.domain;

import java.math.BigDecimal;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.springframework.stereotype.Component;

@Component
@Entity
@Table(name="T_mzyw_sczy")
@SequenceGenerator(name="seq_sczy",sequenceName="seq_sczy")
public class Sczy{
  private String id;
private String glbmc;
private String glbxxdm;
private String glywdm;
private String cclx;
private String ljlx;
private String ccqlj;
private String wjm;
private String wjlx;
private byte[] wjnr;
private BigDecimal wjdx;
private String scsj;
private String yxbs;
public void setId(String id){
 this.id=id;
}
public void setGlbmc(String glbmc){
 this.glbmc=glbmc;
}
public void setGlbxxdm(String glbxxdm){
 this.glbxxdm=glbxxdm;
}
public void setGlywdm(String glywdm){
 this.glywdm=glywdm;
}
public void setCclx(String cclx){
 this.cclx=cclx;
}
public void setLjlx(String ljlx){
 this.ljlx=ljlx;
}
public void setCcqlj(String ccqlj){
 this.ccqlj=ccqlj;
}
public void setWjm(String wjm){
 this.wjm=wjm;
}
public void setWjlx(String wjlx){
 this.wjlx=wjlx;
}
public void setWjnr(byte[] wjnr){
 this.wjnr=wjnr;
}
public void setWjdx(BigDecimal wjdx){
 this.wjdx=wjdx;
}
public void setScsj(String scsj){
 this.scsj=scsj;
}
public void setYxbs(String yxbs){
 this.yxbs=yxbs;
}
@Id
@GeneratedValue(generator="seq_sczy")
@GenericGenerator(name="seq_sczy",strategy="uuid")
public String getId(){
 return this.id;
}
public String getGlbmc(){
 return this.glbmc;
}
public String getGlbxxdm(){
 return this.glbxxdm;
}
public String getGlywdm(){
 return this.glywdm;
}
public String getCclx(){
 return this.cclx;
}
public String getLjlx(){
 return this.ljlx;
}
public String getCcqlj(){
 return this.ccqlj;
}
public String getWjm(){
 return this.wjm;
}
public String getWjlx(){
 return this.wjlx;
}
@Lob
@Basic(fetch = FetchType.LAZY)
@Column(columnDefinition = "BLOB")
public byte[] getWjnr(){
 return this.wjnr;
}
public BigDecimal getWjdx(){
 return this.wjdx;
}
public String getScsj(){
 return this.scsj;
}
public String getYxbs(){
 return this.yxbs;
}
public String toString(){
return "id="+id+"glbmc="+glbmc+"glbxxdm="+glbxxdm+"glywdm="+glywdm+"cclx="+cclx+"ljlx="+ljlx+"ccqlj="+ccqlj+"wjm="+wjm+"wjlx="+wjlx+"wjnr="+wjnr+"wjdx="+wjdx+"scsj="+scsj+"yxbs="+yxbs;
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值