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事务
所谓事务,是指一组相互依赖的操作单元的集合,用来保证对数据库的正确修改,保护数据的完整性、一致性和安全性,如果一个事物的某个单元操作失败,将取消本次事务的全部操作。例如银行交易软件、股票交易软件等都用到书屋管理。我们知道数据库事务必须具有:原子性、一致性、持久性。所谓事务管理,就是执行以下流程
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集合,同时在员工中存一个公司的类
配置文件配置的方式:
在多的(职工中)
<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集合
name指的是 类中的属性名 table多对多的关系必须生成第三张表来维护inverse关系维护控制,双方必须有一方放弃维护,否则就会报错。通常为不常用的一方放弃维护
Key column 列名 在第三张表中该字段作为外键的名字
Many-to-many column 对应的是第三张表另外一个表中外键名字
class对应的是第三张表中的类
一般情况下,在多对多关系中,采用级联操作