这是黑马视频的学习笔记
实体类编写规则
1.实体类里面属性是私有的
2.私有属性使用公开的get和set方法操作
3.实体类要有属性作为唯一值(一般使用id值)
4.实体类属性建议不使用基本数据类型,而是使用包装类型。
int--Integer char---Character,其他都是首字母大写
hibernate主键生成策略
1.hibernate要求实体类里面有一个属性作为唯一值,对应表的主键,主键有不同的生成策略
2.hibernate的主键生成策略有很多值
native: 由hibernate根据使用的数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式,灵活性很强。如果能支持identity则使用identity,如果支持sequence则使用sequence。
UUID:Universally Unique Identifier,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字,标准的UUID格式为:
xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx (8-4-4-4-12)
其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。
Hibernate在保存对象时,生成一个UUID字符串作为主键,保证了唯一性,但其并无任何业务逻辑意义,只能作为主键,唯一缺点长度较大,32位(Hibernate将UUID中间的“-”删除了)的字符串,占用存储空间大,但是有两个很重要的优点,Hibernate在维护主键时,不用去数据库查询,从而提高效率,而且它是跨数据库的,以后切换数据库极其方便。
实体类操作
对实体类的crud操作
1.添加操作:
package test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import cn.itcast.entity.User;
public class Test {
public static void main(String[] args) {
Configuration configuration = new Configuration();
configuration.configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
User user3=new User();
user3.setUsername("lucy");
user3.setPassword("520");
user3.setAddress("越南");
session.save(user3);
//提交事务
tx.commit();
//关闭资源
session.close();
sessionFactory.close();
}
}
2.根据id查询操作:
调用session里面的get方法,
public void testGet() {
// 获取sessionfactory对象
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 获取session
Session session=sessionFactory.openSession();
// 开始事物
Transaction tx=session.beginTransaction();
//根据id查询
User user=session.get(User.class,1);
System.out.println(user);
//提交事务
tx.commit();
//关闭资源
session.close();
sessionFactory.close();
}
3.修改操作
@Test
public void testUpdate() {
// 获取sessionfactory对象
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 获取session
Session session=sessionFactory.openSession();
// 开始事物
Transaction tx=session.beginTransaction();
//根据id查询
User user=session.get(User.class,1);
user.setUsername("东方不败");
session.update(user);
//提交事务
tx.commit();
//关闭资源
session.close();
sessionFactory.close();
}
4.删除操作
@Test
public void testDelete() {
// 获取sessionfactory对象
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
// 获取session
Session session=sessionFactory.openSession();
// 开始事物
Transaction tx=session.beginTransaction();
//第一种删除方法,根据id值删除
User user=session.get(User.class,2);
session.delete(user);
//第二种删除方法
// User user2=new User();
// user2.setUid(3);
//
// session.delete(user2);
//
//提交事务
tx.commit();
//关闭资源
session.close();
sessionFactory.close();
}
5.实体类对象的状态:
瞬时态:对象里面没有id值,对象与session也没有关联
持久态:对象里面有id值,也与session有关联
脱管态:对象里面有id值,但是与session没有关联
6.演示操作实体类对象的方法saveOrUpdate()方法
实体类对象是瞬态时,执行添加操作。实体类对象是持久态或脱管态时,执行修改操作
hibernate的一级缓存
缓存:数据存放在数据库中,数据库本身是个文件系统。如果使用流的方式操作文件,效率不高。所以把数据存放在内存里面,不使用流的方式就可以读取数据。从而提高了读取效率
hibernate缓存:
1.hibernate框架提供很多优化方式。hibernate缓存就是一种优化方式
2.hibernate缓存的特点:一级缓存和二级缓存,
a. 一级缓存是默认打开的,而且有自己的使用范围:即session范围,从session创建到session关闭
hiberntae的一级缓存中,存储的数据必须是持久态
b. 二级缓存目前不适用了,有替代技术redis。二级缓存默认不打开,二级缓存的适用范围是sessionFactory范围
验证一级缓存的存在
根据id=1查询,返回对象。重复这个步骤,又得到一个对象,第二次不会发送sql查询语句
//验证一级缓存的存在性
@Test
public void testCache() {
SessionFactory sessionFactory=HibernateUtils.getSessionFactory();
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
User user=session.get(User.class, 6);
System.out.println(user);
User user2=session.get(User.class, 6);
System.out.println(user2);
tx.commit();
session.close();
sessionFactory.close();
}
一级缓存的执行过程
hibernate一级缓存特性
特性:持久态自动更新数据库
@Test
public void fun8() {
SessionFactory sessionFactory=hibernateUtils.getSessionFactory();
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
User user=session.get(User.class,2);
user.setUsername("苏苏");
//session.update(user);持久态自动更新数据库,不需要这句
tx.commit();
session.close();
sessionFactory.close();
}
执行过程:
hibernate的事务操作
事务:如果不考虑隔离性;产生问题:脏读、不可重复度、虚读
设置事务隔离级别:mysql默认隔离级别:repeatable read
hibernate事务代码的规范写法
//事物规范代码
@Test
public void testTx() {
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
session=HibernateUtils.getSessionObject();
tx=session.beginTransaction();
User user=new User();
user.setUsername("小马");
user.setPassword("250");
user.setAddress("美国");
session.save(user);
int i=10/0;
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
session.close();
}
}
hibernate绑定session
1.session类似jdbc的connection,web阶段学过threadLocal
2.hibernate帮助与本地线程绑定session
3.如何获取与本地线程绑定的session
先在hibernate的核心配置文件中配置,再调用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-factory>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///hibernate_day02?serverTimezone=UTC</property>
<property name="connection.username">root</property>
<property name="connection.password">666666</property>
<property name="show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<mapping resource="cn/itcast/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
package cn.itcast.entity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
static SessionFactory sessionFactory;
static {
Configuration configuration=new Configuration();
configuration.configure();
sessionFactory=configuration.buildSessionFactory();
}
public static Session getSessionObject() {
return sessionFactory.getCurrentSession();
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
注:获取与本地线程绑定的session时,最后关闭session会报错。因为会随着本地线程结束而自动关闭,不需要手动关闭hibernate的API的使用
Query对象
使用query对象的死后,不写SQL语句,写的时HQL语句。二者类似,只是HQL语句操作的时实体类和它的属性
查询所有记录的语句:from实体类名
package cn.itcast.hibernatetest;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.junit.jupiter.api.Test;
import cn.itcast.entity.HibernateUtils;
import cn.itcast.entity.User;
public class HibernateQueryData {
@Test
public void testQuery() {
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
sessionFactory=HibernateUtils.getSessionFactory();
session=sessionFactory.openSession();
tx=session.beginTransaction();
Query query=session.createQuery("from User");
List<User> list=query.list();
for (User user : list) {
System.out.println(user);
}
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
session.close();
sessionFactory.close();
}
}
}
Criteria对象
使用Criteria对象不需要写查询语句,而是通过调用不同方法查询
public class HibernateQueryData {
@Test
public void testCriteria() {
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
sessionFactory=HibernateUtils.getSessionFactory();
session=sessionFactory.openSession();
tx=session.beginTransaction();
Criteria criteria=session.createCriteria(User.class);
List<User> list=criteria.list();
for (User user : list) {
System.out.println(user);
}
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
session.close();
sessionFactory.close();
}
}
SQLQuery对象
正常的情况返回的是数组组成的list集合
@Test
public void testSQLQuery() {
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
sessionFactory=HibernateUtils.getSessionFactory();
session=sessionFactory.openSession();
tx=session.beginTransaction();
SQLQuery sqlQuery=session.createSQLQuery("select * from t_user");
List<Object[]> list=sqlQuery.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
session.close();
sessionFactory.close();
}
}
可以设置成返回的list里面都是对象
@Test
public void testSQLQuery() {
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
sessionFactory=HibernateUtils.getSessionFactory();
session=sessionFactory.openSession();
tx=session.beginTransaction();
SQLQuery sqlQuery=session.createSQLQuery("select * from t_user");
sqlQuery.addEntity(User.class);
List<User> list=sqlQuery.list();
for (User user : list) {
System.out.println(user);
}
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}finally {
session.close();
sessionFactory.close();
}
}