Hibernate(一)

 映射文件(hbm.xml): 是配置对象与数据库表的对应关系。是站在对象的位置上进
行配置的。* hibernate-mapping元素, package:指定一个包前缀,如果在映射文档中
没有指定全限定的类名,就使用这个作为包名。auto-import:指定是否可以在查
询语言中使用非全限定名(仅限于本映射文件中的类),默认为true。

   Java是面向对象语言,对象模型,其主要概念有:继承、关联、多态等;关系型
数据库中的概念有:表、主键、外键等。当使用Jdbc去操作关系型数据库时,因
为他们对应不起来,所以要做转换(转换的过程就叫做ORM, Object Relation
Mapping, 对象关系映射)。除了手工转换外,还可以使用ORM框架来解决,当前
主流ORM框架有Hibernate和TopLink等,我们学习的是Hibernate(3.2.6).

准备环境:
   1,引入jar包,最基本的包为:
      hibernate3.jar
      antlr-2.7.6.jar
      asm.jar
      asm-attrs.jar
      cglib-2.1.3.jar
      dom4j-1.6.1.jar
      commons-collections-2.1.1.jar
      commons-logging-1.0.4.jar
      jta.jar
     所用的数据库的JDBC驱动
     可以选择加入log4j-1.2.11.jar。
 2,拷贝配置文件hibernate.cfg.xml到classpath的根中,并修改其中的数据
      库连接信息。选择拷贝log4j.properties文件。
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 显示sql语句 -->
<property name="show_sql">true</property>
<!-- 自动更新表结构 -->
<property name="hbm2ddl.auto">update</property>

Hibernate映射文件就是用于说明Java对象与数据库表中的记录的对应关系的。不
能性质的属性(例如主键和普通属性)用不同的标签来映射,如果Java对象中的
某个属性不需要存储到数据库中,那么就不需要在映射文件中配置这个属性。
User.java
package cn.itcast.demo.entities;

import java.util.Date;

public class User {

 private int id;
 private String name;
 private String desc;

 private Date birthday;
 private byte[] avatar;

 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 getDesc() {
  return desc;
 }

 public void setDesc(String desc) {
  this.desc = desc;
 }

 public Date getBirthday() {
  return birthday;
 }

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

 public byte[] getAvatar() {
  return avatar;
 }

 public void setAvatar(byte[] avatar) {
  this.avatar = avatar;
 }

 @Override
 public String toString() {
  return new StringBuffer()//
    .append("[User: id=").append(id) //
    .append(",name=").append(name)//
    .append("]")//
    .toString();
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + id;
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  final User other = (User) obj;
  if (id != other.id)
   return false;
  return true;
 }

}

加入User.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">
<hibernate-mapping package="cn.itcast.demo.entities">
 <class name="User" table="itcast_user" >
  <id name="id" unsaved-value="undefined">
   <generator class="native" />
  </id>
  <property name="name"  type="string"/>
  <property name="birthday" type="date"/>
  <property name="desc" column="desc_" type="text"/>
  
  <property name="avatar" length="512000" type="binary"/>
  <!--
  <property name="avatar" >
   <column name="avatar" sql-type="MEDIUMBLOB"/>
  </property>
  -->
  
 </class>
</hibernate-mapping>
在hibernate中加入这个映射文件。 <mapping resource="cn/itcast/demo/entities/User.hbm.xml"/>

建个用户类:
package cn.itcast.demo.test;

import java.io.File;
import java.io.FileInputStream;
import java.util.Date;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

import cn.itcast.demo.entities.User;

public class First {

 public static void main(String[] args) throws Exception {
  User user = new User();
  // user.setId(3);
  user.setName("zhangsan");
  user.setBirthday(new Date());
  user.setDesc("just for test");

  File file = new File("c:/default.gif");
  FileInputStream fis = new FileInputStream(file);
  byte[] avatar = new byte[(int) file.length()];
  fis.read(avatar);
  fis.close();

  user.setAvatar(avatar);

  Configuration cfg = new Configuration();
  cfg.configure("hibernate.cfg.xml");
  SessionFactory sessionFactory = cfg.buildSessionFactory();

  Session session = sessionFactory.openSession();
  Transaction tx = session.beginTransaction();

  session.save(user);

  tx.commit();
  session.close();
 }
}

UserDao.java
package cn.itcast.demo.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import cn.itcast.demo.entities.User;

public class UserDao {
 private Configuration cfg = new Configuration().configure();
 private SessionFactory sessionFactory = cfg.buildSessionFactory();

 
 public void save(User user) {
  Session session = null;
  Transaction tx = null;
  try {
   session = sessionFactory.openSession();
   tx = session.beginTransaction();

   session.save(user);

   tx.commit();
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw new RuntimeException(e);
  } finally {
   if (session != null) {
    session.close();
   }
  }
 }

 
 public void delete(int id) {
  Session session = null;
  Transaction tx = null;
  try {
   session = sessionFactory.openSession();
   tx = session.beginTransaction();

   User user = (User) session.get(User.class, id);
   session.delete(user);

   tx.commit();
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw new RuntimeException(e);
  } finally {
   if (session != null) {
    session.close();
   }
  }
 }

 
 public void update(User user) {
  Session session = null;
  Transaction tx = null;
  try {
   session = sessionFactory.openSession();
   tx = session.beginTransaction();

   session.update(user);

   tx.commit();
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw new RuntimeException(e);
  } finally {
   if (session != null) {
    session.close();
   }
  }
 }

 
 public User get(int id) {
  Session session = null;
  Transaction tx = null;
  try {
   session = sessionFactory.openSession();
   tx = session.beginTransaction();

   User user = (User) session.get(User.class, id);

   tx.commit();
   return user;
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw new RuntimeException(e);
  } finally {
   if (session != null) {
    session.close();
   }
  }
 }

 
 @SuppressWarnings("unchecked")
 public List<User> find(int first, int max) {
  Session session = null;
  Transaction tx = null;
  try {
   session = sessionFactory.openSession();
   tx = session.beginTransaction();

   String hql = "from User";
   List users = session.createQuery(hql)//
     .setFirstResult(first)//
     .setMaxResults(max)//
     .list();

   tx.commit();
   return users;
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw new RuntimeException(e);
  } finally {
   if (session != null) {
    session.close();
   }
  }
 }
}
这里我们要对上面的代码要进行测试,这样就用到jutil这样的测试工具,需要导入junit.jar才可以。之后建立个jutil测试类。
要注意的就是在所要测试的方法前,要加@Test。
UserDaoTest.java:
package cn.itcast.demo.dao;

import java.util.List;

import org.junit.Test;

import cn.itcast.demo.entities.User;

public class UserDaoTest {
 private UserDao userDao = new UserDao();

 @Test
 public void testSave() {
  User user = new User();
  user.setName("lisi");
  userDao.save(user);
 }

 @Test
 public void testDelete() {
  User user = new User();
  user.setName("testDelete");
  userDao.save(user);

  userDao.delete(user.getId());
 }

 @Test
 public void testUpdate() {
  User user = new User();
  user.setName("xx");
  userDao.save(user);

  user.setName("testUpdate");
  userDao.update(user);
 }

 @Test
 public void testGet() {
  User user = new User();
  user.setName("testGet");
  userDao.save(user);

  User u = userDao.get(user.getId());
  System.out.println(u);
 }

 @Test
 public void testFind() {
  List<User> users = userDao.find(3, 3);
  for (User user : users) {
   System.out.println(user);
  }
 }

}
注意点:如果下面的测试成功的话呢,出现的就是绿色的进度条,错误的就是红色的进度条,并报有相对应的错。

Session的几个主要方法
 1.save,persist,保存数据
 2.delete,删除对象
 3.update,更新对象,如果数据库中没有记录,会出现异常。
 4.get,根据ID查,会立刻访问数据库。
 5.Load,根据ID查,(返回的是代理,不会立即访问数据库)。
 6.saveOrUpdate,merge,由Hibernte来确定是save或update

3,Hibernate对象实例的三种状态与Session的方法:
  三种状态:自由(瞬时)、持久、游离;
    自由(瞬时)状态:从未与任何Session关联过,一般指新创建的对象实例。
    持久状态:目前正与Session有关联,拥有持久化标识(相当于主键值),
            并且相关联的session没有关闭,事务没有提交。持久对象状态发
            生改变,在事务提交时会更新到数据库。
    游离状态:曾经与Session关联过,不过那个Session已经关闭了。

  三种状态之间的转换(通过Session的方法):
  Session的方法:save(persist), delete, get, load.
    update:update是把一个已经更改过的脱管状态的对象变成持久状态。
    saveOrUpdate(merge):【什么下情况添加什么情况下更新】;
       使用save和saveOrUpdate方法时,如果被操作对象与另一个跟本session
       关联的po对象拥有相同的持久化标识(identifier),就会抛出一个异常:
       org.hibernate.NonUniqueObjectException。

       通常下面的场景会使用update()或saveOrUpdate():程序在第一个
       session 中加载对象,接着把session关闭,该对象被传递到表现层,对
       象发生了一些改动,该对象被返回到业务逻辑层最终到持久层,程序创建
       第二session调用第二个session的update()方法持久这些改动。

    contains:Session是否包含某个对象(是否是持久状态);
    clear:清空一级缓存;
    flush:强制刷出(更新到数据库);
 
    load与get的区别:
       get方法:如果找不到符合条件的纪录,返回null。
       load方法:返回的是一个代理对象。在第一次访问这些懒加载对象(代理对
         象)的属性(getId方法除外)时,hibernate 会初始化这些代理。这
         时如果数据库中没有与之对应的记录,就会抛异常:
         org.hibernate.ObjectNotFoundException: No row with the given
         identifier exists: ...。
       如果PO是final的,则load被调用时会马上发出一条select语句(即不能使
       用懒加载功能)。

package cn.itcast.demo.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import cn.itcast.demo.entities.User;

public class SessionTest {

 @Test
 public void test() {
  Configuration cfg = new Configuration().configure();
  SessionFactory sessionFactory = cfg.buildSessionFactory();

  Session session = sessionFactory.openSession();
  Transaction tx = session.beginTransaction();
  // ----------------------------
  // 1, test get() and load()
  // User user = (User) session.get(User.class, 10);
  // User user = (User) session.load(User.class, 1);
  // System.out.println(user.getId());
  // System.out.println(user.getName());
  // System.out.println(user);

  // 2, test save() and flush() and update() and delete
  // User user = new User();
  // user.setId(12);
  // user.setName("xxx");
  // session.save(user);

  // User user = (User) session.get(User.class, 1);
  // user.setName("yyy2");
  // session.update(user);
  // session.flush();

  // session.delete(user);

  // 3, test saveOrUpdate()
  // User user = new User();
  // user.setName("aa");
  // User user = (User) session.get(User.class, 2);
  // User user = new User();
  // user.setId(8);
  // user.setName("xxxyyy");
  // session.saveOrUpdate(user);

  User user = new User();
  user.setId(2);
  user.setName("aaa");
  session.update(user);
  // session.update(user);

  // User user2 = new User();
  // user2.setId(2);
  // user2.setName("bbb");
  // session.update(user2);

  // 4, test evict() and clear()
  // User user = (User) session.get(User.class, 2);
  // boolean b = session.contains(user);
  // System.out.println(b);
  //
  // // session.evict(user);
  // session.clear();
  //
  // b = session.contains(user);
  // System.out.println(b);

  // ----------------------------
  System.out.println("--- commiting...");
  tx.commit();
  session.close();
 }
}

在学习的过程中,初学者经常会出现的一些典型的错误;
第一个:就是Hibernate的HQL查询的是对象,而sql查询的是表。
String hql = "from User";记住是User不是user;
第二个就是关于映射的问题。一定要记住,每生成一张hbm。xml表就要在hibernate.cfg.xml中映射。
还有的许多注意点,汤老师都做了详细的总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值