zoukankan      html  css  js  c++  java
  • Hibernate笔记2

    hibernate实体的状态

    实体Entity有三种状态,瞬时状态,持久状态,脱管状态

    瞬时状态:transient,session 没有缓存,数据库也没有记录,oid没有值

    持久状态:persistent,session有缓存,数据库也有记录,oid有值

    脱管状态:detached,session没有缓存,数据库有记录,oid有值

    瞬时状态转持久状态

    public void test1(){
    		Configuration cfg = new Configuration().configure();
    		//创建会话工厂
    		SessionFactory factory = cfg.buildSessionFactory();
    		//获取session对象
    		Session session = factory.openSession();
    		session.getTransaction().begin();
    
    		//创建一个对象,这个对象就是瞬时状态
    		User user = new User("迪丽热巴","123");//没有id,数据库没有数据session没有缓存
    		System.out.println(user);//User [uid=0, username=迪丽热巴, password=123]
    
    		session.save(user);//经过保存后,这个对象就是持久状态,id有值,数据库有数据,session有缓存
    		System.out.println(user);//User [uid=1, username=迪丽热巴, password=123]
    
    		session.getTransaction().commit();
    		session.clear();
    	}
    

    持久状态转脱管状态

    public void test2(){
    		Configuration cfg = new Configuration().configure();
    		//创建会话工厂
    		SessionFactory factory = cfg.buildSessionFactory();
    		//获取session对象
    		Session session = factory.openSession();
    		session.getTransaction().begin();
    		//通过get方法可以获取一个持久状态对象
    		User user = (User) session.get(User.class,1);//执行select语句
    		System.out.println(user);
    		User user1 = (User) session.get(User.class,1);//不执行select语句,因为有session缓存
    		System.out.println(user1);
    		session.getTransaction().commit();
    		session.clear();
    	}
    

    img

    把持久状态转脱管状态需要使用session.clear方法

    	User user = (User) session.get(User.class,1);//执行select语句
    		System.out.println(user);
    		session.clear();//清除session
    		User user1 = (User) session.get(User.class,1);//执行select语句,因为没有session缓存
    		System.out.println(user1);
    

    执行两次select

    Hibernate: 
        select
            user0_.id as id0_0_,
            user0_.username as username0_0_,
            user0_.password as password0_0_,
            user0_.birthday as birthday0_0_ 
        from
            t_user user0_ 
        where
            user0_.id=?
    User [uid=1, username=迪丽热巴, password=123]
    Hibernate: 
        select
            user0_.id as id0_0_,
            user0_.username as username0_0_,
            user0_.password as password0_0_,
            user0_.birthday as birthday0_0_ 
        from
            t_user user0_ 
        where
            user0_.id=?
    User [uid=1, username=迪丽热巴, password=123]
    

    一级缓存,快照,一级缓存刷新

    一级缓存:又称为session级别的缓存,当获得一侧会话(session),hibernate在session中创建多个集合(Map),用于存放操作数据(PO对象),为程序优化服务,如果之后需要相应的数据,hibernate优先从session缓存中获取,如果有就使用:如果没有在查询数据库,当session关闭时,一级缓存销毁

    快照:与一级缓存一样的存放位置,对一级缓存数据备份,保证数据库的数据与一级缓存的数据必须一致。如果一级缓存修改了,在执行commit提交时,将自动刷新一级缓存,执行update语句,将一级缓存的数据更新到数据库

    使用HQL会对数据进行一级缓存,使用SQL不会对数据进行缓存

    Query query = session.createQuery("from User");//HQL对数据进行一级缓存
    		List<User> list = query.list();
    		User user = (User)session.get(User.class,1);//有缓存,不用执行select语句,就能获取数据
    

    save和persist方法区别

    save方法:瞬时态 转换 持久化 会初始化OID

    执行save方法前,设置OID将忽略

    如果执行查询,session缓存移除了,在执行save方法,将会执行insert

    public void test1(){
    		Configuration cfg = new Configuration().configure();
    		SessionFactory factory = cfg.buildSessionFactory();
    		Session session = factory.openSession();
    		session.getTransaction().begin();
    		User user = new User("迪丽热巴","123");
    		user.setUid(13);
    		System.out.println(user);//[uid=13, username=迪丽热巴, password=123]
    		//执行save方法前,设置的OID将会忽略,
    		session.save(user);//瞬时态转持久态,执行save方法会立即出发insert语句,从数据库获取主键的值
    		System.out.println(user);//User [uid=1, username=迪丽热巴, password=123]
    
    		//执行session.clear,将会把缓存移除,再次执行save方法,将会执行insert,sql语句
    		session.clear();
    		session.save(user);//再次保存,id会自动增长
    		System.out.println(user);//[uid=2, username=迪丽热巴, password=123]
    		session.getTransaction().commit();//当事务提交时会自动自行update语句
    		session.clear();
    	}
    
    

    persist方法:瞬时态,转换持久态

    persist保存的对象,在保存前,不能设置id,否则会报错

    save和persist都是持久化对象的作用

    save因为需要返回一个主键值,因此会立即执行Insert语句,

    而persist在事务外部调用是则不会立即执行insert语句

    在事务内部调用还是会立即执行insert语句的

    public void test1(){
    		Configuration cfg = new Configuration().configure();
    		SessionFactory factory = cfg.buildSessionFactory();
    		Session session = factory.openSession();
    		session.getTransaction().begin();
    		User user = new User("古娜力扎","123");
    		//user.setUid(30);persist保存的对象,在保存前,不能设置id,否则会报错
    		session.persist(user);//该方法在事务外不会执行insert sql语句
    		session.getTransaction().commit();//当事务提交时会自动自行update语句
    		session.clear();
    	}
    

    一对多实体类和映射文件

    多表关系

    多对多:比如老师对应多个学生,学生对应多个老师,有中间表的关系

    一对多:一个客户对应多个订单,表之间有主表和从表,之间的关系(主外键关系)

    一个客户对应多个订单

    img

    客户与订单文件的映射

    	<!--
    		 描述一对多的关系
    		 key中column写的是外键名称
    		 one-to-many:一对多,里面写的class,写多的一方
    		-->
    		<set name="orders">
    			<key column="customer_id"></key>
    			<one-to-many class="domain.Order"></one-to-many>
    		</set>
    
    <!--描述customer的关系
    		class写一的一方
    		column:写外键
    		-->
    		<many-to-one name="customer" class="domain.Customer" column="customer_id"/>
    
  • 相关阅读:
    05--STL序列容器(List和Forward_list)
    04--STL序列容器(Stack和Queue)
    03--STL序列容器(Deque)
    STL迭代器iterator
    02--STL序列容器(Vector)
    C++回顾day03---<string字符串操作>
    C++回顾day03---<输入输出流>
    C++回顾day03---<异常>
    16位结构的CPU,8086给出物理地址的方法
    初识STM32固件库
  • 原文地址:https://www.cnblogs.com/train99999/p/11173441.html
Copyright © 2011-2022 走看看