hibernate框架

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_36762821/article/details/82192908

1】了解hibernate框架,首先了解crm,即客户管理系统,对企业的销售,营销,服务等各阶段的客户信息和客户活动进行管理。其具体功能如下:

     客户信息管理、联系人管理、客户访问管理,综合查询,统计分析,系统管理。

2】crm三层技术架构:表示层(视图+控制 即jsp、html、servlet)、业务层(service)持久层(将数据持久化到数据库以及一些接口)。

3】hibernate属于轻量级持久层框架,用于实现DAO,是一个关系型数据库ORM框架。用于实现DAO:用hibernate实现对数据库的访问。

ORM:object ralation mapping 对象关系映射

4】hibernate项目准备:

1、导包

2、建表

3、创建配置文件X.hbm.xml(配置数据库表和pojo属性的对应关系,主键信息等)和X.java(对应数据库中的表中字段)的pojo文件。

public class CstCustomer implements java.io.Serializable {

	private Long custId;
	private String custName;
	private Long custUserId;
	private Long custCreateId;
	private String custSource;
	private String custIndustry;
	private String custLevel;
	private String custLinkman;
	private String custPhone;
	private String custMobile;
	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 Long getCustUserId() {
		return custUserId;
	}
	public void setCustUserId(Long custUserId) {
		this.custUserId = custUserId;
	}
	public Long getCustCreateId() {
		return custCreateId;
	}
	public void setCustCreateId(Long custCreateId) {
		this.custCreateId = custCreateId;
	}
	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 getCustLinkman() {
		return custLinkman;
	}
	public void setCustLinkman(String custLinkman) {
		this.custLinkman = custLinkman;
	}
	public String getCustPhone() {
		return custPhone;
	}
	public void setCustPhone(String custPhone) {
		this.custPhone = custPhone;
	}
	public String getCustMobile() {
		return custMobile;
	}
	public void setCustMobile(String custMobile) {
		this.custMobile = custMobile;
	}
	
	
}

4、创建hibernate.cfg.xml文件,里面配置访问数据库的信息,如驱动,数据库,数据库账号密码,及加载X.hbm.xml文件。

<hibernate-configuration>
	<!-- 配置会话工厂所需要的属性 -->
	<session-factory>
	<!-- 配置hibernate运行的参数 -->

	<!-- 数据库方言,根据数据库选择 -->
	<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
	<!-- 数据库驱动 -->
	<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
	<!-- 数据库连接url -->
	<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernateproject</property>
	<!-- 数据库用户名和密码 -->
	<property name="hibernate.connection.username">root</property>
	<property name="hibernate.connection.password">123456</property>
<!-- 配置c3p0 -->
	 <!-- 连接池提供商 -->
	<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
	<!-- 连接池中保留的最大连接数-->
	<property name="hibernate.c3p0.max_size">10</property>
	<!-- 连接池中保留的最小连接数 -->
	<property name="hibernate.c3p0.min_size">1</property>
	<!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃 -->
	<property name="hibernate.c3p0.maxIdleTime">60</property>
	<!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->
	<property name="hibernate.c3p0.timeout">5000</property>
	

	<!--为了方便调试是否在运行hibernate时在日志中输出sql语句 -->
	<property name="hibernate.show_sql">true</property>
	<!-- 是否对日志中输出的sql语句进行格式化 -->
	<property name="hibernate.format_sql">true</property>

	<!-- 
		hbm2ddl.auto的4个值,如果不需要设置为none,建议正式环境设置为none
		validate 加载hibernate时,验证创建数据库表结构
		create 每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
		create-drop 加载hibernate时创建,退出是删除表结构
		update 加载hibernate自动更新数据库结构
		none 不执行检查
		 -->
	<property name="hibernate.hbm2ddl.auto">none</property>
	


	<!-- 加载hbm.xml映射文件 -->
	<mapping resource="cn/itcast/crm/domain/CstCustomer.hbm.xml"/>
	</session-factory>

5】hibernate执行流程:

    应用程序

   1、 configuration hibernate配置文件(hibernate.cfg.xml--->X.hbm.xml---->X.java)

   2 、Sessionfactory会话工厂(线程安全,采用单例模式创建)

    3、Session会话

    4、Transaction事务管理对象(回滚事务、提交事务),其中进行query查询操作不需要开启事务,增删改操作需要。

    5、 访问到数据库

     6、 释放资源

6】hibernateUtil工具类

public class HibernateUtil {

	// 会话工厂,以单例方式管理
	private static SessionFactory sessionFactory;

	// ThreadLocal存储session
	private static ThreadLocal<Session> session = new ThreadLocal<Session>();


	// 以单例方式管理sessionFactory
	static {
		try {
			sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
		} catch (HibernateException e) {
			e.printStackTrace();
			throw new HibernateException("初始化会话工厂失败!");
		}

	}
	//得到一个单例的会话工厂
	public static SessionFactory getSessionFactory(){
		return sessionFactory;
	}
	//获取一个新session
	public static Session openSession(){
		return sessionFactory.openSession();
	}
	
	//获取当前与线程绑定的session,如果获取不到则创建一个新session并与当前线程绑定
//	public static Session getCurrentSession() throws HibernateException {
//		//获取当前线程绑定的session
//		Session s = (Session) session.get();
//		if (s == null) {
//			//创建一个新session
//			s = sessionFactory.openSession();
//			//新session并与当前线程绑定
//			session.set(s);
//		}
//		return s;
//	}
 
	public static Session getCurrentSession() throws HibernateException {
		return sessionFactory.getCurrentSession(); 
	}
	//关闭当前线程绑定的session
//	public static void closeSession() throws HibernateException {
//		//获取当前线程绑定的session
//		Session s = (Session) session.get();
//		if (s != null){
//			//关闭session
//			s.close(); 
//		}
//		session.set(null);
//	}
	
	public static void closeSession() throws HibernateException {
		sessionFactory.getCurrentSession().close();
	}
}

7】客户列表查询

   1、QBC(query by criteria)按条件查询。

public Long findCustomerCount(CstCustomer cstCustomer) {
		Session session = HibernateUtil.openSession();
		Criteria criteria = session.createCriteria(CstCustomer.class);
		criteria.setProjection(Projections.rowCount());
		//查询总数
		Long total = (Long) criteria.uniqueResult();
		return total;
	}

    2、离线的criteria即DetachedCriteria,其创建不需要session,但必须通过session变为criteria才能执行操作,建议使用detachedcriteria。

public Long findCustomerCount(DetachedCriteria detachedCriteria){
		Session session = HibernateUtil.openSession();
		//离线criteria与session绑定生成可执行criteria
		Criteria criteria = detachedCriteria.getExecutableCriteria(session);
		criteria.setProjection(Projections.rowCount());
		//查询总数
		Long total = (Long) criteria.uniqueResult();
		return total;
	}
	public List<CstCustomer> findCustomerList(DetachedCriteria detachedCriteria, int firstResult, int maxResults){
		Session session = HibernateUtil.openSession();
		//离线criteria与session绑定生成可执行criteri
		Criteria criteria = detachedCriteria.getExecutableCriteria(session);
		criteria.setFirstResult(firstResult);
		criteria.setMaxResults(maxResults);
		List list = criteria.list();
		return list;
	}

8】hibernate对象的三种状态

   1、瞬时态(创建对象时为瞬时态,没与session绑定,无主键值,瞬时态设置主键值便变为托管态)

   2、持久态(瞬时态对象执行save之后变为持久态,与session关联),持久态对象可直接设置属性,并在数据库更改。持久态执行delete方法后转为瞬时态。

   3、托管态(持久态对象关闭session后变为托管态,有主键值),托管态执行updata或saveorupdata方法时转为持久态。

9】一级缓存

对象执行save,对象保存在一级缓存中。

一级缓存是 session对象中一块内存。

在同一个session中,查询一个对象是不会发出sql语句。

session关闭一级缓存不存在了,再查询对象,会发出sql。

10】客户和联系人的增删改查,配置:

一个客户有多个联系人,客户到联系人为一对多关系。

一个联系人只有属于一个客户,联系人到客户多对一关系。

客户方配置:

 

联系人方配置:

1、双方同时添加

 

2、已有客户,只添加联系人

         方法:通过客户持久态对象添加联系人

         错误:持久态对象引用了一个舜时态对象

         object references an unsaved transient instance - save the transient instance

 

         解决:commit之前将瞬时态转成持久态,使用hibernate级联保存方法解决。

 

   在CstCustomer.hbm.xml中配置cascade:

报错:

Column 'lkm_cust_id' cannot be null

执行向联系人表插入时,'lkm_cust_id字段设置了一个空值。

解决方法:

观察控制台,打出一条多条的sql:

 

上边打出多余sql的原因,当前一对多、多对一的关系由一方来维护的。

解决方法:让关系的维护方变为多方。

 

 

展开阅读全文

没有更多推荐了,返回首页