hibernate的查询方式

1.1 Hql

基础查询

条件查询:建议使用字符串的占位符的方式

@Test
public void fun1(){
    Session session = HibernateUtil.getSession();
    Transaction transaction = session.beginTransaction();
    //hql语句中的查找是类名类的属性名
    String hql = "from User where name=?";
    Query query = session.createQuery(hql);
    //hql 的占位符是从0开始的
    query.setParameter(0,"莫邪");
    List<User> list = query.list();
    System.out.println(list);
    transaction.commit();
    HibernateUtil.close(session);
}

分页查询:setFirstResult第几个开始,setMaxResult查找几个

public void fun4(){
    Session session = HibernateUtil.getSession();
    Transaction transaction = session.beginTransaction();
    String hql = "from User";
    Query query = session.createQuery(hql);
    //开始到结束,包含后面的,不包含前面的
    query.setFirstResult(1);
    query.setMaxResults(2);
    List<User> list = query.list();
    System.out.println(list);
    transaction.commit();
    HibernateUtil.close(session);
}

最大的特点是封装了sql语句,在查找时用的是类名和类的属性

1.2 Criteria

public void fun(){
    Session session = HibernateUtil.getSession();
    Transaction transaction = session.beginTransaction();
    //获得criteria工厂 封装了方法  获得criteriaQuery对象
    CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
    //获得criteriaquery对象,封装所有信息,并告诉查询哪张表,存储查找条件
    CriteriaQuery<User> query = criteriaBuilder.createQuery(User.class);
    //指定从那张表进行查询 适用于单表,返回root对象 root存储的是数据库表的信息
    Root<User> root = query.from(User.class);
    //增加条件
    query.select(root);
    //讲条件放到query中
    //把这个query对象传给session调用他的list方法
    List<User> list = session.createQuery(query).list();
    System.out.println(list);
    transaction.commit();
    HibernateUtil.close(session);
}

1.2 这种语法连sql语句都不用写,在查询的时候调用用它封装好的方法

and()并且

or()或者
equal()等于
notEqual不等于
like()模糊查询
isnull()为空
in():等于列表中的某一个值(特别注意,使用特别)
gt(): 大于
ge(): 大于等于
lt(): 小于
le(): 小于等于
between()在两者之间
count():统计数量

1.3语句

NativeQuwey

事务的概念

1.1事务

所谓事务,是指一组相互依赖的操作单元的集合,用来保证对数据库的正确修改,保护数据的完整性、一致性和安全性,如果一个事物的某个单元操作失败,将取消本次事务的全部操作。例如银行交易软件、股票交易软件等都用到书屋管理。我们知道数据库事务必须具有:原子性、一致性、持久性。所谓事务管理,就是执行以下流程

hibernate的查询方式


1.2事务线程问题

1)脏读数据

张三(商家)从李四(货商)买东西 转账成功

事务一,张三给李四转账  转账成功

事务二,李四查看账户,钱多了,他就发货,提交了事务

事务一,回滚

2)不可重复读

酒店前台(a和b)

来了一个人客人,这个客人相住天字一号楼房间(前台a)

又来了一个人客人,这个客人又前台b接待,这个客人也想住天

一号楼房间,b把1101房间开了给这个客人

3)幻读(虚读)

对一个订单表查询两次,另为一个事务已经添加了新的记录,之前 查的 100条,现在发现是101次

为了解决上述问题,提出了一个隔离性:

1)串行化

想要完全的解决上述问题,只有一个办法,串行化(死锁)(不推行使用,原因:效率太低)

可重复读(mysql数据库默认的隔离级别)

可以防止脏读,不能防止幻读

读已提交数据(Oracle默认的隔离级别)

可以防止脏读数据,不可以防止不可重复读和幻读

读未提交数据

所有的问题都不解决,这种情况是所有隔离中,性能最好的

Hibernate复杂表的关系

Mysql是一个关系型数据库  表与表之间存在关系

一对一 一对多 多对一

(1)一对多

比如公司表与员工表

一个公司可以有多和员工,而一个员工只能能对应一个公司,这 样的关系就是一对多

再比如用户与角色

用户有a1、a2,角色有总监,小组长 普通

同时总监这个角色,有多个用户与它对用

这个时候1个用户有多个角色,有多个用户与它对应 a1和a2都是总监,这样的表与表之间的关系就是多对多关系

 

一对多的关系 如何维护

1中的主键存在多个表中,在多表中存在了1的主键就叫外键

Hibernate中维护的方式

在公司中存一个员工的set集合,同时在员工中存一个公司的类

hibernate的查询方式

hibernate的查询方式

配置文件配置的方式:

在多的(职工中)

<many-to-one name="enterprise" class="cn.hd.bean.Enterprise" column="enterpriseId"></many-to-one>

name在类中的属性名 class多的一方的类名 column生成外键的字段名

1中(公司中)

<set name="employeeSet">
    <key column="enterpriseId"></key>
    <one-to-many class="cn.hd.bean.Employee"></one-to-many>
</set>

set就是类中set  name就是公司类中储存的set的变量名

key就是外键

one-to-many写的对应关系表中的类名

 

级联操作

在保存企业的同时,将这个企业中的所有职工也同时保存,这样就少写了保存职工的代码

<!--cascade就是级联操作,是为了减少代码
    save-update 级联保存
    delete  级联删除(不推荐使用,不安全)
    all 既有级联删除又有级联保存(不推荐使用)
-->
<set name="employeeSet" cascade="save-update">
    <key column="enterpriseId"></key>
    <one-to-many class="cn.hd.bean.Employee"></one-to-many>
</set>

关系维护

<!--inverse  (在一对多的时候,多的一方维护,一的一方放弃维护)可以提高效率
    true    放弃维护
    false   维护(默认的值)
-->
<set name="employeeSet" cascade="save-update" inverse="true">
    <key column="enterpriseId"></key>
    <one-to-many class="cn.hd.bean.Employee"></one-to-many>
</set>

多对多

用户与角色

配置方式

bean类中双方都存set集合

hibernate的查询方式

hibernate的查询方式

hibernate的查询方式

name指的是 类中的属性名 table多对多的关系必须生成第三张表来维护inverse关系维护控制,双方必须有一方放弃维护,否则就会报错。通常为不常用的一方放弃维护

Key  column 列名 在第三张表中该字段作为外键的名字

Many-to-many column 对应的是第三张表另外一个表中外键名字

class对应的是第三张表中的类

一般情况下,在多对多关系中,采用级联操作