hibernate核心API和级联的增删改查(CRUD)

简单介绍API

  1. delete
    hibernate的删除操作,一定要有id才能删除。
    可以从persistent——>transient
    也可以detached——->transient
  2. load
    这是个特别的方法,延迟加载就是基于这一原理,load方法调用后,会先从一级缓存中查找,如果没有从数据库查找,但是不是立马发送sql语句,返回的是代理对象。而是在使用的过程中才会发送sql语句。如果在使用的时候session已经关闭,那么就会有异常
    问题:
    每次查询都会查询所有的字段。建议使用sql或者hql
  3. get
    立马向数据库发送sql语句,返回的就是对象本身,而非代理
    问题:
    每次查询都会查询所有的字段。建议使用sql或者hql
  4. update
    更新transient对象,就会报错,意思只能根据id来更新
    4.1即使你只更新一个字段,但是数据默认也是更新所有字段
    • 使用hql或者原生sql
    • @column(updatable=false)在某一个字段上,这个字段就参加更新了,这种方式十分不灵活
    • XML配置文件上dynamic-update,只有修改才会更改,比较session缓存里面的和数据库立马的,如果你更新一个detached对象,就没有比较了,还是都会更新
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);//比如这个更新,因为session缓存里面没有了,所以还是更新所有字段
        session2.getTransaction().commit();
      - 使用merge
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();

5.saveOrupdate
没id就save,有就update

6.clear
清除session缓存

7.flush
让session缓存和数据库里面进行同步
commit默认就会flush
了解 flushMode

级联的增删改查

  1. save
    street类
package com.hfview.bean;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Cascade;

@Entity
public class Street {
    private int id;
    private String name;
    private City city;

    @ManyToOne()//注意Cascade ={cascade=CascadeType.PERSIST} 对save并不其效果
    @JoinColumn(name="cityId")
    @Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE})
    public City getCity() { 
        return city;
    }

    public void setCity(City city) {
        this.city = city;
    }

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

street类

package com.hfview.bean;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.hibernate.annotations.Cascade;

@Entity
public class City {
    private int id;
    private String name;
    private Set street =new HashSet();

    @OneToMany(mappedBy="city")
    @Cascade(value=org.hibernate.annotations.CascadeType.SAVE_UPDATE)
    public Set getStreet() {
        return street;
    }

    public void setStreet(Set street) {
        this.street = street;
    }

    @Id@GeneratedValue
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

测试类1

@Test
    public void saveRelation() {
        City city = new City();
        Street street = new Street();
        street.setName("aa");
        city.setName("bb");
        street.setCity(city);
        Session session = sf.getCurrentSession();
        session.beginTransaction();
        session.save(street);
        session.getTransaction().commit();
    }

如果设置了@Cascade(value = {org.hibernate.annotations.CascadeType.SAVE_UPDATE}),那么在存street的过程总也会把city存储了

测试类2

@Test
    public void saveRelation2() {
        City city = new City();
        Street street = new Street();
        street.setName("aa");
        city.setName("bb");
        street.setCity(city);
        city.getStreet().add(street);

        Session session = sf.getCurrentSession();
        session.beginTransaction();
        session.save(city);
        session.getTransaction().commit();
    }

在存一的那一方的时候,必须在集合里面存储好多的那一方(city.getStreet().add(street)),而且如果想在多的那一方对应一的那个外键有值,还要设置导向(street.setCity(city))

  1. update
    和save类似
    比如get一个对象,更改这个对象的属性会发出sql语句
    如果更改想关联的对象的属性(然后设置了cascade为CascadeType.SAVE_UPDATE)那么也会更新

  2. get、load
    这里主要住如果想取一个对象的像关联对象,那么通过设置fetch
    fetch=FetchType.EAGER:一定会取相关联的对象
    fetch=FetchType.LAZY:默认是不取相关联对象,但是你如果在session关闭前调用这个关系对象 还是会向数据库发送sql语句来获取,如果在session关闭后,再去相关联对象就会报错

  3. delete
    删除也没意思,就是级联删除
    如果不想级联 就打破关系就行,其实这都不要用用hql或者sql最好

你可能感兴趣的:(hibernate学习)