Hibernate详解(一)---Hibernate的实现和常用对象

1、Hibernate是一个面向对象的持久化框架

  • 持久化

    1、把内存中的Java对象保存到存储设备上面;
    2、最好的解决方案:把对象持久化到数据库里面;
    3、在Java里面,把对象持久化到数据库只能使用JDBC

  • 框架
    1、框架是一个半成品,是一个脚手架,它可以方便的,快速的辅助开发人员针对某一领域进行快速开发;
    2、使用框架,提高开发效率,减少重复代码,提高应用安全性,减少应用的bug;
    3、框架一定是按照开发人员告诉他的方式去运行,交流的工具就是框架的配置文件或者约定;

  • 面向对象

    一个面向对象的持久化框架,在代码当中一定不可能出现关系的概念;

2、hibernate的使用

2.1、hibernate环境搭建

1、把Hibernate运行所需的jar包放到classpath中;
2、把mysql驱动放到classpath中;
Hibernate详解(一)---Hibernate的实现和常用对象_第1张图片

2.2、hibernate的配置文件:

:session-factory:暂时理解为一个DataSource;
:配置session-factory相关信息:
1、连接信息
connection.driver_class:驱动
connection.url:url
connection.username:用户名
connection.password:密码

2、其他信息
dialect:数据库方言:方言在告诉hibernate我现在使用的是什么数据库,你需要生成什么样的SQL
show_sql:显示hibernate执行的SQL;
:引入对象的映射文件;

<session-factory>
    <property name="hibernate.connection.driv-class">com.mysql.jdbc.Driverproperty>
    <property name="connection.url">jdbc:mysql:///hibernate2property>
    <property name="connection.username">rootproperty>
    <property name="connection.password">adminproperty>
    <property name="show_sql">trueproperty>
    <property name="dialect">org.hibernate.dialect.MySQLDialectproperty>
    <mapping resource="com/it520/hello/Employee.hbm.xml"/>
session-factory>
	

2.3、hibernate的对象映射文件:

1、映射文件一般起名:类名.hbm.xml;一般放在对应的类型同一个包中;
2、hibernate-mapping.package:包名,
3、class:配置一个类型的映射

  • name:类型的名称;
  • table:该类型对应的表名;

4、id:配置主键

  • name:在类型中哪个属性作为主键;
  • column:在表中,哪个列作为主键;
  • generator:配置主键的生成策略;告诉hibernate怎么去处理我们的主键,不同的主键生成策略对应着不同的SQL和不同的主键处理方式;

5、property:配置属性映射

  • name:属性的名称;
  • column:属性对应列的名称;
<hibernate-mapping package="com.it520.hello">
<class name="Employee" table="employee">
    <id name="id" column="id" >
    <generator class="native">generator>
    id>
    <property name="name" column="name">property>
    <property name="hiredate" column="hiredate">property>
    <property name="age" column="age">property>
class>
hibernate-mapping>

2.4、创建工具类

工具类一般都是采用单例模式,工具类的作用就是用来获取session,Hibernate的session是用来完成持久化的,且session是线程不安全的,通过单例模式能够保证每次拿到的是一个全新的session。

public class HibernateUtil {
    private static final HibernateUtil instance = new HibernateUtil();
    private SessionFactory sessionFactory;
    private HibernateUtil() {//私有化构造器
        Configuration configure = new Configuration().configure();
         sessionFactory = configure.buildSessionFactory();//方法已过期,但还是使用很频繁
    }
    public static HibernateUtil getinstance() {//向外暴露一个公共的静态方法,让其他对象能够通过类名访问这个方法
        return instance;
    }
    public SessionFactory getsessionFactory() {//创建sessionFactory
        return sessionFactory;
    }
    public Session getSession() {//创建Session
        return sessionFactory.openSession();
    }
}

2.5、创建需要持久化对象及DAO接口

//Employee对象
public class Employee {
    private Long id ;
    private String name;
    private Integer age;
    private Date hiredate;
    //getter,setter,tostring方法
} 
public interface IEmployeeDAO {
	void save(Employee e);//保存
	Employee get(Long id);//获取一个对象
	void update(Employee e);//更新
	void delete(Long id);//删除
	List<Employee> list();//获取对象集合
}

2.6、编写DAO实习类

public class EmployeeDAOImpl implements IEmployeeDAO {
    Transaction tx = null;
    Session session = null;
    @Override
    public void save(Employee e) {
     try {
         session = HibernateUtil.getinstance().getSession();//获取session
         tx = session.beginTransaction();//开启事务
         session.save(e);//保存对象
         tx.commit();//提交事务
     }catch (Exception e1) {
         e1.printStackTrace();
         if(session!=null&&tx.isActive()) {
         tx.rollback();//事务回滚,事务后续会再详细说明,这个例子后面的几个方法就没有完整的写
         System.out.println(" tx.rollback()");}
     }finally {
         session.close();
     }
    }   
    @Override
    public Employee get(Long id) {
        session = HibernateUtil.getinstance().getSession();
        Employee e =(Employee) session.get(Employee.class, id);
        session.close();
        return e;
    }
    @Override
    public void delete(Employee e) {
        session = HibernateUtil.getinstance().getSession();
        tx = session.beginTransaction();
        session.delete(e);
        tx.commit();
        session.close();
    }
    @Override
    public void update(Employee newe) {
       session = HibernateUtil.getinstance().getSession();
       tx = session.beginTransaction();
       session.update(newe);
       tx.commit();
       session.close();
    }
    @Override
    public List<Employee> list() {
        String sql = "select e from Employee e";
        session= HibernateUtil.getinstance().getSession();
        Query query = session.createQuery(sql);
        List<Employee> list = query.list();
        return list;
    }

}

2.7、测试类

public class EmployeeTest {
   private IEmployeeDAO dao ;
    public EmployeeTest() {
    dao = new EmployeeDAOImpl();
}
    @Test
    public void testsave() {
        Employee e = new Employee();
        e.setAge(2);
        e.setHiredate(new Date());
        e.setName("xiaohu");
        dao.save(e);
    }
//    @Test
    public void testGet() {
        Employee e = dao.get(1L);
        System.out.println(e);
        
    }
//    @Test
     public void testDelete() {
        Employee e = dao.get(1L);
         dao.delete(e);
     }
//    @Test
    public void testUpdate() {
        Employee e = dao.get(4L);
        e.setName("update");
        dao.update(e);
    }
//    @Test
    public void testList() {
        List<Employee> list = dao.list();
        System.out.println(list);
    }
}

3、hibernate主要对象

3.1、Configuration;

主要用来加载配置,解析配置通过Configuration对象获取SessionFactory对象;

1、Configuration对象提供了很多额外的通过API配置hibernate的方式;

2、buildSessionFactory虽然已经过期了,但是仍然是使用最广泛的得到sessionfactory的方法(大家平时就用这个)

3、新的sessionFactory方法:

sessionFactory =cfg.buildSessionFactory(new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry());

3.2、sessionFactory:

sessionFactory是一个线程安全的对象,所以,一般一个应用针对一个数据源只需要一个sessionfactory对象就可以了;

sessionFactory是用来创建session对象的;

openSession:开启一个全新的Session;

  • 全新的Connection对象;
  • 全新的事务

3.3、Session对象

session对象提供了对象持久化的各种方法:

1、beginTransaction:开启一个事务;

2、save(object):保存一个对象;

3、get(Class,Serializable):根据主键加载一个指定类型的对象实例;

4、update(object):修改一个对象,要求对象需要有id等值;

5、delete(object):删除一个对象,要求对象必须有id;

6、createQuery(String hql):创建一个查询对象;

7、close():关闭一个session;

8、session的生命周期有多长?session是线程不安全的,所以session的生命周期最长为一个线程

9、saveOrUpdate:保存没有id的对象,修改有id的对象;

10、load:load方法和get一样,也能够查询指定id的对象;load方法把真正执行select延后到了使用这个对象的时候,我们叫做延迟加载,后续会对延迟做一个详细介绍。

3.4、Transaction对象:

对事务的一个封装,事务的提交或者回滚由这个对象管理;

session.getTransaction:得到当前会话上绑定的事务对象;

session.beginTransaction:在标记当前session的事务正常开始了;

transaction.isActive:判断当前事务是否是活动的;

session.isOpen:判断当前session处于打开状态;

transaction.commit:提交事务

transaction.rollback:回滚事务

public class EmployeeDAOImpl implements IEmployeeDAO {
    Transaction tx = null;
    Session session = null;
    @Override
    public void save(Employee e) {
     try {
         session = HibernateUtil.getinstance().getSession();
         tx = session.beginTransaction();//开启事务
         session.save(e);
         tx.commit();//提交事务
     }catch (Exception e1) {
         e1.printStackTrace();
         if(session!=null&&tx.isActive()) {//判断session是否为空,事务是否活动的
         tx.rollback();//事务回滚
         System.out.println(" tx.rollback()");}
     }finally {
         session.close();
     }
    } 

3.5、一级缓存

在Session对象上面有一个缓存;这个缓存在hibernate里面叫做一级缓存;

一级缓存能够保证:

1、在一个session中拿到的多个相同类型,相同id的对象实例是同一个实例;

2、一级缓存的生命周期?和session相同;在web应用中,一级缓存的生命周期一次请求;

3、一级缓存能够提高一定的性能,但是非常有限;

4、一级缓存提供了对该session加载出来的对象的一个管理的区域;(session加载出来的对象都放在一级缓存里面进行管理)

5、sessionFactory.openSession还代表开启一个全新的一级缓存空间;

6、session.clear方法:清空一级缓存所有对象;

7、session.evict(object)方法:从一级缓存中去掉一个指定的对象;

 @Test
    public void test() {
        Employee employee1 = dao.get(10L);
        Employee employee2 = dao.get(10L);
        System.out.println(employee1==employee2);//true
    }
}

@Test
    public void test1() {
        Employee employee1 = dao.get(10L);
       HibernateUtil.getinstance().getsessionFactory().openSession();
        Employee employee2 = dao.get(10L);
        System.out.println(employee1==employee2);//false
    }

4、hibernate单对象映射细节

1、在一个映射文件中可以写多个实体的映射;但是必须在同一个包内;一般在开发中,还是一个实例对应一个映射文件;
2、table和column属性都是可以省略的,

  • 如果省略table,就会使用类名作为表名;(注意大小写敏感问题);
  • 如果省略column,就会使用属性名称作为列名;

3、id和property的name属性代表的是对象中的属性:

  • hibernate什么时候用getter;getter方法返回的值就是要存到数据库中的值;
  • hibernate什么时候用setter;setter方法传入的参数值,就是数据库中的值;

4、hibernate不关心getter和setter方法的可见性;

5、property和id上可以通过access属性来设置访问的方式,默认是property,可以设置为field,代表直接使用字段访问;
6、type属性用于配置java类型到列类型的映射;

7、在属性上面添加Insert=false,那么这个属性永远不会出现在insert语句中;

8、在属性上面添加update=false,那么这个属性永远不会出现在update语句中;

9、在class上面添加dynamic-insert=true,那么在insert的时候,只会insert这个类上不为空的属性;

5、hibernate表的自动生成

5.1、#hibernate.hbm2ddl.auto create-drop

在hibernate启动的时候,创建表,在hibernate正常关闭的时候删除表;

​ 1,删除那些表?创建那些表:hibernate只会去删除/创建这次让他管理的对象对应的表;

​ 2,如果新加一个domain会怎么处理:重新创建;

​ 3,如果删除一个domain会怎么处理:不管

​ 4,一定要正常关闭SessionFactory(正常的关闭hibernate),

使用:一般不会使用create-drop;

5.2、#hibernate.hbm2ddl.auto create

在hibernate启动的时候,创建表;

​ 1,删除那些表?hibernate只会去删除/创建这次让他管理的对象对应的表;

​ 2,如果新加一个domain会怎么处理:重新创建

​ 3,如果删除一个domain会怎么处理:不管

使用:

  • 一般我们程序员在做白盒测试的时候,会使用create;(每次测试的主键都是从1 开始)

  • 在测试的时候,注意使用@Before标签

5.3、#hibernate.hbm2ddl.auto update

在hibernate启动的时候,去检查并修改表结构;

​1,检查并修改那些表?这次让hibernate管理的对象对应的表;

​2,如果表已经存在,怎么处理?检查这个表,如果有变化,尝试做适当的修改;

​3,如果表不存在,怎么处理:创建表;

​4,如果对象的结构有变化,怎么更新
添加一个属性:在表里面增加一列;
删除一个属性:不管;
修改一个属性:尝试去修改这个列的类型;如果修改不成功,hibernate会在启动的时候给一个警告;
使用:

  • 一般在黑盒测试的时候使用update;
  • 注意,一定不要在生产环境中使用update;

5.4、#hibernate.hbm2ddl.auto validate

在hibernate启动的时候,去检查表结构;

如果检查发现表结构不对,怎么处理;hibernate不能正常启动;

在生产环境一般使用validate去检查数据库版本和代码版本是否一致;

5.5、#hibernate.hbm2ddl.auto none

就是什么都不管;

你可能感兴趣的:(框架,Hibernate,hibernate,mysql,java)