先来了解两个概念
一、什么是持久层?
持久是相对于瞬时来说的,简单说就是把数据保存到数据库中,然后持久保存到存储设备上,不像放在内存中断电就消失。企业应用中数据很重要(各种订单数据、客户数据、库存数据之类的),比应用程序本身更重要,所以需要把数据持久化。
二、什么是对象关系映射(ORM)
ORM是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。
Hibernate
一、什么是Hibernate?
Hibernate是一个基于Java的开放源代码的持久化中间件,是持久层的一种实现方式,它对JDBC做了轻量级封装,不仅提供ORM映射服务,还提供数据查询和数据缓存功能,Java人员可以方便地通过Hibernate API来操纵数据库。
二、Hibernate优点
- l 提高生产力。不用写大量的sql语句。
- l 更加面向对象了,重点考虑对象,不用考虑sql。
- l 移植性,用hibernate写的代码不需要改变,如改变数据库,只要修改dialet(适配器就可以)。
- l 透明持久化对象。(News对象不继承任何框架。重用性更好)
三、Hibernate体系结构和开发步骤
四、Hibernate第一个程序
官网地址: www.hibernate.org
(不同的Hibernate版本使用方法会有稍许差异)
3.6.0版本百度网盘分享:http://pan.baidu.com/s/1i4I1mcd
1 新建Java工程,并添加如下jar包:
- {hibernate_home}/hibernate3.jar
- {hibernate_home}/lib/required/*.jar
- {hibernate_home}/lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar (如果不加此包,会有异常:java.lang.ClassNotFoundException: javax.persistence.EntityListeners)
- 数据库对应的JDBC驱动(例如oarcle数据库对应ojdbc14.jar)
- 还可以加入日志相关的jar包(不加也可以):因已经添加了{hibernate_home}/lib/required/slf4j-api-1.6.1.jar只需要下载slf4j-1.6.1.zip,添加其中的slf4j-nop-1.6.1.jar
2 创建持久化对象
package com.silvan.pojo; public class News { private Integer id; private String newsTitle; private String newsContent; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNewsTitle() { return newsTitle; } public void setNewsTitle(String newsTitle) { this.newsTitle = newsTitle; } public String getNewsContent() { return newsContent; } public void setNewsContent(String newsContent) { this.newsContent = newsContent; } }
3 创建对象关系映射文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping> <class name="com.silvan.pojo.News" table="t_news"> <id name="id" column="id"> <generator class="sequence"><!-- id的生成策略:从序列中产生 --> <param name="sequence">news_sequence</param> </generator> </id> <property name="newsTitle" column="news_title"></property> <property name="newsContent" column="news_content"></property> </class> </hibernate-mapping>
4 创建Hibernate配置文件
<?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" > <hibernate-configuration> <!-- 一个sessionfactory配置一个数据库 --> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:zhouyq</property> <property name="hibernate.connection.username">zhou</property> <property name="hibernate.connection.password">123456</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 加载映射文件 --> <mapping resource="com/silvan/pojo/News.hbm.xml"/> </session-factory> </hibernate-configuration>
5 使用Hibernate API操作数据库
package com.silvan.test; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import com.silvan.pojo.News; public class NewsDao { public void saveNews(News news) { // 1读取src下的hibernate.cfg.xml文件,从而得到Configuration对象,Configuration包含了hibernate的配置信息 Configuration cfg = new Configuration().configure(); // 2 得到sessionFactory对象:sessionFactory是产生session对象的工厂 SessionFactory sessionFactory = cfg.buildSessionFactory(); // 3 从sessionFactory中得到session对象,session是持久化管理器 Session session = sessionFactory.openSession(); // 4 启动食物(在hibernate框架中事务时单独处理的,transcation:默认手动提交) session.beginTransaction(); // 5 完成保存新闻 session.save(news); // 6 提交事务 session.getTransaction().commit(); // 7 释放资源 if (session != null) { if (session.isOpen()) { session.close(); } } } public static void main(String[] args) { NewsDao newsDao = new NewsDao(); News news = new News(); // 保存新闻信息 news.setNewsContent("NewsContent"); news.setNewsTitle("title"); newsDao.saveNews(news); } }
上述使用Hibernate API操作数据库的方法可以提取一些读取配置文件、创建sessionFactory对象等公共行为,放置于一个公共文件中供调用,简化开发,详细方法见下面:
6 操作数据库程序的工具化(与第5步任选其一)
package com.silvan.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtils { //SessionFactory多线程之间可以共享一个实例 private static SessionFactory sessionFactory; static{ Configuration cfg = new Configuration().configure(); sessionFactory = cfg.buildSessionFactory(); } //得到session对象(持久化管理器) public static Session getSession(){ Session session = null; if(sessionFactory != null){ session = sessionFactory.openSession(); } return session; } //释放资源 public static void close(Session session){ if(session != null){ if(session.isOpen()){ session.close(); } } } }
package com.silvan.test; import org.hibernate.Session; import com.silvan.pojo.News; import com.silvan.util.HibernateUtils; public class NewsDao1 { public void saveNews(News news){ Session session =null; try { //从SessionFactory中得到Session对象,Session是持久化管理器。 session = HibernateUtils.getSession(); // 启动事务。(在Hibernate框架中事务是单独处理的,Transcation:默认手动提交事务) session.beginTransaction(); //完成保存新闻。 session.save(news); //提交事务 session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); // 回滚事务 session.getTransaction().rollback(); }finally{ //释放资源 HibernateUtils.close(session); } } public static void main(String[] args) { News news = new News(); news.setNewsTitle("1111"); news.setNewsContent("2222"); NewsDao1 newsDao = new NewsDao1(); newsDao.saveNews(news); } }
7 其他用户信息维护方法
- 添加新用户信息 session.save(news);
- 修改某用户信息 session.update(news);
手动构造的对象也可以修改,但是需要指定所有属性,不建议使用,因为手动构造时,没有指定属性的字段会被置空。
- 删除某用户信息 session.delete(news);
手动构造一个对象指定其主键是可以删除该对象的。但是不建议这么用
通过从数据库中加载该对象,然后删除,根据查询结果是不是为空再去删除,进行判断进而避免异常,提高程序健壮性
- 按照用户编号检索某用户信息
News news1 = (News) session.get(News.class, 1);
System.out.println(news1.getNewsTitle());
get和load方法的区别(功能:根据主键值进行查询)
get: 1.发出sql文的时机:调用session.get()时;
2.判断查询结果是否存在?用返回的对象是否为null进行判断
Load: 1.发出sql文的时机:用户第一次访问对象的属性时,才发出sql文。
2.判断查询结果是否存在?如果主键值不存在,则使用load方法()后,报异常No row with the given identifier
public void testGet(){ Session session = null; Transaction tx =null; News news =null; try{ session = HibernateUtils.getSession(); tx = session.beginTransaction(); news = (News) session.get(News.class, 5); System.out.println(news.getNewsTitle()); }catch(Exception e){ e.printStackTrace(); tx.rollback(); }finally{ HibernateUtils.close(session); } } public void testLoad(){ Session session = null; Transaction tx =null; News news =null; try{ session = HibernateUtils.getSession(); tx = session.beginTransaction(); news = (News) session.load(News.class, 5); System.out.println(news.getNewsTitle()); }catch(Exception e){ e.printStackTrace(); tx.rollback(); }finally{ HibernateUtils.close(session); } }
- 检索所有的用户信息
List<News> newl = (List<News>)session.createQuery("from News");
for(News object : newl){System.out.println(object.getNewsTitle());}