Hibernate学习笔记2.5(Hibernate核心开发接口和三种状态)

1.configuration(配置信息管理,产生sessionfactory)

 

sessionfactory管理一系列的连接池

opensession 永远打开新的,需要手动close

getcurrentsession如果当前环境有,就会用已经存在的,没有就创建新的

一旦提交就没了

getcurrentsession主要用于界定事务边界,事务提交自动close

上下文:在hibernate.cfg.xml里面改   currentsession_context_class

thread:线程  当前线程有没有一个对象,没有就创建i新的,使用connection

jta: 分布式事务 ,Java tarsaction api多数由中间键服务器提供 Tomcat不具备该能力

manager:手动管理事务

custormclass:自己定义

 如果使用getcurrentsession必须设定上下文环境

geucurrentsession和sessionopen拿到的类 具体实现可能不一样 因此一般情况下 不建议混用

 如果址用hibernate 就要写trycatch

用spring的话就不用写try catch

save();设定一个主键,id

首先搞懂三种状态

三种状态

transient   :内存中的一个对象 缓存中没有对应的id和value

Persistent:内存中有 缓存中有 数据库有 有id

Datached: 内存有 缓存没有 数据库有 有id

save方法即是把transient转化为Persisitence

delete方法

Load 

    @Test
    public void testLoad() {
    
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t = (Teacher)session.load(Teacher.class, 1);
        
        session.getTransaction().commit();
        System.out.println(t.getClass());
        //System.out.println(t.getName());
    }

1,自动打包为intege 实现了序列化接口

get

@Test
    public void testGet() {
    
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t = (Teacher)session.get(Teacher.class, 1);
        
        session.getTransaction().commit();
        System.out.println(t.getClass());
        //System.out.println(t.getName());
    }
    

用load拿出东西的时候才会发出sql语句,不存在对应记录不拿东西不会报错,返回代理对象()

用get拿出对象的时候是直接在数据库加载,不存在对应记录不拿东西也会报错

 update

第一种 有detach到persistence 同时数据库更新

    @Test
    public void testUpdate1() {
    
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t = (Teacher)session.get(Teacher.class, 1);
        
        session.getTransaction().commit();
        
        t.setName("zhanglaoshi");
        
        Session session2 = sessionFactory.getCurrentSession();
        session2.beginTransaction();
        session2.update(t);
        
        session2.getTransaction().commit();
    }

更新trasent会报错

如果transent设置id数据库并且存在

数据库得有对应的记录

@Test
    public void testUpdate2() {
        
        
        Teacher t = new Teacher();
        t.setName("zhanglaoshi");
        
        Session session2 = sessionFactory.getCurrentSession();
        session2.beginTransaction();
        session2.update(t);
        
        session2.getTransaction().commit();
    }
    

如果有一个字段特别长 全改就会变低

Load的时候自动会检查缓存是否与数据库一致 如果不一致 就会发update语句 ,所有字段均会更新,如果相同,不会更改

@Test
    public void testUpdate4() {
        
        
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t = (Teacher)session.get(Teacher.class, 1);
        t.setName("zhangsan2");
        session.getTransaction().commit();
    }

想要只更改一条想要更改的内容

1.加注解(很少用 不够灵活)

anntation

    @Column(updatable = false)
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }

 xml:

property属性 update 设置true或者false

2.在xml配置文件上写

<hibernate-mapping>
    <class name="com.bjsxt.hibernate.Student" dynamic-update="true">

设置之后在同一个session之后就只更新只更改改的那一部分

跨session的话

@Test
    public void testUpdate5() {
        
        
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Student s = (Student)session.get(Student.class, 1);
        s.setName("zhangsan5");
        session.getTransaction().commit();
        
        s.setName("z4");
        
        Session session2 = sessionFactory.getCurrentSession();
        session2.beginTransaction();
        session2.update(s);
        session2.getTransaction().commit();
    }

他会全部发送,全部更改

如果想要跨session,可以使用merge方法

    @Test
    public void testUpdate6() {
        
        
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Student s = (Student)session.get(Student.class, 1);
        s.setName("zhangsan6");
        session.getTransaction().commit();
        
        s.setName("z4");
        
        Session session2 = sessionFactory.getCurrentSession();
        session2.beginTransaction();
        session2.merge(s);
        session2.getTransaction().commit();
    }

在update之前会先搜索一下 比较是否相同

3.使用hql语句

@Test
    public void testUpdate7() {
        
        
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Query q = session.createQuery("update Student s set s.name='z5' where s.id = 1");
        q.executeUpdate();
        session.getTransaction().commit();
        
    }

 Save or update

    @Test
    public void testSaveOrUpdate() {
        
        
        Teacher t = new Teacher();
        t.setName("t1");
        t.setTitle("middle");
        t.setBirthDate(new Date());
        
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        session.saveOrUpdate(t);
        
        session.getTransaction().commit();
        
        t.setName("t2");
        
        Session session2 = sessionFactory.getCurrentSession();
        session2.beginTransaction();
        session2.saveOrUpdate(t);
        session2.getTransaction().commit();
        
    }
    

没id就save 有id就update

Clear方法

@Test
    public void testClear() {
    
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t = (Teacher)session.load(Teacher.class, 1);
        System.out.println(t.getName());   //first
        
        session.clear();
        
        Teacher t2 = (Teacher)session.load(Teacher.class, 1);   //second
        System.out.println(t2.getName());
        session.getTransaction().commit();

clear用于清除缓存,load和get方法都会先查找缓存,有的话就不会发sql语句

Flush

    @Test
    public void testFlush() {
    
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t = (Teacher)session.load(Teacher.class, 1);
        t.setName("tttt");
        

        
        t.setName("ttttt");
        
    
        session.getTransaction().commit();
        
        
    }

如果不加flush的话 他永远只取一次,取最后的

@Test
    public void testFlush() {
    
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Teacher t = (Teacher)session.load(Teacher.class, 1);
        t.setName("tttt");
        
        
        session.flush();
        
        t.setName("ttttt");
        
    
        session.getTransaction().commit();
        
        
    }

加了flush之后可以强制缓存的内容与数据库的内容做同步

commit方法默认执行flush

在什么时间执行flush由flushmode控制

在前面设置 session.setFlushMode(FlushMode.xxxx)

find方法很老 现在也不怎么用了

SkemaExport

@Test
    public void testSchemaExport() {
        new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
    }

 控制建表语句

原文地址:https://www.cnblogs.com/frankzone/p/9445167.html