(详细)Hibernate框架的搭建,Hibernate的CRUD操作(一)

一、框架概述:

框架的优点:开发速度快,规范

后台框架:HibernateMyBATISiBATIS),EJB

前台框架(MVC):Struts(1/2)SpringMVCJSF

Spring框架:SpringSeam

JS框架:JQueryExtJS

二、Hibernate框架与ORMapping概念

ORMapping:对象关系映射,通过在类与表之间建立关系,使程序操作类能自动影响到表中的数据。

ORMapping的发展过程:

 

优点

缺点

JDBC

好学,执行速度快

重复代码比较多,开发速度慢

EJB1,2

提出了ORMapping

除了有概念,什么都不行。

JDO

简单

连接控制有问题

Apache OJB

太多

Hibernate

很多

执行速度慢

MyBATIS

Hibernate执行速度快

JDBC代码简单

Hibernate代码多

JDBC执行速度慢

EJB3

使用了Hibernate的源代码

架构还是EJB的原始架构

Hibernate建立ORMapping关系的方式是使用 XMLAnnotation(在Hibernate3.2以上版本才可以使用)

JDBC完成数据库操作的支持类: Hibernate

Connection    —>   Session

PreparedStatement     —>  Query

ResultSet    —>   List

DataBaseConnection     —>   HibernateSessionFactory

三、Hibernate完成单表数据库CRUD操作

1,在数据库中建立一张数据表,这里建立一个张新闻表(news

CREATE TABLE news (
       id           number(8)         primary key ,
       title        varchar2(50)      not null,
       content      varchar2(500)     not null,
       pub_date     date              not null                                            
);

在MyEclipse中需要建立项目,并加入Hibernate框架支持。但在这些之前,建议先在MyEclipse里建立与数据库的连接。

 建立数据库连接:windows-->show view-->other-->MyEclipse Database-->DB Browser;

然后右击DB Brower 下的空白部分选择New,在Driver template 中选择所需的Oracle(Thin driver),Driver name  随便取,

Connection UrL:   jdbc:oracle:thin:@localhost:1521:ORCL, username  和password是数据库连接的姓名和密码;

Driver JARs:添加的是Oracle的驱动Jar包;

点Test Driver,测试是否连接成功。测试成功后如果可以在连接中找到之前建立好的表,表示配置成功,可以开始建立项目。

2、新建项目:FirstHibernateDemo,加入Hibernate支持

右击MyEclipse-->Add Hibernate Capabilities

选择Hibernate版本Hibernate3.3(足够可以用),虽然hibernate最新版已经到4.0+,但是开发中没人用,因为太新;

如果要手工加入框架支持,需要加入以下两部分内容:

1)  支持jar包加入到WEB-INF/lib目录下

(详细)Hibernate框架的搭建,Hibernate的CRUD操作(一)_第1张图片

2)  Hibernate.cfg.xml(核心配置文件,不推荐改名字)加入到src目录下。

(详细)Hibernate框架的搭建,Hibernate的CRUD操作(一)_第2张图片

建立数据库连接的类:

(详细)Hibernate框架的搭建,Hibernate的CRUD操作(一)_第3张图片

好了,点击Finish,Hibernate支持加好了,项目环境搭建好了;

Hibernate核心配置文件的功能:

1)  配置数据库连接参数(已经配置好了)

2)  加入Hibernate的属性配置,例如:通常加入两个属性property:show_sql,value:true; 格式化sql语句 property:format_sql,value:true;

3、生成的HibernateSessionFactory中,实现了连接池功能,要求掌握连接池的实现原理。

[java] view plain copy
  1. public class HibernateSessionFactory {  
  2.     // 配置文件的所在位置和名称  
  3.     private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";  
  4.     // 用来实现连接池的,该类类似Map集合。  
  5.     private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();  
  6.     // Hibernate用来读取配置文件的类  
  7.     private static Configuration configuration = new Configuration();  
  8.     // 用来建立连接的,该类就是连接池,使用单例设计模式  
  9.     private static org.hibernate.SessionFactory sessionFactory;  
  10.     // 备用的配置文件位置  
  11.     private static String configFile = CONFIG_FILE_LOCATION;  
  12.   
  13.     // 静态块,类加载时最先执行  
  14.     static {  
  15.         try {  
  16.             // 加载配置文件到内存中  
  17.             configuration.configure(configFile);  
  18.             // 建立连接池以及里面的连接  
  19.             sessionFactory = configuration.buildSessionFactory();  
  20.         } catch (Exception e) {  
  21.             System.err.println("%%%% Error Creating SessionFactory %%%%");  
  22.             e.printStackTrace();  
  23.         }  
  24.     }  
  25.   
  26.     private HibernateSessionFactory() {  
  27.     }  
  28.     /** 
  29.      * 取得数据库连接对象  
  30.      * @return Session 
  31.      * @throws HibernateException 
  32.      */  
  33.     public static Session getSession() throws HibernateException {  
  34.         // 先从ThreadLocal中取得连接。  
  35.         Session session = (Session) threadLocal.get();  
  36.   
  37.         // 如果手头没有连接,则取得一个新的连接  
  38.         if (session == null || !session.isOpen()) {  
  39.             session = sessionFactory.openSession();  
  40.             // 把取得出的连接记录到ThreadLocal中,以便下次使用。  
  41.             threadLocal.set(session);  
  42.         }  
  43.         return session;  
  44.     }  
  45.     /** 
  46.      * 连接关闭的方法  
  47.      * @throws HibernateException 
  48.      */  
  49.     public static void closeSession() throws HibernateException {  
  50.         Session session = (Session) threadLocal.get();  
  51.         // 将ThreadLocal清空,表示当前线程已经没有连接。  
  52.         threadLocal.set(null);  
  53.         // 连接放回到连接池  
  54.         if (session != null) {  
  55.             session.close();  
  56.         }  
  57.     }  
  58.     public static Configuration getConfiguration() {  
  59.         return configuration;  
  60.     }  
  61. }  
4、下面需要根据数据库表,完成Vo对象。.

注意,在一些框架中,VO课程被称为其他的称呼。

TO(EJB1,2),POJO(Hibernate),EntityBean(EJB3)

MyEclipse中提供了根据表自动生成pojo和映射文件的功能。

在DB Browser下,找到对应用户名下table下的news表,选中右击,Hibernate Reverse Engineering -->在java src folders选择对应项目的src;

(详细)Hibernate框架的搭建,Hibernate的CRUD操作(一)_第4张图片

(详细)Hibernate框架的搭建,Hibernate的CRUD操作(一)_第5张图片

这里需要选择主键生成方式,主要有以下几种:

1)  assigned:通过程序添加。

2)  sequence:通过Oracle的序列生成主键值

3)  native:通过数据库表中自带的关键字生成主键值,例如:MySQL,SQLServer,DB2,HSQL等

4)  increment:自增长,通过程序实现自增长功能。

5)  UUID:生成一个32的位随机值作为主键。

点击finish即可以生成Hibernate的映射;生成的pojo对象

映射文件要求能看懂,会改。News.hbm.xml:

[java] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  4. <hibernate-mapping>  
  5.     <!--   
  6.         News类和SUNXUN用户下的NEWS表映射.  
  7.     -->  
  8.     <class name="org.liky.pojo.News" table="NEWS" schema="SUNXUN">  
  9.         <!--   
  10.             类中的Integer类型的id对应表中的主键  
  11.         -->  
  12.         <id name="id" type="java.lang.Integer">  
  13.             <!--   
  14.                 表中主键字段为ID,scale是指小数点后0位,即是整形  
  15.             -->  
  16.             <column name="ID" precision="8" scale="0" />  
  17.             <!--   
  18.                 主键生成方式  
  19.             -->  
  20.             <generator class="assigned" />  
  21.         </id>  
  22.         <!--   
  23.             类中的String类型的title属性与表中的TITLE字段对应,长度是50,不允许为空  
  24.         -->  
  25.         <property name="title" type="java.lang.String">  
  26.             <column name="TITLE" length="50" not-null="true" />  
  27.         </property>  
  28.         <property name="content" type="java.lang.String">  
  29.             <column name="CONTENT" length="500" not-null="true" />  
  30.         </property>  
  31.         <property name="pubDate" type="java.util.Date">  
  32.             <column name="PUB_DATE" length="7" not-null="true" />  
  33.         </property>  
  34.     </class>  
  35. </hibernate-mapping>  
5、创建一个公共的DAO接口方法,为了方便使用。
[java] view plain copy
  1. /** 
  2.  * 公共接口 
  3.  *  
  4.  * @param <K> 
  5.  *            主键类型 
  6.  * @param <V> 
  7.  *            Vo对象的类型 
  8.  */  
  9. public interface IDAO<K, V> {  
  10.   
  11.     public void doCreate(V vo) throws Exception;  
  12.   
  13.     public void doUpdate(V vo) throws Exception;  
  14.   
  15.     public void doRemove(K id) throws Exception;  
  16.   
  17.     public List<V> findAll() throws Exception;  
  18.   
  19.     public V findById(K id) throws Exception;  
  20.   
  21.     /** 
  22.      * 分页查询方法 
  23.      */  
  24.     public List<V> findAll(int pageNo, int pageSize, String keyword,  
  25.             String column) throws Exception;  
  26.   
  27.     /** 
  28.      * 查询全部记录数,用来计算总页数 
  29.      */  
  30.     public int getAllCount(String keyword, String column) throws Exception;  
  31.   
  32. }  
6、建立新闻的接口,继承公共接口,完成操作。
[java] view plain copy
  1. public interface INewsDAO extends IDAO<Integer, News> {  
  2. }  
7、建立实现类对象
[java] view plain copy
  1. public class NewsDAOImpl implements INewsDAO {  
[java] view plain copy
  1. public void doCreate(News vo) throws Exception {  
  2.     HibernateSessionFactory.getSession().save(vo);  
  3. }  
[java] view plain copy
  1. public void doRemove(Integer id) throws Exception {  
  2.     // 注意,使用Hibernate删除时,必须先查询对象,再删除.  
  3.     HibernateSessionFactory.getSession().delete(findById(id));  
  4. }  
  5. public void doUpdate(News vo) throws Exception {  
  6.     HibernateSessionFactory.getSession().update(vo);  
  7. }  
  8. public List<News> findAll() throws Exception {  
  9.     // 使用HQL语句完成查询功能  
  10.     // 1.HQL查询的是类,而不是表  
  11.     // 2.可以不写SELECT关键字  
  12.     String hql = "FROM News";  
  13.     Query query = HibernateSessionFactory.getSession().createQuery(hql);  
  14.     return query.list();  
  15. }  
  16. public List<News> findAll(int pageNo, int pageSize, String keyword,  
  17.         String column) throws Exception {  
  18.     String hql = "FROM News AS n WHERE n." + column + " LIKE ?";  
  19.   
  20.     Query query = HibernateSessionFactory.getSession().createQuery(hql);  
  21.     query.setString(0"%" + keyword + "%");  
  22.   
  23.     // 分页处理  
  24.     query.setFirstResult((pageNo - 1) * pageSize);  
  25.     query.setMaxResults(pageSize);  
  26.   
  27.     return query.list();  
  28. }  
  29. public News findById(Integer id) throws Exception {  
  30.     // 根据主键完成查询功能,需要传入类型,以及主键值  
  31.     return (News) HibernateSessionFactory.getSession().get(News.class, id);  
  32. }  
  33. public int getAllCount(String keyword, String column) throws Exception {  
  34.     // 这里由于查询的不再是对象,因此必须写SELECT统计数量  
  35.     String hql = "SELECT COUNT(n) FROM News AS n WHERE n." + column  
  36.             + " LIKE ?";  
  37.     Query query = HibernateSessionFactory.getSession().createQuery(hql);  
  38.   
  39.     query.setString(0"%" + keyword + "%");                <p align="left">   <span style="white-space:pre">     </span><span style="color:#cc0000;">// 手工使用拆箱方法,将Long转换为基本数据类型的<u>int</u>.</span></p><p align="left"><span style="color:#cc0000;">        <span style="white-space: pre; ">   </span><strong>return</strong> ((Long)query.uniqueResult()).intValue();</span></p>  }  
9、建立工厂类
[java] view plain copy
  1. public class DAOFactory {  
  2.     public static INewsDAO getINewsDAOInstance() {  
  3.         return new NewsDAOImpl();  
  4.     }  
  5. }  
10、编写Service层,这里随意定义几个方法
[java] view plain copy
  1. public interface INewsService {  
  2.     public void insert(News news) throws Exception;  
  3.     public void delete(int id) throws Exception;  
  4.     public News findById(int id) throws Exception;  
  5.     // 如果要一次性返回多种类型的数据,可以使用Map集合,这样方便区分.  
  6.     public Map<String, Object> list(int pageNo, int pageSize, String keyword,  
  7.             String column) throws Exception;  
  8. }  
11、建立实现类
[java] view plain copy
  1. public class NewsServiceImpl implements INewsService {  
  2.     public void delete(int id) throws Exception {  
  3.         // 加入事务处理功能  
  4.         Transaction tx = HibernateSessionFactory.getSession()  
  5.                 .beginTransaction();  
  6.         try {  
  7.             DAOFactory.getINewsDAOInstance().doRemove(id);  
  8.             tx.commit();  
  9.         } catch (Exception e) {  
  10.             e.printStackTrace();  
  11.             tx.rollback();  
  12.             throw e;  
  13.         } finally {  
  14.             HibernateSessionFactory.closeSession();  
  15.         }  
  16.     }  
  17.   
  18.     public News findById(int id) throws Exception {  
  19.         News news = null;  
  20.         try {  
  21.             news = DAOFactory.getINewsDAOInstance().findById(id);  
  22.         } catch (Exception e) {  
  23.             e.printStackTrace();  
  24.             throw e;  
  25.         } finally {  
  26.             HibernateSessionFactory.closeSession();  
  27.         }  
  28.         return news;  
  29.     }  
  30.   
  31.     public void insert(News news) throws Exception {  
  32.         // 加入事务处理功能  
  33.         Transaction tx = HibernateSessionFactory.getSession()  
  34.                 .beginTransaction();  
  35.         try {  
  36.             DAOFactory.getINewsDAOInstance().doCreate(news);  
  37.             tx.commit();  
  38.         } catch (Exception e) {  
  39.             e.printStackTrace();  
  40.             tx.rollback();  
  41.             throw e;  
  42.         } finally {  
  43.             HibernateSessionFactory.closeSession();  
  44.         }  
  45.     }  
  46.   
  47.     public Map<String, Object> list(int pageNo, int pageSize, String keyword,  
  48.             String column) throws Exception {  
  49.         Map<String, Object> map = new HashMap<String, Object>();  
  50.         try {  
  51.             map.put("allNews", DAOFactory.getINewsDAOInstance().findAll(pageNo,  
  52.                     pageSize, keyword, column));  
  53.             map.put("allCount", DAOFactory.getINewsDAOInstance().getAllCount(  
  54.                     keyword, column));  
  55.         } catch (Exception e) {  
  56.             e.printStackTrace();  
  57.             throw e;  
  58.         } finally {  
  59.             HibernateSessionFactory.closeSession();  
  60.         }  
  61.         return map;  
  62.     }  
  63. }  
12、工厂类
[java] view plain copy
  1. public class ServiceFactory {  
  2.     public static INewsService getINewsServiceInstance() {  
  3.         return new NewsServiceImpl();  
  4.     }  
  5. }  
13、JUnit测试
针对Service的所有方法,开发中一般要求使用JUnit编写测试用例进行测试。
[java] view plain copy
  1. public class NewsServiceImplTest {  
  2.   
  3.     @Test  
  4.     public void testDelete() throws Exception {  
  5.         ServiceFactory.getINewsServiceInstance().delete(2);  
  6.     }  
  7.   
  8.     @Test  
  9.     public void testFindById() throws Exception {  
  10.         System.out.println(ServiceFactory.getINewsServiceInstance().findById(2)  
  11.                 .getTitle());  
  12.     }  
  13.   
  14.     @Test  
  15.     public void testInsert() throws Exception {  
  16.         News news = new News(3"测试添加数据032""测试内容023"new Date());  
  17.         ServiceFactory.getINewsServiceInstance().insert(news);  
  18.     }  
  19.   
  20.     @Test  
  21.     public void testList() throws Exception {  
  22.         Map<String, Object> map = ServiceFactory.getINewsServiceInstance()  
  23.                 .list(12"添加""title");  
  24.         System.out.println(map.get("allCount"));  
  25.         System.out.println(map.get("allNews"));  
  26.     }  
  27. }  

在执行时,控制台中一直提示警告信息,该警告是因为Hibernate中加入的log4j支持造成的。

如果不想显示这个警告,需要自己将log4j的配置文件加入到项目中。

Hibernate中使用到的类和配置:

1)  Configuration:读取配置文件

2)  SessionFactory:连接池

3)  ThreadLocal:实现连接池的支持类

4)  Session:数据库连接

a)         Save()

b)        Update()

c)         Delete()

d)        Get()

e)         createQuery()

f)         beginTransaction()

5)  Query:查询对象

a)         setXxx:设置参数,从 0 开始

b)        list():查询多条数据

c)         uniqueResult():查询唯一数据,前提是必须只有一条结果,只在查询全部记录数时使用。

6)  Transaction:事务处理对象

a)         Commit

b)        rollback

你可能感兴趣的:((详细)Hibernate框架的搭建,Hibernate的CRUD操作(一))