初学者想学Hibernate初级基础教程

2016-02-19 19:28 16 1 收藏

最近很多朋友喜欢上设计,但是大家却不知道如何去做,别担心有图老师给你解答,史上最全最棒的详细解说让你一看就懂。

【 tulaoshi.com - 编程语言 】

  Hibernate理论基础

  1. 什么是hibernate?
  2. hibernate的知识内容
  3. 什么是对象持久化?对象持久化有什么用?(解决的问题)
  4. 如何对象持久化?
  5. 如何用数据库的方法做对象持久化?
  6. ORM(对象关系映射)是什么?有什么作用?
  7. ORM从对象到表所要考虑的问题
  8. 什么是ORM框架?有什么用?
  9. 使用hibernate的方法做对象持久化的工作,程序员应该怎么做?
  10. hibernate有什么用?
  11. 程序员和hibernate的整体工作流程

  什么是hibernate:

  持久化的框架,属于设计方面的内容,类库,用来做对象持久化的,什么是对象持久化呢?

  Hibernate的知识内容:

  语法部分(类库)

  程序设计思想,也就是持久层的设计

  什么是对象持久化?对象持久化有什么用?(解决的问题):

  发现问题:

  程序设计的架构: 表现层—业务层—持久层—数据库层,其中表现层和业务层是JVM来执行,应用程序会产生许多的对象,假如断电了,对象就消失了,也就是说在内存中的对象是不稳定的,状态不能持久

  发现问题:

  将一个对象从A电脑复制到B电脑,如何做到呢?

  那么有三种方法解决上面的问题:
  1. 序列化: 通过网络传递,或者硬盘共享
  2. 存储到数据库中,谁想用,从数据库中拿
  3. EJB Entity Bean(实体Bean)

  序列化的方法比较死板:假如当一个对象的结构比较复杂的时候,我们这时只需要一部分内容,没有办法,只能整个写入到文件,整个读取
  序列化的缺点: 不能检索,不能分离一个对象,不方便共享
  所以说第一种方法只能用于做临时的持久化,简单的传输,但不适合复杂的持久化工作

  第二种方法(数据库持久化):检索方便,分布式共享,永久数据

  总结:
  什么是对象持久化: 对象持久化就是把内存中的对象永久的保存起来,保护对象的状态,方便使用
  对象持久化有什么用: 1.解决掉电的问题 2.共享方便 3.保证对象安全检索方便

  如何对象持久化:
  1. 对象序列化
  2. 数据库(JDBC,EJB,Hibernate)

  如何用数据库的方法做对象持久化:
  1. JDBC
  发现问题: 需要做大量的工作,难度大
  2. EJB
  使用的是其中的一个功能来做持久化,解决了使用JDBC方法的的大量工作的问题
  发现问题: EJB是重量级的组件,要使用它,有两个问题 1.成本 2.性能

  发现问题: 以上两种方式还有个共同的问题,对象不是简单存储在数据库中的,比如多态的特点就不能处理 A b=new B(); B为A的子类

  3. Hibernate
  解决了以上的所有问题,作用:1.不用做大量的工作 2.移植性能好 3.提高了代码的质量,简单 4.检索共享重用成本调试

  ORM(对象关系映射)是什么?有什么作用?
  发现问题:
  Java中的对象的属性类型和数据库中的字段类型是不一样的,那么如何来存储java中的对象呢?这就需要做对象关系的映射,也就是ORM
  什么是ORM: 将内存中的对象和数据库做转化,这样就实现了java与数据库之间的访问等功能

  ORM从对象到表所要考虑的问题:
  Orm的复杂问题:
  1. 数据库如何保证对象的唯一性:在内存中,两个对象属性值都一样,但是内存地址不一样,可以做区分,但是在数据库中如何分辨呢?
  2. 继续关系如何转化
  3. 集合如何映射呢?

  什么是ORM框架?有什么用?
  就是一个类库,通过这个类库完成持久化层的设计

  使用hibernate的方法做对象持久化的工作,程序员应该怎么做?
  1. 将ORM方案定下来,就是类到数据库的转化 2.利用hibernate生成代码
  hibernate有什么用?
  1. 完成jdbc的代码
  2. 治理持久化对象的状态
  3. 提供一个查询的API

  程序员和hibernate的整体工作流程
  程序员:
  1. 设计ORM方案
  2. 写配置文件
  3. 调用Hibernate的API,向Hibernate发出命令
  hibernate:
  4. 读配置文件
  5. 生成jdbc代码
  6. 执行

  Hibernate简单实例
  Hibernate语法:
  作用: 数据库的增删改查 HQL面向对象的查询语句

  大致步骤:
  1. 设置环境 类库
  2. 定义映射
  A 定义映射的实体po
  B 建立数据库表
  C 写XML配置文件(表,数据库)
  3. 调用Hibernate API
  A 治理po的状态(增删改,恢复po状态)
  B 检索(查询)

  Hibernate第一个简单的实例: 引例(frisHbn包)
  1. 设置环境
  hibernate配置环境需要的资源
  Hibernate的jar包: lib.zip dtd.zip: dtd.zip可以不设置
  2. 定义映射
  建立项目:
  bussiness包: entity包 Biz包业务
  client包: 测试
  util包: 工具

  先写持久化类: 以花为实体,建立花类,并且建立数据库表
  /**
  * 建表语句:
  * CREATE TABLE T_FRUIT(
  FID NUMBER(10) PRIMARY KEY,
  
   NAME VARCHAR(20) NOT NULL,
  COMMENTS VARCHAR(50),
  PRICE NUMBER(5) NOT NULL
  );
  */
  package YUChen.fristHbn.business.entity;
  //持久化类(花类),注重因为采用的是hilo的方式获得id,所以需要有setid的方法
  public class Fruit {

  private Integer fid;//hibernate中的id不能识别int
  private String name;
  private String comments;
  private int price;

  public Fruit() {
  super();
  }

  public Fruit(String name, String comments, int price) {
  super();
  this.name = name;
  this.comments = comments;
  this.price = price;
  }

  public String getComments() {
  return comments;
  }
  public void setComments(String comments) {
  this.comments = comments;
  }

  public Integer getFid() {
  return fid;
  }
  public String getName() {
  return name;
  }
  public void setName(String name) {
  this.name = name;
  }
  public int getPrice() {
  return price;
  }
  public void setPrice(int price) {
  this.price = price;
  }

  public void setFid(Integer fid) {
  this.fid = fid;
  }

  }

  使用hilo的方式获得id:
  建表语句:
  CREATE TABLE T_HILO(HILO_ID NUMBER(10));
  INSERT INTO T_HILO VALUES(1);

  写hibernate的连接数据库的配置文件:
  ?xml version="1.0"?
  !DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
  hibernate-configuration
  session-factory
  property name="show_sql"true/property
  property name="connection.driver_class"Oracle.jdbc.driver.OracleDriver/property
  property name="connection.url"jdbc:oracle:thin:@127.0.0.1:1521:name/property
  property name="connection.username"scott/property
  property name="connection.passWord"tiger/property
  property name="connection.isolation"2/property
  property name="dialect"org.hibernate.dialect.Oracle9Dialect/property
  mapping resource="Yuchen/fristHbn/business/entity/Fruit.hbm.xml"/
  /session-factory
  /hibernate-configuration

  写映射配置文件:
  ?xml version="1.0"?
  !DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
  hibernate-mapping package="Yuchen.fristHbn.business.entity"
  class name="Fruit" table="T_FRUIT"
  id name="fid" column="fid"
  generator class="hilo"
  
   param name="table"t_hilo/param
  param name="column"hilo_id/param
  /generator
  /id
  property name="name" column="name" /
  property name="comments" column="comments"/property
  property name="price" column="price"/property
  /class
  /hibernate-mapping
  A. 类名—表名
  B. id—id 获得id的方式 具体信息(如: hilo的表名和字段)
  C. 属性—字段

  使用hibernate API(FruitManager.java):
  package Yuchen.fristHbn.business.Biz;
  //业务逻辑类:负责增删改查通过使用hibernate API进行
  import org.hibernate.Session;
  import org.hibernate.SessionFactory;
  import org.hibernate.Transaction;
  import org.hibernate.cfg.Configuration;

  import Yuchen.fristHbn.business.entity.Fruit;

  public class FruitManager {
  public void insert(Fruit fruit){
  Configuration config=new Configuration();
  config.configure();//读配置文件
  SessionFactory sf=config.buildSessionFactory();//得到工厂
  Session session=sf.openSession();//得到session
  Transaction tt=session.beginTransaction();//检查事务开启
  session.save(fruit);//存储insert
  tt.commit();//提交
  session.close();//关闭资源
  }
  }

   

  写测试类: 插入一个对象到数据库中
  /**
  * 知识点:
  * hibernate基础:练习语法部分API和简单的映射关系
  * 程序目标:
  * 使用hibernate方法将对象进行持久化
  * 实现数据库的增删改查
  * API:
  * 1.Configuration:这个类负责读取XML文档(映射配置文件)
  * configure():读xml
  * buildSessionFactory():创建一个生产session对象的工厂,其实是再次检查
  * 因为hibernate和jdbc不一样,jdbc是假如不手动设置开启事务,那它
  * 就是马上执行sql的,hibernate的不会马上执行,是事务提交后执行
  * 默认情况下就是打开事务的状态,这里只是再检查以下
  * 2.SessionFactory:负责生产session对象
  * openSession():创建一个session
  * 3.Session类:这个是主要的类,负责增删改查,开启事务等
  * beginTransaction():产生一个事务对象(Transaction)
  * save():增加相当于操作sql中的insert语句
  * 4.Transaction类:负责治理事务的
  * commit():提交一个事务
  *
  */
  package Yuchen.fristHbn.client;

  import Yuchen.fristHbn.business.Biz.FruitManager;
  import Yuchen.fristHbn.business.entity.Fruit;

  public class Test {

  public static void test1(){
  Fruit fruit=new Fruit("lisi","hello",100);
  // fruit.setName("zhangsan");
  // fruit.setComments("hello");
  // fruit.setPrice(100);

  FruitManager fm=new FruitManager();
  fm.insert(fruit);
  }
  public static void main(String[] args) {
  // TODO 自动生成方法存根
  Test t=new Test();
  t.test1();
  }

  }

  hibernate API(一):
  Configuration: 读取配置文件信息用来初始化的
  SessionFactory: 重量级对象,特点:消耗资源大,线程是安全,所以可以被共享
  上面两个对象只实例化一个就行了,都是用于初始化的
  Session: 线程是不安全的,所以要避免多个线程共享它,是轻量级的对象,使用后关闭

  Session对象的状态:
  顺态: 还没有被持久化,也就是说数据库中没有该对象的记录,并且Session中的缓冲区里没有这个对象的引用
  持久态: 在数据库中有该对象的记录,并且在session中的缓冲区里有这个对象的引用,和顺态正好相反
  游离态: 在数据库中有记录,但是不在session的缓冲区里

  对象状态的转换:
  做一个工具类,将hibernate中重复的代码包装起来:
  package Yuchen.fristHbn.util;
  //生产session对象的工具类
  import org.hibernate.Session;
  import org.hibernate.SessionFactory;
  import org.hibernate.cfg.Configuration;

  public class HbnUtil {
  
   private static SessionFactory sf;
  static{
  sf=new Configuration().configure().buildSessionFactory();
  }

  public static Session getSession(){
  return sf.openSession();
  }
  }

  完善FruitManager类:
  package Yuchen.fristHbn.business.Biz;
  //业务逻辑类:负责增删改查通过使用hibernate API进行
  import org.hibernate.Session;
  import org.hibernate.SessionFactory;
  import org.hibernate.Transaction;
  import org.hibernate.cfg.Configuration;

  import Yuchen.fristHbn.business.entity.Fruit;
  import Yuchen.fristHbn.util.HbnUtil;

  public class FruitManager {
  public Integer insert(Fruit fruit){
  Session session=HbnUtil.getSession();//通过工具更方便了
  Integer id=null;
  // Configuration config=new Configuration();
  // config.configure();//读配置文件
  // SessionFactory sf=config.buildSessionFactory();//得到工厂
  // Session session=sf.openSession();//得到session
  Transaction tt=session.beginTransaction();//检查事务开启
  id=(Integer)session.save(fruit);//存储insert
  tt.commit();//提交
  session.close();//关闭资源
  return id;
  }

  public Fruit selectId(Integer id){
  Session session=HbnUtil.getSession();
  Transaction t=session.beginTransaction();
  Fruit fruit=(Fruit)session.get(Fruit.class, id);
  t.commit();
  session.close();
  return fruit;
  }

  public void remove(Fruit fruit){
  Session session=HbnUtil.getSession();
  Transaction t=session.beginTransaction();
  session.delete(fruit);
  t.commit();
  session.close();
  }
  }

  测试对象状态的转换:
  /**
  * 知识点:
  * hibernate基础:练习语法部分API和简单的映射关系
  * 程序目标:
  * 使用hibernate方法将对象进行持久化
  * 实现数据库的增删改查
  * API:
  * 1.Configuration:这个类负责读取XML文档(映射配置文件)
  * configure():读xml
  * buildSessionFactory():创建一个生产session对象的工厂,其实是再次检查
  * 因为hibernate和jdbc不一样,jdbc是假如不手动设置开启事务,那它
  * 就是马上执行sql的,hibernate的不会马上执行,是事务提交后执行
  * 默认情况下就是打开事务的状态,这里只是再检查以下
  * 2.SessionFactory:负责生产session对象
  * openSession():创建一个session
  * 3.Session类:这个是主要的类,负责增删改查,开启事务等
  * beginTransaction():产生一个事务对象(Transaction)
  * save():增加相当于操作sql中的insert语句
  * 4.Transaction类:负责治理事务的
  * commit():提交一个事务
  * test1():测试插入的功能
  * test2():测试数据同步更新的功能
  * test3():测试saveOrUpdate()
  * test4():测试clear()和flush()
  */
  package Yuchen.fristHbn.client;

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

  import Yuchen.fristHbn.business.Biz.FruitManager;
  import Yuchen.fristHbn.business.entity.Fruit;
  import Yuchen.fristHbn.util.HbnUtil;

  public class Test {

  public void test1(){
  Fruit fruit=new Fruit("lisi","hello",100);
  // fruit.setName("zhangsan");
  // fruit.setComments("hello");
  // fruit.setPrice(100);

  FruitManager fm=new FruitManager();
  fm.insert(fruit);
  }

  public void test2(){
  //测试同步更新的功能
  Fruit fruit=new Fruit("meigui","hongse",70);//顺态
  FruitManager fm=new FruitManager();
  Fruit fruit2=new Fruit();

  Integer id=fm.insert(fruit);
  
   fruit2=fm.selectId(id);
  System.out.println(fruit2.getFid());
  System.out.println(fruit2.getName());

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  fruit.setName("ziluolan");//这里修改了对象
  fruit2=fm.selectId(id);
  System.out.println(fruit2.getFid());//但是结果没有更新
  System.out.println(fruit2.getName());
  //因为fruit在Integer id=fm.insert(fruit);后变成游离态了
  //也就是说只有持久态才能实现同步更新
  System.out.println(fruit.getFid());
  System.out.println(fruit.getName());
  }

  public void test3(){
  Session session=HbnUtil.getSession();
  Transaction t=session.beginTransaction();
  Fruit fruit=new Fruit("ziluolan","lanse",100);//顺态
  Fruit fruit2=new Fruit();
  FruitManager fm=new FruitManager();
  session.save(fruit);//fruit在运行完此句后变为游离态
  fruit2=(Fruit) session.get(Fruit.class, fruit.getFid());
  //从数据库读并打印出来
  System.out.println(fruit2.getFid()+":"+fruit2.getName());

  session.saveOrUpdate(fruit);//假如该对象为游历态就更新数据库update
  //否则就是顺态,增加insert
  fruit2=(Fruit) session.get(Fruit.class, fruit.getFid());
  //saveOrUpdate后再从数据库读并打印出来
  System.out.println(fruit2.getFid()+":"+fruit2.getName());
  //两个打印结果一样,saveOrUpdate方法判定假如id为null,就
  //顺态,否则就是游离态
  t.commit();
  session.close();
  }

  public void test4(){
  Session session=HbnUtil.getSession();
  Transaction t=session.beginTransaction();
  Fruit fruit=new Fruit("guihua","fense",300);//顺态
  Fruit fruit2=new Fruit();
  session.saveOrUpdate(fruit);//执行insert因为对象为顺态
  // session.flush();
  session.clear();//fruit变成游离态了,并且不会执行insert语句
  //因为hibernate不是马上执行sql,而是等t.commit()提交事务
  //后才执行,clear后,对象为游离态

  session.saveOrUpdate(fruit);//这里验证上面的话,执行update
  //做个select查看一下,可以证实,因为clear后,没有马上执行
  //sql语句,所以表里没有数据,这里update也没有用,所以表中
  //一个对象也没插入,但是假如加入flush()刷新就是马上执行sql了

  t.commit();
  session.close();
  }
  public static void main(String[] args) {
  // TODO 自动生成方法存根
  Test t=new Test();
  // t.test1();
  // t.test2();
  // t.test3();
  t.test4();
  }

  }

  hibernate API(二):
  flush(): 从上面的例子可以看出,flush是刷新session的缓冲区,并执行里面的命令
  flush()的事务治理模式: flushMode()里面有三个常量,可以用数字来表示
  Load(): 另一种读取数据的方法,和get的区别是: 1.异常处理: load有异常处理,get没有,它返回null,2.get从数据库读数据,load可能去读缓冲区

  事务的隔离级别:
  在hibernate的数据库配置文件中设置
  数字1为可以脏读,数字2为不能,这个是最常用的

  锁机制:
  避免并发冲突,在数据库中写数据是自动加锁的,读一般不加,有悲观锁和乐观锁
  乐观锁是可以是hibernate程序自己加
  实现乐观锁: 引例(hbn2包)
  步骤:
  1. 在表中加个version字段
  2. 在持久类里加个version属性
  3. 配置文件version name=”versopm” 每存一次值加1

  引例:hbn2包

  复杂的映射:
  1. 基数关系映射
  2. 继续关系映射
  3. 组件关系映射
  4. 集合映射

  基数关系的映射—one to one:
  基数关系的映射需要考虑的问题:
  1. 数量问题
  2. 方向问题
  在one to one的关系中,我们有两种方法可以体现类与类之间的关系
  1. 共享主键
  2. 外键唯一
  引例: Joto包-此包引用了fristHbn包

  建立与Fruit类有一对一关系的类:
  我们认为一个花有一个产地,一个产地生产一种花,所以要建立产地类
  package Yuchen.Joto.business.entity;
  //花的地址类
  //问题:为什么不能在构造函数中写Fruit?因为生成对象后要持久化
  //这个对象,但是数据库的表中不能插入另一个类的值,写上null又不
  //大合适,所以就去掉它
  public class Address {
  private Integer aid;
  
   private String nation;
  private String postcode;
  private Fruit fruit;
  public Address() {

  }
  public Address(String nation, String postcode) {
  super();
  this.nation = nation;
  this.postcode = postcode;
  }
  public Integer getAid() {
  return aid;
  }
  public void setAid(Integer aid) {
  this.aid = aid;
  }
  public Fruit getFruit() {
  return fruit;
  }
  public void setFruit(Fruit fruit) {
  this.fruit = fruit;
  // fruit.setAddress(this);
  }
  public String getNation() {
  return nation;
  }
  public void setNation(String nation) {
  this.nation = nation;
  }
  public String getPostcode() {
  return postcode;
  }
  public void setPostcode(String postcode) {
  this.postcode = postcode;
  }

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  }

  修改Fruit类:
  package Yuchen.Joto.business.entity;
  //持久化类(花类),注重因为采用的是hilo的方式获得id,所以需要有setid的方法
  public class Fruit {

  private Integer fid;//hibernate中的id不能识别int
  private String name;
  private String comments;
  private int price;
  private Address address;//一朵花对应一个地址

  public Fruit() {
  super();
  }

  public Fruit(String name, String comments, int price) {
  super();
  this.name = name;
  this.comments = comments;
  this.price = price;
  }

  public Address getAddress() {
  return address;
  }

  public void setAddress(Address address) {
  this.address = address;
  address.setFruit(this);//因为当你给一个花设置产地的时候
  //该产地也有了花
  }

  public String getComments() {
  return comments;
  }
  public void setComments(String comments) {
  this.comments = comments;
  }

  public Integer getFid() {
  return fid;
  }
  public String getName() {
  return name;
  }
  public void setName(String name) {
  this.name = name;
  }
  public int getPrice() {
  return price;
  }
  public void setPrice(int price)


来源:http://www.tulaoshi.com/n/20160219/1621091.html

延伸阅读
欧莱雅极细造型眉笔 欧莱雅应该是很人都知道的一个品牌,这个品牌目前也是有旗舰店了,所以买的时候也已经很方便了。我个人也是比较喜欢用极细眉笔的,因为我觉得画眉的时候会更加方便。另外这款眉笔非常顺滑,可以帮助我们一笔成型,我们画眉的时候最担心就是卡眉的问题,会让我们的眉毛看起来不自然。 L.A girl极细眉笔 这个品牌也...
初学者的化妆步骤 初学者的化妆步骤 初学者正确化妆步骤 化妆步骤1:面部清洁 生活妆对面部皮肤的清洁要求较高,以油性皮肤为例,如果皮肤上的油脂没清洗干净,那么粉底打不上去,即使上去了也很容易脱妆,导致妆容变得花花的。 初学者的化妆步骤 初学者正确化妆步骤 化妆步骤2:修饰眉形 ...
标签: Web开发
    差不多每天都有人问“什么是 XML”,“XML 能做什么”,“XML 能不能替我做这个”,“XML 会取代什么” 等等诸如此类的问题。由于最近一段时间稍微对 xml 使用了一下,我来谈谈自己的感觉。这些经验都很浅显,任何一个用过 xml 的人都有,并且见仁见智,只不过我算刚刚走过这段路,对自己一开始的困惑,误解还记得清,所以...
标签: 化妆
化妆,不管是爱美的女生还是喜欢随意的女生,都需学会的技巧。每个女人都想学会化妆,化妆其实并不难,关键是要学会使用 化妆技巧 。只要学会了这些技巧,化妆就变得很容易,让你在大众的面前呈现一幅好妆容。那今天小编为你揭秘几大 化妆小技巧 ,让你日后可以轻松“妆”扮自己。 不可低估褐色系眼影的神奇力量 在整个眼皮都...
本文是创建HTML文件的初级读物。HTML 是 WWW(World Wide Web )中使用的超文本标记语言。本指南的目的是介绍如何使用HTML和创建 web 文件。本文中的链接指向一些附加的信息。你还可以到你本地的书店查看一下,那里可能会有很多有价值的关于 Web 和 HTML 的资料。 前言 术语 WWW World Wide Web Web World Wide Web SGML Standard Generali...

经验教程

667

收藏

52
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部