hibernate的基础入门

来源:互联网 发布:淘宝申请退款时间5天 编辑:程序博客网 时间:2024/05/21 17:09

第1天:hibernate的基础入门

      第1章hibernate和ORM的概念部分

1.1Hibrenate概述
Hibernate框架是当今主流的Java持久层框架之一,由于它具有简单易学、灵活性强、扩展性强等特点,能够大大地简化程序的代码量,提高工作效率,因此受到广大开发人员的喜爱。
Hibernate是一个开放源代码的ORM框架,它对JDBC进行了轻量级的对象封装,使得Java开发人员可以使用面向对象的编程思想来操作数据库。

1.2ORM概述
Object Relation Mapping 对象关系映射。
对象-关系映射是随着面向对象的软件开发方法发展而产生的。用来把对象模型表示的对象映射到基于S Q L 的关系模型数据库结构中去。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的 SQ L 语句打交道,只需简单的操作实体对象的属性和方法[2] 。O R M 技术是在对象和关系之间提供了一条桥梁,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化[1] 。
简单的说就是把我们程序中的实体类和数据库表建立起来对应关系。

1.2.1.1为什么要学习Hibernate
使用传统的JDBC开发应用系统时,如果是小型应用系统,并不觉得有什么麻烦,但是对于大型应用系统的开发,使用JDBC就会显得力不从心。例如对几十、几百张包含几十个字段的表进行插入操作时,编写的SQL语句不但很长,而且繁琐,容易出错;在读取数据时,需要写多条getXxx语句从结果集中取出各个字段的信息,不但枯燥重复,并且工作量非常大。为了提高数据访问层的编程效率,Gavin King开发出了一个当今最流行的的ORM框架,它就是Hibernate框架。
所谓的ORM就是利用描述对象和数据库表之间映射的元数据,自动把Java应用程序中的对象,持久化到关系型数据库的表中。通过操作Java对象,就可以完成对数据库表的操作。可以把ORM理解为关系型数据和对象的一个纽带,开发人员只需要关注纽带一端映射的对象即可。ORM原理如图1-1所示。

ORM原理
与其它操作数据库的技术相比,Hibernate具有以下几点优势:
Hibernate对JDBC访问数据库的代码做了轻量级封装,大大简化了数据访问层繁琐的重复性代码,并且减少了内存消耗,加快了运行效率。
Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了DAO(Data Access Object,数据访问对象)层编码工作。
Hibernate的性能非常好,映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系。
可扩展性强,由于源代码的开源以及API的开放,当本身功能不够用时,可以自行编码进行扩展。
明确:
操作实体类就相当于操作数据库表
第2章CRM介绍
CRM(Customer Relationship Management)客户关系管理,是利用相应的信息技术以及互联网技术来协调企业与顾客间在销售、营销和服务上的交互,向客户提供创新式的个性化的客户交互和服务的过程。
其最终目标是将面向客户的各项信息和活动集成起来,组建一个以客户为中心的企业,实现对面向客户的活动的全面管理。
2.1功能模块划分:
CRM系统实现了对企业销售、营销、服务等各阶段的客户信息、客户活动进行统一管理。
CRM系统功能涵盖企业销售、营销、用户服务等各各业务流程,业务流程中与客户相关活动都会在CRM系统统一管理。
下边列出一些基本的功能模块,包括:客户信息管理、联系人管理、商机管理、统计分析等。

    客户信息管理        对客户信息统一维护,客户是指存量客户或拟营销的客户,通过员工录入形成公司的“客户库”是公司最重要的数据资源。    联系人管理        对客户的联系人信息统一管理,联系人是指客户企业的联系人,即企业的业务人员和客户的哪些人在打交道。    客户拜访管理        业务员(用户)要开发客户需要去拜访客户,客户拜访信息记录了业务员与客户沟通交流方面的不足、采取的策略不当、有待改进的地方或值得分享的沟通技巧等方面的信息。    综合查询        客户相关信息查询,包括:客户信息查询、联系人信息查询、商机信息查询等。    统计分析        按分类统计客户信息,包括:客户信息来源统计、按行业统计客户、客户发展数量统计等。    系统管理        系统管理属于crm系统基础功能模块,包括:数据字典、账户管理、角色管理、权限管理、操作日志管理等。

第3章Hibernate快速入门
3.1需求介绍
本章节我们是实现的功能是保存一个客户到数据库的客户表中。
3.2开发包和版本介绍
下载网址:http://sourceforge.net/projects/hibernate/files/hibernate-orm/5.0.7.Final/
页面显示如下图:

开发包目录,如下图所示:

从图可以看出,hibernate5.0.7的解压s目录中包含一系列的子目录,这些子目录分别用于存放不同功能的文件,接下来针对这些子目录进行简单介绍,具体如下:
documentation文件夹:存放Hibernate的相关文档,包括参考文档的API文档。
lib文件夹:存放Hibernate编译和运行所依赖的JAR包。其中required子目录下包含了运行Hibernate5项目必须的JAR包。
project文件夹:存放Hibernate各种相关的源代码。
3.3搭建hibernate开发环境(重点内容)
3.3.1第一步:拷贝必备的jar包到开发目录
数据库驱动包,如下图:
Hibernate/lib/required/*.jar 如下图

    日志记录的包,如下图              

3.3.2第二步:创建数据库和实体类
持久化类是应用程序中的业务实体类,这里的持久化是指类的对象能够被持久化保存到数据库中。Hibernate使用普通Java对象(Plain Old Java Object),即POJO的编程模式来进行持久化。POJO类中包含的是与数据库表相对应的各个属性,这些属性通过getter和setter方法来访问,对外部隐藏了内部的实现细节。下面就来编写Customer持久化类。
在项目src目录下,创建cn.itcast.domain包,并在包中创建实体类Customer(对应数据库表cst_customer),Customer类包含与cst_customer数据表字段对应的属性,以及相应的getXxx ()和setXxx ()方法。
/创建客户表/

CREATE TABLE `cst_customer` (  `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',  `cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',  `cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',  `cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',  `cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',  `cust_address` varchar(128) DEFAULT NULL COMMENT '客户联系地址',  `cust_phone` varchar(64) DEFAULT NULL COMMENT '客户联系电话',  PRIMARY KEY (`cust_id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

/**
* 客户的实体类
*/

public class Customer implements Serializable {    private Long custId;    private String custName;    private String custSource;    private String custIndustry;    private String custLevel;    private String custAddress;    private String custPhone;    public Long getCustId() {        return custId;    }    public void setCustId(Long custId) {        this.custId = custId;    }    public String getCustName() {        return custName;    }    public void setCustName(String custName) {        this.custName = custName;    }    public String getCustSource() {        return custSource;    }    public void setCustSource(String custSource) {        this.custSource = custSource;    }    public String getCustIndustry() {        return custIndustry;    }    public void setCustIndustry(String custIndustry) {        this.custIndustry = custIndustry;    }    public String getCustLevel() {        return custLevel;    }    public void setCustLevel(String custLevel) {        this.custLevel = custLevel;    }    public String getCustAddress() {        return custAddress;    }    public void setCustAddress(String custAddress) {        this.custAddress = custAddress;    }    public String getCustPhone() {        return custPhone;    }    public void setCustPhone(String custPhone) {        this.custPhone = custPhone;    }    @Override    public String toString() {        return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource                + ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress                + ", custPhone=" + custPhone + "]";    }}       

3.3.3第三步:编写映射配置文件(xml)
实体类Customer目前还不具备持久化操作的能力,而Hibernate需要知道实体类Customer映射到数据库Hibernate中的哪个表,以及类中的哪个属性对应数据库表中的哪个字段,这些都需要在映射文件中配置。
在实体类Customer所在的包中,创建一个名称为Customer.hbm.xml的映射文件,在该文件中定义了实体类Customer的属性是如何映射到cst_customer表的列上的。

public class HibernateUtil {    private static SessionFactory factory;    static{        try {            Configuration cfg = new Configuration();            cfg.configure();            factory = cfg.buildSessionFactory();        } catch (Exception e) {            //e.printStackTrace();            throw new ExceptionInInitializerError("初始化SessionFactory失败");        }    }
/** * 使用工厂生产一个Session对象, * 每次都是一个新的 * 此时Session还不符合自己的使用原则,调整符合放到hibernate的第二天 * @return */
public static Session openSession(){        return factory.openSession();    }}

第6章案例:使用Hibernate实现增删改查
6.1保存操作
/**
* hibernate的增删改查(查一个)

public class HibernateDemo4 {

/**
* 保存
*/

@Tpublic void testAdd(){Customer c = new Customer();c.setCustName("test");c.setCustLevel("VIP客户");c.setCustSource("网络");c.setCustIndustry("IT教育");c.setCustAddress("昌平");c.setCustPhone("010-84389340");//1.使用工具类获取一个SessionSession session = HibernateUtil.openSession();//2.开启事务//Transaction tx = session.beginTransaction();//3.保存客户session.save(c);//4.提交事务//tx.commit();//5.释放资源session.close();}

6.2查询一个实体
/**
* 根据id查询一个实体
*/

@Test    public void testFindOne(){        //1.使用工具类获取一个Session        Session session = HibernateUtil.openSession();        //2.开启事务        Transaction tx = session.beginTransaction();        //3.根据id查询        Customer c = session.get(Customer.class, 2L);        System.out.println(c);        //4.提交事务        tx.commit();        //5.释放资源        session.close();    }

6.3修改操作
/**
* 修改一个实体
*/

@Test    public void testUpdate(){        //1.使用工具类获取一个Session        Session session = HibernateUtil.openSession();        //2.开启事务        Transaction tx = session.beginTransaction();        //3.根据id查询        Customer c = session.get(Customer.class, 1L);        c.setCustName("TBD云集中心");        //修改实体        session.update(c);        //4.提交事务        tx.commit();        //5.释放资源        session.close();    }

6.4删除操作
/**
* 删除一个实体
*/

@Test    public void testDelete(){        //1.使用工具类获取一个Session        Session session = HibernateUtil.openSession();        //2.开启事务        Transaction tx = session.beginTransaction();        //3.根据id查询        Customer c = session.get(Customer.class, 1L);        //删除实体        session.delete(c);//delete from cst_customer where cust_id = ?        //4.提交事务        tx.commit();        //5.释放资源        session.close();    }}

6.5实体查询的另一个方法load
6.5.1实体查询的概念
所谓实体查询即OID查询,就是使用主键作为条件来查询一个实体。其中涉及的方法是Session对象get方法和load方法。
在本章节都是使用客户查询示例。
6.5.2方法的说明
get方法:
/**
* 根据id查询一个实体
* @param entityType 指的是要查询的实体类字节码对象
* @param id 查询的条件,即主键的值。
* @return 返回的是实体类对象
*/
T get(Class entityType, Serializable id);
get方法的代码演示:
/**
* 需求: 使用get方法查询id为1的客户
*/

@Test    public void test1(){        Session s = HibernateUtil.getCurrentSession();        Transaction tx = s.beginTransaction();        Customer c = s.get(Customer.class, 1L);        System.out.println(c);        tx.commit();    }       

load方法:
/**
* 根据id查询一个实体
* @param theClass 指的是要查询的实体类字节码
* @param id查询的条件,即主键的值。
* @return 返回的是实体类对象或者是实体类对象的代理对象
*/
T load(Class theClass, Serializable id);
load方法的代码演示:
/**
* 需求: 使用load方法查询id为1的客户
*/

@Test    public void test2(){        Session s = HibernateUtil.getCurrentSession();        Transaction tx = s.beginTransaction();        Customer c = s.load(Customer.class, 1L);        System.out.println(c.toString());        tx.commit();    }

问题:既然两个方法都是根据ID查询一个实体,他们有什么区别呢?
6.5.3get和load的区别
区别:
1、查询的时机不一样
get方法任何时候都是立即加载,即只要一调用get马上发起数据库查询
load方法默认情况下是延迟加载,即真正用到对象的非OID字段数据才发起查询
load方法可以通过配置的方式改为立即加载。
配置的方式:
由于load方法是hibernate的方法所以只有XML的方式:

2、返回的结果不一样
get方法永远返回查询的实体类对象。
load方法当是延迟加载时,返回的是实体类的代理对象。
涉及的概念:
立即加载:
是不管用不用马上查询。
延迟加载:
等到用的时候才真正发起查询。