Hibernate基本使用

MVC和分层架构

  1. 持久层的设计理念 - DAO = Data Accessor + Active Domain Object
  2. 业务层的设计理念 - 事务脚本模式(事务的边界在业务层)
  3. 表示层的架构理念 - MVC架构模式 - 通过控制器(C)实现模型(M)和视图(V)的解耦合

ORM是什么

  1. ORM映射:Object Relational Mapping(对象关系映射)
  • O:面向对象领域的 Object(JavaBean 对象)
  • R:关系数据库领域的 Relational(表的结构)
  • M:映射 Mapping(XML 的配置文件)
  1. 如果使用关系型数据库作为持久化方案,那么ORM框架可以帮助我们完成从对象模型到关系模型的双向转换,从而避免繁琐的JDBC模板代码和编写SQL语句
  2. 最主流的ORM框架是Hibernate和MyBatis
    什么时候使用Hibernate - 对应用和数据库设计有完全控制权,不熟悉SQL
    什么时候使用MyBatis - 需要高度优化的SQL或存储过程
  3. 简单一句话:Hibernate 使程序员通过操作对象的方式来操作数据库表记录

Hibernate简介

  1. Hibernate 是一个开放源代码的对象关系映射(ORM)框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。
  2. Hibernate 可以应用在任何使用 JDBC 的场合,既可以在 Java 的客户端程序使用,也可以在 Servlet/JSP 的 Web 应用中使用。
  3. Hibernate 是轻量级 JavaEE 应用的持久层解决方案,是一个关系数据库ORM框架

Hibernate的使用步骤

  1. 封装业务实体
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String username;
    private String password;
    private String email;
    private Boolean gender;//不使用基本类型
    private String tel;
        //getter和setter方法
}

在对象关系映射的框架中不要使用基本类型,应该使用包装类型,因为,包装类型的默认值为null,而数据库中的字段为空值时也是null,两两对应。
基本数据类型对应的包装类:int--Interger byte--Byte short--Short long--Long float--Float double--Double char--Character boolean--Boolean

  1. 对象关系映射(注解/XML)
//POJO = Plain Ordinary Java Object
//PO = Persistence Object
//POJO + 映射文件/注解 ->PO
@Entity//注解声明该类是Hibernate的持久化类
@Table(name = "t_user")//指定该类映射的表
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id//指定该类的标识属性
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    //GeneratedValue(generator = "gen")
    //GenericGenerator(name = "gen",strategy = "uuid")
    @Column(name="userid")
    private Integer id;
    @Column(unique = true,nullable = false,length = 20)
    private String username;
    @Column(name="userpass")
    private String password;
    private String email;
    private Boolean gender;//不使用基本类型
    @Transient
    private String tel;
        //getter和setter方法
}

@Entity:被该注解修饰的POJO就是一个实体。使用该注解可以指定一个name属性,name属性指定该实体类的名称,但大部分无须指定该属性,因为系统默认以该类的类名称作为实体类的名称
@Table:该注解指定持久化类所映射的表,一般需要指定name属性,即所映射的表名
@id:指定该类的标识属性。
通常情况下,Hibernate建议为持久化类定义一个标识属性,用于唯一标识某个持久化实例,映射为数据表的主键,如果希望Hibernate自动生成主键值,使用下面这个注解
@GeneratedValue:属于JPA的注解,支持的属性有:

  • strategy:指定主键的生成策略,该属性支持如下4个属性
    • GenerationType.AUTO:自动选择最适合底层数据库的书剑生成策略(不推荐使用,在某些情况下会出错)
    • GenerationType.IDENTITY:对于MySQL、SQL Server这样的数据库,选择自增长的主键生成策略
    • GenerationType.SEQUENCE:对于Oracle这样的数据库,选择使用基于Sequence的主键生成策略
    • GenerationType.TABLE:使用辅助表来生成主键
  • 如果需要使用Hibernate提供的主键生成策略还需要结合下面这个属性

@GenericGenerator:支持的属性

  • name:必须属性,设置该主键生成器的名称,设置后可在GenerratedValue中指定generator生成器值为该name值,即可使用该主键生成器
  • strategy:必须属性。设置该主键生成器的生成策略
    • increment:为long、short、int类型主键生成唯一标识,只有在没有其他进程往同一个表中插入数据才能使用,在集群下不要使用
    • identity:给提供自增长主键支持的数据表中适用
    • sequence:给提供Sequence支持的数据表中适用
    • hilo:使用一个高/低位算法高效的生成long、short、int型的标识符
    • seqhilo:同上,指定条件有所不同
    • uuid:使用UUID算法生成字符串类型的标识符

@Column:通过该注解可以指定类中的属性所映射的字段的名称,字段长度,唯一约束等等,但是,在实际开发中,都是先创建数据库表再创建持久化类,所以,一般指定列名就可以
@Transient:在默认情况下,持久化类的所有属性会自动映射到数据表的数据列,如果不想持久化的属性,则使用该注解来修饰

  1. Hibernate配置文件
    默认加载的配置文件hibernate.cfg.xml

    
        
        com.mysql.jdbc.Driver
        jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8
        root
        123456

        
        
        
        
        
        org.hibernate.dialect.MySQL5InnoDBDialect
        
        

        
        
        
        thread

        
        true
        true

        
        
    

  1. 核心API的使用
    编写测试类
public class AppTest{
    
    private static SessionFactory sessionFactory;
    
    private Session session;
    
    @BeforeClass  //在所有的测试方法执行之前只执行一次得方法
    public static void setUpBeforeClass(){
        sessionFactory = new Configuration().configure().buildSessionFactory();
    }
    
    @AfterClass  //在所有的测试方法执行结束后只执行一次得方法
    public static void tearDownAfterClass(){
        sessionFactory.close();
    }
    
    @Before //每个测试方法执行之前都要先执行的方法
    public void foo(){
        session = sessionFactory.getCurrentSession();
        session.beginTransaction();
    }
    
    @After //每个测试方法执行之后都要执行该方法
    public void bar(){
        session.getTransaction().commit();
        session.close();
    }
    @Test
    public void testSave(){
        User user = new User();
        user.setUsername("陈其");
        user.setPassword("741852");
        user.setGender(false);
        user.setEmail("[email protected]");
        Assert.assertNotNull(session.save(user));
    }
    @Test
    public void testGet(){
        User user = session.get(User.class, "陈其");
        Assert.assertEquals("陈其", user.getUsername());
        Assert.assertEquals("[email protected]", user.getEmail());
        Assert.assertEquals("741852", user.getPassword());
        Assert.assertEquals(false, user.getGender());
    }
}

Configuration:每个Hibernate的配置文件对应一个Configuration对象,new Configuration().configure()负责加载hibernate.cfg.xml文件
SessionFactory:new Configuration().configure().buildSessionFactory()该方法产生一个不可变的SessionFactory对象,该对象很消耗资源,所以一般一个数据库对应一个SessionFactory
Session:通过SessionFactory对象.openSessioon(),或许.getCurrentSession()可以得到一个Session实例,推荐使用getCurrentSession,1.因为getCurrentSession创建的session会和绑定到当前线程,而openSession不会。2.getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭。

这里getCurrentSession本地事务(本地事务:jdbc)时要在配置文件里进行如下设置:
thread

Session对象的几个重要方法:

  • 持久化对象状态的方法
    • save:将对象转化为持久化状态,该对象的属性将被保存到数据库,该方法需要立即返回持久化对象的标识属性值,所以执行save方法时立即将持久化对象对应的数据插入数据库
    • persist:将对象转化为持久化状态,该对象的属性将被保存到数据库
      与save方法的区别是,当它在一个事务外部被调用时,并不立即转换成insert语句。这个功能很有用,尤其是需要封装长会话流程时。
  • 根据主键加载持久化实体
    • get():根据主键加载持久化实例,但get()方法会立刻访问数据库,如果没有记录返回null
    • load():根据主键加载持久化实例,如果没有匹配到数据库记录,load()方法抛出HibernateException异常,如果在持久化注解中指定了延迟加载,则load方法会返回一个未初始化的代理对象(持久化对象的替身),这个代理对象并没有加载数据记录,直到程序去调用该代理对象的某个方法是,Hibernate才会去访问数据库(如果希望在某个对象中创建一个指向另一个对象的关联,又不想在数据库中装载该对象的同时立即装载相关联的全部对象,延迟加载方式就非常有用了)
  • 更新持久化实体
    Hibernate中对象有三种状态:1.瞬时态(刚创建的对象,尚未与Session关联,不会持久化到数据库,也不会被赋予持久化标识,有机会被垃圾回收)2.持久态(对象在数据库中有对应的记录,并拥有持久化标识,与Session关联,对象状态的改变会被写回数据库,无法垃圾回收)3.游离态(曾经处于持久态,但是因为Session关闭或者对象从Session中移除变成与Session失去关联,有机会被垃圾回收)
    • 更新处于持久化状态的对象时,直接调用该对象的属性set方法即可更新数据库,Hibernate会自动发出数据库更新语句
    • 更新一个游离态的对象时通过update()、updateOrSave()方法来保存这些修改,使用这两个方法后对象由游离态再次回到持久态
  • 删除持久化实体
    • 通过delete()方法来删除持久化实例,对象从持久态变为瞬时态(删除态)

你可能感兴趣的:(Hibernate基本使用)