大家好,我是酱油君。这是互联网技术岗的分享专题,废话少说,进入正题:
对象-关系映射(Object-Relational Mapping,简称ORM),面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。
在application.properties配置如下代码:
1spring.jpa.properties.hibernate.show_sql=true //控制台是否打印
2spring.jpa.properties.hibernate.format_sql=true //格式化sql语句
3spring.jpa.properties.hibernate.use_sql_comments=true //指出是什么操作生成了该语句
HQL查询、SQL查询、QBC条件查询
HQL的具体分类:1、 属性查询;2、 参数查询、命名参数查询;3、 关联查询;4、 分页查询;5、 统计函数。
HQL和SQL的区别:HQL是面向对象查询操作的,SQL是结构化查询语言 是面向数据库表结构的
代码举例:
x1//HQL: Hibernate Query Language. 面向对象的写法:
2Query query = session.createQuery("from Students where name = ?");
3query.setParameter(0, "酱油君");
4Query.list();
5
6//QBC: Query By Criteria.(条件查询)
7Criteria criteria = session.createCriteria(Student.class);
8criteria.add(Restrictions.eq("name", "酱油君"));
9List<Student> list = criteria.list();
10
11//SQL:
12SQLQuery query = session.createSQLQuery("select * from Students");
13query.addEntity(Student.class);
14List<Student> list = query.list();
可以将Hibernate的实体类定义为final类,但这种做法并不好。
因为Hibernate会使用代理模式在延迟关联的情况下提高性能,如果你把实体类定义成final类之后,因为 Java不允许对final类进行扩展,所以Hibernate就无法再使用代理了,如此一来就限制了使用可以提升性能的手段。不过,如果你的持久化类实现了一个接口而且在该接口中声明了所有定义于实体类中的所有public的方法轮到话,你就能够避免出现前面所说的不利后果。
在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。
hibernate工作原理:
Hibernate中的缓存分为一级缓存和二级缓存。
一级缓存就是 Session 级别的缓存,在事务范围内有效是,内置的不能被卸载。二级缓存是 SesionFactory级别的缓存,从应用启动到应用结束有效。是可选的,默认没有二级缓存,需要手动开启。保存数据库后,缓存在内存中保存一份,如果更新了数据库就要同步更新。
什么样的数据适合存放到第二级缓存中?
扩展:hibernate的二级缓存默认是不支持分布式缓存的。使用 memcahe,redis等中央缓存来代替二级缓存。
hibernate里对象有三种状态:
openSession 是打开一个新的session对象,而且每次使用都是打开一个新的session,假如连续使用多次,则获得的session不是同一个对象,并且使用完需要调用close方法关闭session。
getCurrentSession 是获取当前上下文一个session对象,当第一次使用此方法时,会自动产生一个session对象,并且连续使用多次时,得到的session都是同一个对象,这就是与openSession的区别之一,简单而言,getCurrentSession 就是:如果有已经使用的,用旧的,如果没有,建新的。
注意:在实际开发中,往往使用getCurrentSession多,因为一般是处理同一个事务(即是使用一个数据库的情况),所以在一般情况下比较少使用openSession或者说openSession是比较老旧的一套接口了。
必须,因为hibernate框架会调用这个默认构造方法来构造实例对象,即Class类的newInstance方法,这个方法就是通过调用默认构造方法来创建实例对象的。
另外再提醒一点,如果你没有提供任何构造方法,虚拟机会自动提供默认构造方法(无参构造器),但是如果你提供了其他有参数的构造方法的话,虚拟机就不再为你提供默认构造方法,这时必须手动把无参构造器写在代码里,否则new Xxxx()是会报错的,所以默认的构造方法不是必须的,只在有多个构造方法时才是必须的,这里“必须”指的是“必须手动写出来”。