• 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"/>
    
  • 相关阅读:
    HTML5结构
    HTML5新增的非主体元素header元素、footer元素、hgroup元素、adress元素
    CF GYM 100703G Game of numbers
    CF GYM 100703I Endeavor for perfection
    CF GYM 100703K Word order
    CF GYM 100703L Many questions
    CF GYM 100703M It's complicate
    HDU 5313 Bipartite Graph
    CF 560e Gerald and Giant Chess
    POJ 2479 Maximum sum
  • 原文地址:https://www.cnblogs.com/train99999/p/11173441.html
Copyright © 2020-2023  润新知