实体类的编写规则
- 实体类中属性私有
- 私有属性使用公有的set get方法进行操作
- 要求属性中有一个值都是唯一的
- 实体类中属性的数据类型,不建议基本数据类型,而要使用包装类
hibernate主键生成策略
<!-- 设置数据表字段生成和增长策略
native 生成表主键和自动增长-->
<generator class="native"></generator>
native:
根据底层数据库对自动生成表示符的能力来选择,identity,sequence,hio三种生成器的一种,适合跨数据库平台开发,适用于代理主键.
uuid: hibernate采用128位的uuid算法来生成标识符,该算法能够在网络环境中生成唯一的字符串标识符,该策略并不流行,因为字符串类型的主键比整数类型的主键占用更多的数据库空间,适合于代理主键.
演示uuid
- 使用uuid,实体类中的唯一属性是String
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- name 实体类的全路径
table 表的名称-->
<class name="entity.User" table="user">
<!-- 配置实体类属性和表字段一一对应-->
<id name="id" column="id">
<!-- 设置数据表字段生成和增长策略
native 生成表主键和自动增长-->
<generator class="uuid"></generator>
</id>
<!-- 配置其他属性-->
<property name="name" column="name"></property>
<property name="address" column="address"></property>
</class>
</hibernate-map
实体类操作
- 添加操作
// 5. 具体操作
// uid 设置或者不设置没有影响
User u = new User();
u.setName("靳飞飞");
u.setAddress("西安");
session.save(u);
- 根据id查询
@Test
public void test() {
//
// 2. 创建sessionFactory对象
// 读取hibernate配置文件内容,创建sessionFactory
// 在过程中,根据映射关系,在配置数据库里面将表创建
SessionFactory factory = HibernateFactory.getFactory();
// 3. 获取session
Session session = factory.openSession();
// 查询根据id
User user = session.get(User.class, 1);
System.out.println(user);
// 6. 关闭
session.close();
factory.close();
}
- 修改操作
先查询,在修改
// 进行操作
User user = session.get(User.class, 1);
user.setName("虎哥");
session.update(user);
transaction.commit();
使用下面这种修改方法,相当于重新对所有的属性改变,如果没有设置,相当于是null;
User u = new User();
u.setId(1);
u.setName("飞飞飞");
session.update(u);
- 删除操作
// 操作
User user = session.get(User.class, 2);
session.delete(user);
或者
// 操作
User user = new User();
user.setId(1);
session.delete(user);
实体类对象状态
- 瞬时态
对象里面没有id值,对象与session没有关联
User user = new User();
user.setName("户户");
- 持久态
对象里面有id值,对象与session有关联
User user = session.get(User.class, 1);
- 托管态
对象有id值,对象与session没有关联
User u=new User();
u.setId(1);
session.saveOrUpdate()此方法在实体类为瞬时态时候做添加,托管态和持久态时候做修改
hibernate的一级缓存
- 什么是缓存?
数据存到数据库里面(硬盘),数据库本身是文件系统,使用流方式操作文件效率不是很高.
(1) 把数据存到内存里面,不需要使用流的方式,可以直接读取内存中的数据
(2) 把数据放到内存中,提高读取效率.
hibernate缓存
hibernate 框架中提供很多优化方式,hibernate缓存你就是一个优化方式.
hibernate缓存特点
- 第一类缓存 Hibernate一级缓存
a. hibernate一级缓存默认打开
b. hibernate一级缓存使用范围,是从session创建到session关闭范围
c. hibernate一级缓存中,存储数据必须持久态数据. - 第二类缓存 hibernate二级缓存
a. 目前已经不使用了,替代技术redis
b. 二级缓存默认不是打开的,需要配置
c. 二级缓存适用范围,是sessionFactory的范围
验证一级缓存
// 进行操作
User user = session.get(User.class, 3);
System.out.println(user);
User user1 = session.get(User.class,3);
System.out.println(user1);
第一次查询时会发送sql语句进行查询
第二次查询同样的东西,不会在发送sql语句
一级缓存特性
- 持久态自动更新数据
不需要写update方法
cache.png
hibernate 事务规范写法
@Test
public void updateTest() {
SessionFactory factory = null;
Session session = null;
Transaction tx = null;
try {
// 获取sessionFactory
factory = HibernateFactory.getFactory();
// 获取session
session = factory.openSession();
tx = session.beginTransaction();
// 进行操作
User user = session.get(User.class, 3);
user.setName("飞飞");
int i = 10/0;
tx.commit();
}catch (Exception e){
// 事务回滚
tx.rollback();
}finally {
// 关闭
session.close();
factory.close();
}
}
hibernate绑定session
- session类似于jdbc中的connection,
- hibernate帮忙实现与本地线程绑定session
- 获取与本地线程绑定的session
(1) 在hibernate核心配置文件中配置
<!--配置本地线程绑定session-->
<property name="hibernate.current_session_context_class">thread</property>
(2) 调用sessionFactory里面的方法得到session
/**
* 获取与本地线程绑定的session
* @return
*/
public static Session getSession(){
return factory.getCurrentSession();
}
(3) 获取与本地线程绑定的session时候,关闭session报错,不需要在手动关闭session了.
query对象查询所有记录
- 使用query对象,不需要写sql语句,但是写hql语句
(1) hql:hibernate query language 提供查询语言,这个sql语句和普通sql语句很相似.
(2) hql和sql语句的区别
- 使用sql操作表和表字段
- 使用hql 操作实体类和属性.
查询所有hql语句
(1) from 实体类名称query 对象的使用
(1) 创建query对象
(2) 调用里面的方法
@Test
public void queryTest(){
Session session = null;
Transaction tx = null;
try{
session = HibernateFactory.getSession();
tx = session.beginTransaction();
Query query = session.createQuery("from User");
List<User> list = query.list();
for(User u:list){
System.out.println(u);
}
} catch (Exception e) {
tx.rollback();
}finally {
session.close();
}
}
- Criteria对象的使用,必须先开启事务,在获取对象
@Test
public void testCritera() {
Session session = null;
Transaction tx = null;
try {
session = HibernateFactory.getSession();
tx = session.beginTransaction();
Criteria criteria = session.createCriteria(User.class);
List<User> list = criteria.list();
for (User u : list) {
System.out.println(u);
}
} catch (Exception e) {
tx.rollback();
} finally {
// session.close();
}
}
- sqlquery对象的使用
sqlQuery默认返回的是List<Object[]>
@Test
public void testSQLQuery(){
Session session = null;
Transaction tx = null;
try{
session = HibernateFactory.getSession();
// 开启事务
tx = session.beginTransaction();
SQLQuery sqlQuery = session.createSQLQuery("select * from user");
List<Object[]> list = sqlQuery.list();
for(Object[] u:list){
System.out.println(Arrays.toString(u));
}
}catch (Exception e){
tx.rollback();
}finally {
}
}
让list()直接返回User对象
@Test
public void testSQLQuery(){
Session session = null;
Transaction tx = null;
try{
session = HibernateFactory.getSession();
// 开启事务
tx = session.beginTransaction();
SQLQuery sqlQuery = session.createSQLQuery("select * from user");
sqlQuery.addEntity(User.class);
List<User> list = sqlQuery.list();
for(User u:list){
System.out.println(u);
}
}catch (Exception e){
tx.rollback();
}finally {
session.close();
}
}