Hibernate学习笔记2;相关概念和api(二)

这是黑马视频的学习笔记

  • 实体类编写规则

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();
		}
 }

猜你喜欢

转载自blog.csdn.net/shanshuisheng/article/details/80974077