Hibernate快速入门
come from:https://www.bilibili.com/video/BV1PE411H7SU?p=24&spm_id_from=pageDriver
1.建库
2.官网地址:https://hibernate.org/
进行下载:
往下翻:
3.压缩包分析
开始写代码
目录结构:
4.实体类
public class User_info {
private Integer id;
private String username;
private String password;
private String reaName;
...get/set
5.映射文件
<?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 package="com.company.entity">
<class name="User_info" table="user_info">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="reaName" column="real_name"></property>
</class>
</hibernate-mapping>
6.配置文件
<?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-factory>
<!--第一部分,数据库配置-->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!--第二部分,Hibernate的可选配置-->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!--第三部分,实体映射文件-->
<mapping resource="com/company/entity/UserInfo.hbm.xml"/>
</session-factory>
</hibernate-configuration>
7.编写测试类
package com.company.test;
import com.company.entity.User_info;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Test01 {
/**
* 步骤
* 1.加载主配置文件
* 2.根据主配置文件构建SessionFactory
* 3.使用SessionFactory生产一个session对象
* 4.使用session对象开启事务
* 5.执行保存客户操作
* 6.提交事务
* 7.释放资源
*/
public static void main(String[] args) {
User_info userInfo = new User_info();
userInfo.setUsername("jhpp");
userInfo.setPassword("jhpp");
userInfo.setReaName("金花婆婆");
//1.加载主配置文件
Configuration configuration = new Configuration();
configuration.configure();//默认会去src下寻找主配置文件
//2.根据主配置文件构建SessionFactory
//3.使用SessionFactory生产一个session对象
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
//4.使用session对象开启事务
Transaction transaction = session.beginTransaction();
//5.执行保存客户操作
session.save(userInfo);
//6.提交事务
transaction.commit();
//7.释放资源
session.close();
}
}
数据库中查看:成功
注:在主配置文件中添加如下属性可在数据库中添加字段
//添加此属性可对表进行更新操作(添加字段)
<property name="hibernate.hbm2ddl.auto">update</property>
如:
public class User_info {
private Integer id;
private String username;
private String password;
private String reaName;
private Integer status;//新添加的字段
<?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 package="com.company.entity">
<class name="User_info" table="user_info">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="reaName" column="real_name"></property>
<property name="status" column="status"></property>//映射文件中也要添加该字段
</class>
</hibernate-mapping>
hibernate执行流程:
Hibernate API详解
1.Configuration(会用)![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/40e9ee2e2403bfec077752e19cf87d5c.png)
Configuration常用方法
2.SessionFactory
3.Session
Session常用方法
获取多个实体
//查询多个实体对象
public static void finAll(){
Session session = HibernateUtil.openSession();
Transaction transaction = session.beginTransaction();
//hql 里面的表名要换成实体类名称,字段名称要改为属性名,占位符后面要加索引
Query query = session.createQuery("from User_info where id>?0");
query.setParameter(0,0);
List<User_info> list = query.list();
Iterator<User_info> iterator = list.iterator();
while (iterator.hasNext()){
User_info info = iterator.next();
System.out.println("==>"+ info);
}
System.out.printf("对象个数:"+list.size());
transaction.commit();
session.close();
}
Transaction的使用
在主配置文件中配置相关的属性
<?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">
<!--主配置文件 使用C3P0连接-->
<hibernate-configuration>
<session-factory>
<!--第一部分,数据库配置-->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!--C3P0 官方推荐的-->
<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!--第二部分,Hibernate的可选配置-->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!--第三部分,实体映射文件-->
<mapping resource="com/company/entity/UserInfo.hbm.xml"/>
</session-factory>
</hibernate-configuration>
使用Druid连接:主配置文件
<?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">
<!--主配置文件 使用Druid连接-->
<hibernate-configuration>
<session-factory>
<!--第一部分,数据库配置-->
<property name="driverClassName">com.mysql.jdbc.Driver</property>
<property name="url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="username">root</property>
<property name="password">123456</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!--Druid连接 hibernate5的连接方式-->
<property name="hibernate.connection.provider_class">com.alibaba.druid.support.hibernate.DruidConnectionProvider
</property>
<!--第二部分,Hibernate的可选配置-->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!--第三部分,实体映射文件-->
<mapping resource="com/company/entity/UserInfo.hbm.xml"/>
</session-factory>
</hibernate-configuration>
hibernate的快照机制
hibernate持久化类的状态
事务
hibernate的事务配置
案例:
添加配置类:
<!--把session绑定到当前线程-->
<property name="hibernate.current_session_context_class">thread</property>
工具类:
/**
* 获取当前线程的session,使用前需要配置
* @return
*/
public static Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
dao层:
/**
* 保证事务的完整性
* 往数据库中插入一条数据
*/
public static void test3(){
Session currentSession = HibernateUtil.getCurrentSession();
User_info user_info = new User_info();
user_info.setReaName("天");
currentSession.save(user_info);
}
/**
* 保证事务的完整性
* 往数据库中插入一条数据
*/
public static void test4(){
Session currentSession = HibernateUtil.getCurrentSession();
User_info user_info = new User_info();
user_info.setReaName("地");
currentSession.save(user_info);
}
service层测试:
public class ServiceTransaction02 {
private UserInfoDao userInfoDao = new UserInfoDao();
@Test
public void test02() {
/**
* java.lang.ArithmeticException: / by zero
* 抛出异常,会导致test1执行成功,test2执行失败
* 问题:怎么保证事务的原子性?
* 解决:原子性不一致问题
* 1.在配置文件中进行配置:
* <!--把session绑定到当前线程-->
* <property name="hibernate.current_session_context_class">thread</property>
* 2.编写工具类
* getCurrentSession(){return sessionFactory.getCurrentSession();}
* 3.保证了
*/
Session currentSession = HibernateUtil.getCurrentSession();
Transaction transaction = currentSession.beginTransaction();
userInfoDao.test3();
int i = 5 / 0;//会抛出异常
userInfoDao.test4();
transaction.commit();
}
hibernate5种查询
Hql常用查询
分页
案例:一对多
一是:stu_class,多是:student
创建stu_class表
创建student表
student的外键
StuClass的实体类:
package com.company.entity;
import java.util.HashSet;
import java.util.Set;
public class StuClass {
private Integer id;
private String className;
private String classNo;
/**
* 一对多关系中,一的一方包含多的一方的集合
* 实体类集合的引用
*/
private Set<Student> students =new HashSet<>();
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getClassNo() {
return classNo;
}
public void setClassNo(String classNo) {
this.classNo = classNo;
}
}
StuClass的映射文件:
<?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 package="com.company.entity">
<class name="StuClass" table="stu_class">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="className" column="class_name"></property>
<property name="classNo" column="class_no"></property>
<!--
一对多关系中,配置一的一方即为主表映射配置
set(用于配置set集合属性)
属性:name:指定set集合的属性名称
table:指定从表的名称(在一对多关系中可以省略)
key(用于映射外键字段)
属性:column:指定从表外键名称,设置该列才能给从表加外键约束
one-to-many(用于建立一对多的映射配置)
属性:class指定从表对应实体的名称
-->
<set name="students" table="student">
<!--key 必须定义在第一个 -->
<key column="class_id"></key>
<one-to-many class="Student"></one-to-many>
</set>
</class>
</hibernate-mapping>
Student实体类:
package com.company.entity;
public class Student {
private Integer id;
private String stuName;
//在一对多关系中,多的一方包含一的一方
private StuClass stuClass;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public StuClass getStuClass() {
return stuClass;
}
public void setStuClass(StuClass stuClass) {
this.stuClass = stuClass;
}
}
Student的映射文件:
<?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 package="com.company.entity">
<class name="Student" table="student">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<!--
一对多关系中,即从表的映射配置
涉及标签:many-to-one(建立多对一的关系)
name:从表实体中引用主表实体中的对象引用名称
class:指定主表的全限定名称
column:指定从表的外键名称
-->
<property name="stuName" column="stu_name"></property>
<many-to-one name="stuClass" class="StuClass" column="class_id">
</many-to-one>
</class>
</hibernate-mapping>
测试类:
package com.company.TestRtoR;
import com.company.entity.StuClass;
import com.company.uitl.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
public class TestOneMoney {
@Test
public void testSaveMaster(){
Session currentSession = HibernateUtil.getCurrentSession();
Transaction transaction = currentSession.beginTransaction();
StuClass stuClass = new StuClass();
stuClass.setClassName("java992");
stuClass.setClassNo("java992");
currentSession.save(stuClass);
transaction.commit();
}
}
级联插入
/**
* 级联插入,让孙悟空与西天取经团关联
* 进行表之间的关联,插入操作(保存学生时,把班级也保存了)
*/
@Test
public void testSaveMaster2(){
Session currentSession = HibernateUtil.getCurrentSession();
Transaction transaction = currentSession.beginTransaction();
//班级对象
StuClass stuClass = new StuClass();
stuClass.setClassName("西天取经团");
stuClass.setClassNo("001");
//学生对象
Student student = new Student();
student.setStuName("孙悟空");
//设置孙悟空的班级
student.setStuClass(stuClass);
//在班级中添加孙悟空的信息
stuClass.getStudents().add(student);
currentSession.save(student);
//需要设置Student映射文件中many-to-one标签的属性cascade="save-update"
transaction.commit();
}
级联修改
/**
* 级联修改1
* 进行表之间的关联,修改操作()
*/
@Test
public void testSaveMaster3(){
Session currentSession = HibernateUtil.getCurrentSession();
Transaction transaction = currentSession.beginTransaction();
//获取具体的班级对象
StuClass stuClass = currentSession.get(StuClass.class, 6);
//学生对象
Student student = new Student();
//插入一个学生对象,让他与ID为6的班级关联
student.setStuName("齐天大圣");
//在班级中添加孙悟空
stuClass.getStudents().add(student);
//修改班级中的孙悟空信息
currentSession.update(stuClass);
transaction.commit();
}
/**
* 级联修改2
* 进行表之间的关联,修改操作()
*/
@Test
public void testSaveMaster4(){
Session currentSession = HibernateUtil.getCurrentSession();
Transaction transaction = currentSession.beginTransaction();
//获取具体的班级对象
StuClass stuClass = currentSession.get(StuClass.class, 6);
//获取具体的学生对象,修改他的姓名,然后再关系ID为6的班级
Student student = currentSession.get(Student.class,1);
//插入一个学生对象,让他与ID为6的班级关联
student.setStuName("美猴王");
//在班级中添加美猴王
stuClass.getStudents().add(student);
//修改班级中的孙悟空信息
currentSession.update(stuClass);
transaction.commit();
}
删除从表
/**
* 删除从表
* 随便删
*
*/
@Test
public void testDeleteMaster(){
Session currentSession = HibernateUtil.getCurrentSession();
Transaction transaction = currentSession.beginTransaction();
Student student = currentSession.get(Student.class,1);
currentSession.delete(student);
transaction.commit();
}
删除主表
/**
* 删除主表
* 慎用
*通过在映射文件中set标签里设置
* <set name="students" table="student" inverse="true" cascade="save-update">
* 可以防止误删主表
*/
@Test
public void testDeleteMaster1(){
Session currentSession = HibernateUtil.getCurrentSession();
Transaction transaction = currentSession.beginTransaction();
StuClass stuClass = currentSession.get(StuClass.class, 8);
currentSession.delete(stuClass);
transaction.commit();
}