Hibernate

海叶秋
2023-12-01

Hibernate

1. Hibernate简介

Hibernate 是一个开源的轻量级的ORM (Object/relational mappping)数据持久化的框架,他是对JDBD进行一个轻量级的封装。并且是一个自动化的框架,(在hibernate中我们可以使用Sql,HQL ,标准查询),HQL ,hibbernate对可以自动化实现sql语句。

2. Hibernate 的下载

[hibernate下载](www.hibernate.org)

3. Hibernate的 HelloWorld

3.1 Hibernate 项目需要导入的jar包

lib/required中所有
jpa-metamodel-generator 下的所有
javax.activation-1.2.0.jar
jaxb-api-2.3.0.jar
jaxb-core-2.3.0.jar
jaxb-impl-2.3.0.jar
mysql 驱动
日志
slf4j-api-1.7.25.jar
log4j-1.2.17.jar
slf4j-log4j12-1.7.25.jar

3.2 新建Java项目

  • 建立lib文件夹
  • 导入jar包
  • buildpath jar 包构建到项目路径中
  • 建立数据库
  • 实体类
  • 项目的结构
  • src
  • com.yunjian.entity
  • Dept.java
  • dept.hbm.xml
  • com.yunjian.dao
  • DeptDao
  • com.yunjian.dao.impl
  • com.yunjian.utils
  • HibernateUtils
  • hibernate.cfg.xml

3.3 Hibernate 的核心配置文件配置

  1. 在src 下新建hibernate.cfg.xml
  2. hibernate 核心jar 下面的hibernate 中找到 hibernate-configuration-3.0.dtd 导入核心配置文件的头
  3. 在sessionfactory中配置信息
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<!-- session -->
	<session-factory>
		<!-- 配置数据源 Driver  url username password -->
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="connection.url">jdbc:mysql://localhost:3306/ajax</property>
		<property name="connection.username">root</property>
		<property name="connection.password">root</property>
		<!-- 配置其他的信息 -->
		<property name="show_sql">true</property>
		<property name="format_sql">true</property>
		<!--配置方言  -->
		<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
		<!-- 配置hibernate 对数据库的操作方式 -->
		<property name="hibernate.hbm2ddl.auto ">update</property>
		<!-- 配置映射文件 -->
		<mapping resource="com/yunjian/entity/Dept.hbm.xml"/>
	</session-factory>
</hibernate-configuration>	

3.4 Hiernate 的映射文件配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  <hibernate-mapping>
  	<class name="com.yunjian.entity.Dept">
  	<!--  name是类的属性名称  colum 是表中的字段名称-->
  		<id name="deptid" column="deptid">
  		<!-- 表中主键的维护关系 -->
  			<generator class="native"></generator>
  		</id>
  		<property name="deptname" column="deptname"></property>
  	 </class>
  </hibernate-mapping>
<id name="deptid" column="deptid">
  		<!-- 表中主键的维护关系  -->
  			<generator class="native"></generator>
 </id>
  • identity 数据库自己维护主键自增
  • native 自动识别

3.5 HibernateUtils

package com.yunjian.utils;

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

public class HibernateUtils {
	/**
	 * hibernate 的核心是session 
	 * 获取到session
	 * session 是通过sessionFactory 创建的
	 * 获取sessionFactory  使用单例设计模式
	 * 
	 */
	static SessionFactory  sessionFactory = null;
	static {
		//读取核心配置文件 加载数据源
		Configuration  config = new Configuration().configure();
		//建立工厂
		sessionFactory = config.buildSessionFactory();
	}
	//获取Session
	public static Session  getSession() {
		return sessionFactory.openSession();
	}
}

3.6 遇到的问题及解决方法

1. 是映射文件找不到
  • 是在hibernate.cfg.xml 中映射文件的路径不正确

  • <class name="com.yunjian.enity.Dept"> 包名要正确
        <!--  name是类的属性名称  colum 是表中的字段名称-->
      		<id name="deptid" column="deptid">
    
  • 在hql 语句中我们 的from 后面跟的是类名

  • <!--  name是类的属性名称  colum 是表中的字段名称-->
      		<id name="deptid" column="deptid">
    
  • xml 对格式要求很严格 顶头不能有空格

3.7 Hibernate 添加日志文件

  • slf4j 他是日志的接口
  • logfj 是日志真正的实现
  • slf4j-log4j12-1.7.25.jar 中间的转换包
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# 日志输出的格式 样式
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
# marn debug info 
log4j.rootLogger=info, stdout

log4j.logger.org.hibernate=debug

log4j.logger.org.hibernate.type=info

log4j.logger.org.hibernate.tool.hbm2ddl=debug

4 Hibernate 的基本操作

hibernate 将数据库的操作封装到了方法中:
是一个对象关系映射的框架。如何映射的?
​ 我们通过hbm.xml 进行映射,通过主键id进行维护映射关系
get: 我们根据主键去数据库直接进行查询。
load:(懒加载)
​ load进行查询的时候我们先去session 看一眼,如果session 中有相同的id的缓存值就直接获取不需要再去数据库查询了。如果session中没有数据他也会去数据库进行查询。
save:
update :
delete:
在hibernate中会关闭事务的自动提交,所以在使用SessionFactory.openSession()的时候,除了查询以外的其他操作都需要事务的开启和提交。
在hibernate中会关闭事务的自动提交,所以在使用SessionFactory.currentSeesion()的时候,包括查询和其他操作都需要事务的开启和提交。

@Override
	public int addDept(Dept dept) {
        //获取事务
		Transaction transaction = session.getTransaction();
       //开启事务
		transaction.begin();
		int result  = (int) session.save(dept);
        //提交事务
		transaction.commit();
		return result;
	}
package com.yunjian.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.yunjian.dao.DeptDao;
import com.yunjian.entity.Dept;
import com.yunjian.utils.HibernateUtils;

public class DeptDaoImpl implements DeptDao {
	//获取到Session
	Session session = HibernateUtils.getSession();
	Session session1 = HibernateUtils.getSession();
	@Override
	public List<Dept> selectAll() {
		session.getTransaction().begin();
		List<Dept> list = session.createQuery("from Dept").list();
		System.out.println(session==session1);//false
		session.getTransaction().commit();
		return list;
	}
	@Override
	public Dept findById(int id) {
		Dept dept = session.get(Dept.class, id);
			//清空session
			session.clear();
			System.out.println(session.load(Dept.class, 1));
		//Dept dept = session.load(Dept.class, 9);
		return dept;
	}
	
	/***
	 * 为什么执行成供以后数据库中没有发生改变
	 * Autocommit mode: false
	 * 我们要进行手动开启和提交事务
	 * 为什么id会自增但是数据库没有进去?
	 */
	@Override
	public int addDept(Dept dept) {
		Transaction transaction = session.getTransaction();
		transaction.begin();
		int result  = (int) session.save(dept);
		transaction.commit();
		return result;
	}
	@Override
	public int updateDept(Dept dept) {
		session.getTransaction().begin();
			session.update(dept);
		session.getTransaction().commit();
		return 0;
	}
	@Override
	public int deleteDept(Dept dept) {
		session.getTransaction().begin();
		session.delete(dept);
		session.getTransaction().commit();
		return 0;
	}

}

5 Session是hibernate 的一级缓存

5.1 openSession()

public class DeptDaoImpl implements DeptDao {
	//获取到Session
	Session session = HibernateUtils.getSession();
	Session session1 = HibernateUtils.getSession();
	@Override
	public List<Dept> selectAll() {
		List<Dept> list = session.createQuery("from Dept").list();
		System.out.println(session==session1);//false
		return list;
	}

我们通过openSession()每次获取的时候SessionFactory 给我们都是一个新的Session.

5.2 getCurrentSeesion()

org.hibernate.HibernateException: No CurrentSessionContext configured!

我们使用SessionFactory 构建getCurrentSeesion的时候回报错。错误解决方式:

<!-- 在单线程的环境中我们需要一个session 就可以了 -->
		<property name="current_session_context_class">thread</property>

如果使用了getCurrentSession 那么所有的操作都需要添加事务。(查询也需要事务的开启和关闭)

单线程中一个session 就足够了。

6 Hibernate 的单表查询

  • 条件查询
  • 分组查询
  • 排序查询
  • 聚合函数查询
  • 模糊查询
public void selectAllkinds() {
		session.getTransaction().begin();
		//-------------条件查询----------------
		//Sql
		String sql = "select * from dept where deptid = ?";
		List<Dept> list = session.createSQLQuery(sql).addEntity(Dept.class)
				.setParameter(0, 1).list();
			//System.out.println(list);
		//Hql
		String hql = "from Dept where deptid =?";
		Dept hqlList = (Dept) session.createQuery(hql)
				.setParameter(0, 1)
				//结果只有一个
				.getSingleResult();
		//System.out.println(hqlList);
		//标准查询  没有sql 语句  全是封装好的放法
		  List list2 = session.createCriteria(Dept.class)
				.add(Restrictions.eq("deptid", 1)).list();
		//System.out.println(list2);
		//------------------------分组--------------------
		//Hql
		  String hqlGrounp = "from Dept group by deptname";
		List<Dept> groupList = session.createQuery(hqlGrounp).list();
		  //System.out.println(groupList);
		//----------------排序-------------------
		//----------------模糊查询-------------------
		 String hqlLike = "from Dept where deptname like ?";
			List<Dept> likeList = session.createQuery(hqlLike)
					.setParameter(0, "%后%")
					.list();
			System.out.println("likeList:"+likeList);
			
			
			
		session.getTransaction().commit();
		
		
		
	}
 类似资料: