Hibernate 是一个开源的轻量级的ORM (Object/relational mappping)数据持久化的框架,他是对JDBD进行一个轻量级的封装。并且是一个自动化的框架,(在hibernate中我们可以使用Sql,HQL ,标准查询),HQL ,hibbernate对可以自动化实现sql语句。
[hibernate下载](www.hibernate.org)
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
- 建立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
- 在src 下新建hibernate.cfg.xml
- hibernate 核心jar 下面的hibernate 中找到 hibernate-configuration-3.0.dtd 导入核心配置文件的头
- 在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>
<?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 自动识别
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();
}
}
是在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 对格式要求很严格 顶头不能有空格
- 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
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;
}
}
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.
org.hibernate.HibernateException: No CurrentSessionContext configured!
我们使用SessionFactory 构建getCurrentSeesion的时候回报错。错误解决方式:
<!-- 在单线程的环境中我们需要一个session 就可以了 -->
<property name="current_session_context_class">thread</property>
如果使用了getCurrentSession 那么所有的操作都需要添加事务。(查询也需要事务的开启和关闭)
单线程中一个session 就足够了。
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();
}