Hibernate学习笔记2
基础学习:
普通内存与Session的对象其实是同一个对象 (瞬时态和持久态对象是同一个对象)
/*
* save方法的执行过程:
* 1)向mysql发送一条信息,告诉mysql要执行一条mysql语句,先为我生成一条id传送给我
* 2)接收到mysql发送过来的id,并使用该id初始化student对象的属性
* 3)现在的student对象已经具有了id,那么session缓存可以管理它:
* 注意:将student的id作为key,student对象的引用作为value,放入到session缓存中
* 也就是说,只有id属性不为null的对象才有可能被session管理
* 一个对象被session管理,就意味着,这个对象被放入到了Session缓存的Map中
* 当对象由持久态转换成游离态时,实际就是将Map的该对象删除了
* 当对象由游离态转换成持久态,实际上就是先将该对象放入到Session的这个Map中,再对其进行update
*/
单表查询:
Hibernate是DAO对象,使用HQL查询,使用query接口,支持动态参数绑定的参数 session.createQuery(HQL) 是面向对象的查询 类名+属性名 sql 是面向二维表的查询
原生HQL语句结构 :就是SQL查询:session.createSQLQuery(sql)
Criteria接口:使用Session对象的crateCriteria()方法可以获得Criteria对象
分类查询:(query)QBC 查询通过标准接口
关联关系:外键:外面的主键,即使用其他表的主键值作为自己的某字段的取值 一对多 外键一般是定义在另一个表中 是建在多方表(建在一方表会出现大量数据冗余) 关系:即是通过外键建立的关系
关联关系映射:
实体对象间的关系,从数量上可以划分为 1:1 1:n m:1 n:m
关联属性:
set具有无序性和不重复性 list具有有序性和可重复性
关联方向: 单向和双向 单向关联只有一个对象可以加载和访问对方,但对方看不到另一个方 save需要进行级联保存,delete需要进行级联删除
关联关系维护: 代码上的关联对象的维护:通过set来建立代码关联关系的维护,某个类关联某个类,是主动关联的类在进行维护
数据库上关联关系的维护:直接通过数据库数据的关联 save执行一个表操作,要再次插入另一个表id,做的update操作
底层用于维护关联关系的sql语句是 save执行的是多方,先插入对方的数据,再插入自己表的id,执行的是insert语句
java代码中谁在维护关联关系,在session.save()谁 (就去执行谁)
关系映射:
1:n 关联关系 单向关联和双向关联
自关联 :所谓自关联是指自己即充当一方,又充当多方 (老板既是员工,又是 员工) 只有一张表,这张表具有外键,一级栏目的外键值为NULL,而子栏目具有外键值
下面是使用到的jar包链接:
下面介绍一个学习的demo
文件结构:
实体类Student
package com.vrv.yinkailong.bean;
public class Student {
//以后定义主键id必须是Integer
private Integer id;
private String name;
private int age;
private double score;
//c o
public Student() {
super();
}
public Student(String name, int age, double score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ", score=" + score + "]";
}
}
下面是映射文件 com/vrv/yinkailong/bean/Student.hbm.xml
<?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.vrv.yinkailong.bean">
<!-- 写映射文件 作用:
1:类到表的映射
2:属性到字段的映射
-->
<class name="Student" table="t_student">
<id name="id" column="tid">
<!-- 指定主键生成器 -->
<generator class="native"/>
</id>
<property name="name" column="tname"/>
<property name="age" column="tage"/>
<property name="score" column="tscore"/>
</class>
</hibernate-mapping>
配置文件:hibernate.cfg.xml 路径在src下即可
<?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">
<!-- session的不同含义 http:session (view层) hibernate :session(DAO层) MyBatis: session(SQL session) -->
<!-- 三大数据库 Mysql DB2 Oracal -->
<hibernate-configuration>
<session-factory>
<!-- DB链接四要素 -->
<property name="hibernate.connection.driver_class" >com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/test</property><!-- /// 相当于127.0.0.1:3306 -->
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 需要指定方言,才能生成相应的sql 语句 去hibernate core 里面找相应的版本 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 数据源 数据库连接池 链接数据库的那个容器我们成为数据库连接池 决定啥时候创建链接 :一般是先建立好,然后用户需要使用的时候直接从数据库连接池获取-->
<!--占用资源 :释放连接 连接个数 当达到下限需要再创建 然后释放之后需要设置最多放置多少条(上限) 空闲时间 :空闲多久会自动进行销毁 使用第三方机构的连接池-->
<!-- 链接提供者 -->
<property name="hibernate.co nnection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!-- 保证在当前线程上下文中获取到的session是同一个session -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 配置自动建表 DDL数据库定义语言 DML数据库操作语言 DQL 数据源查询语言 create 每运行一次都会重新见一个表 update只会做更新 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 调试常用 :显示SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 生成sql语言进行格式化 -->
<property name="hibernate.format_sql">true</property>
<!-- 映射文件 -->
<mapping resource="com/vrv/yinkailong/bean/Student.hbm.xml"/>
</hibernate-configuration>
衍生出来的工具类:
package com.vrv.yinkailong.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
//自定义一个工具类
public class HiberUtil {
private static SessionFactory sessionFactory = null;;
//必须保证sessionfactory是单例的,占资源
public static Session getSession()
{
/*Configuration configure = new Configuration().configure();
//2:创建session工厂对象
SessionFactory sessionFactory = configure.buildSessionFactory();
//3:获取session对象
Session session = sessionFactory.getCurrentSession(); */
SessionFactory sessionFactory = getSessionFactory();
return sessionFactory.getCurrentSession();
}
//抽取局部方法 alt + shift+ m
public static SessionFactory getSessionFactory() {
//此处做到单例,先判断在返回,能够保证做到单例
if (sessionFactory == null || sessionFactory.isClosed()) {
sessionFactory = new Configuration().configure().buildSessionFactory();
}
return sessionFactory;
}
}
测试类:MyTest.java
package com.vrv.yinkailong.test;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import com.vrv.yinkailong.bean.Student;
import com.vrv.yinkailong.util.HiberUtil;
public class MyTest {
//准备测试数据
@ Test
public void test00()
{
Session session = HiberUtil.getSession();
try {
//4:开启事务
session.beginTransaction();
//5:执行操作(保存)
for(int i = 0; i < 10 ; i ++)
{
Student student = new Student("n_",10+i,80+i);
session.save(student);
}
//6:执行事务
session.getTransaction().commit();
} catch (Exception e) {
//7:事务回滚
session.getTransaction().rollback();
e.printStackTrace();
}
}
//查询所有 sql
@ Test
public void test01_SQL()
{
Session session = HiberUtil.getSession();
try {
//4:开启事务
session.beginTransaction();
String sql = "select * from t_student";
List<Student> list = session.createSQLQuery(sql).addEntity(Student.class).list();
for (Student student : list) {
System.out.println(student);
}
session.getTransaction().commit();
} catch (Exception e) {
//7:事务回滚
session.getTransaction().rollback();
e.printStackTrace();
}
}
//查询所有 hql
@ Test
public void test01_HQL()
{
Session session = HiberUtil.getSession();
try {
//4:开启事务
session.beginTransaction();
// leimgin Student
String hql = "from Student";
List<Student> list = session.createQuery(hql).list();
for (Student student : list) {
System.out.println(student);
}
session.getTransaction().commit();
} catch (Exception e) {
//7:事务回滚
session.getTransaction().rollback();
e.printStackTrace();
}
}
//查询所有 QBC
@ Test
public void test01_QBC()
{
Session session = HiberUtil.getSession();
try {
//4:开启事务
session.beginTransaction();
// leimgin Student
List<Student> list = session.createCriteria(Student.class).list();
for (Student student : list) {
System.out.println(student);
}
session.getTransaction().commit();
} catch (Exception e) {
//7:事务回滚
session.getTransaction().rollback();
e.printStackTrace();
}
}
}
最后运行得到正确结果
以后会每天写一个学习笔记和资料,希望能够成长为技术大牛!!!!
推荐阅读