实体类规范(javaBean规范)
1.提供无参构造方法
2.成员变量私有化 提供get/set方法
double 表示学分 0–100.0 没考试只能表示为 0
Double 有null值 缺考 用空值表示 0分
3.基本数据类型尽量使用包装类型(可以多表示一个值null 例如考试分数 缺考和0分)
4.实体中必须要提供一个与表中的主键对应的属性id
hibernate是通过主键来区别对象是否相同
5.不要使用final修饰实体类(代理对象是要继承该类的)
主键类型
1.自然主键
输入信息的时候 人的身份证号 保证了 非空不重复 符合主键的贴点
但是身份证号 本身是业务字段 可以作为主键使用 叫做自然主键
2.代理主键(常用)
找不到主键(没有业务字段符合主键规则)
搞一个没有任何意义的主键id列 作为主键 就是为了非空不重复 叫做代理主键
主键生成策略(7种)
在映射文件中配置
<!-- 主键生成策略 -->
<generator class="native"></generator>
<!-- 主键生成策略 7个 -->
<!--
identity: 主键自增,由数据库维护 插入数据,无id
increment:主键自增,但是由hibernate维护,会先查询最大的id,然后在这个最大的id的基础上+1 并且插入数据时有id
sequence:Oracle中的主键生成策略 序列
hilo:高低位算法(hibernate会自己通过该算法算出主键自增)
native:(常用)hilo + sequence + identity 三选一
系统会检测你的数据库类型 mysql就是自增策略
uuid:全球范围内不重复的值,是字符串
注意:主键必须是字符串类型
是由hibernate生成的uuid 插入到数据库中
assigned:是由程序员自己管理主键
-->
/**
* 测试主键策略,查看生成的sql语句
*/
@Test
public void fun1() {
//获取session
Session session = HibernateUtils.getSession();
//开启事务
Transaction transaction = session.beginTransaction();
//包裹语句(保存一个对象到数据库)
User user = new User();
user.setUsername("ls");
user.setPassword("123");
session.save(user);
//提交事务
transaction.commit();
//关闭session
session.close();
}
三种状态
1.瞬时态 没有id 没有和session关联
2.持久态 有id 有关联
3.游离态 有id 没有关联
/**
* hibernate中对象的三种状态
*/
@Test
public void fun2() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
User user = new User();//瞬时态 没有id,没有和session关联
user.setUsername("zs");
user.setPassword("123");
session.save(user);//持久态 有id,有session关联
transaction.commit();
session.close();//游离态 有id,没session关联
}
结论:就是将我们想要同步到数据库的数据 所对应的对象转换成持久态
一级缓存与快照
/**
* 测试一下hibernate中的缓存
*/
@Test
public void fun3() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
User user1 = session.get(User.class, 1);
User user2 = session.get(User.class, 1);
User user3 = session.get(User.class, 1);
User user4 = session.get(User.class, 1);
User user5 = session.get(User.class, 1);
//1.生成几条sql语句
//2.下面打印的结果
transaction.commit();
session.close();
}
生成一条sql语句
/**
* 快照原理
*/
@Test
public void fun4() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
User user = session.get(User.class, 1);
user.setUsername("xiaohong");
user.setUsername("qw");
session.update(user);
transaction.commit();
session.close();
}
避免重复查询,重复修改,重复同步到数据库
提高效率
/**
* 测试
* 瞬时态---》游离态---》持久态
*/
@Test
public void fun5() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
User user = new User(); //瞬时态 无id session中的有无缓存
user.setId(1); //游离态 有id session中的有无缓存
/*
* 从数据库返回结果集,是保存进缓存和快照中
* update时,把这个要更新的对象放入缓存中(跟快照没关系)
*/
session.update(user); //持久态 有id session中的缓存有联系
//get查询时,去缓存中查找,看有没有该id的对象
User user2 = session.get(User.class, 1);
//当事务提交的时候,hibernate会对比快照和缓存中的对象是否相同
//不相同会把缓存中的对象同步到数据库
transaction.commit();
session.close();
}
指定事务的隔离级别
<!--
通过hibernate来设置事务的隔离级别
1.脏读
2.可重复读
3.幻读
READ UNCOMMITTED 读未提交 123
READ COMMITTED 读已提交 23
REPEATABLE READ 可重复读 3
SERIALIZABLE 串行化(只能一个一个访问)
设置事务的隔离级别(去etc里面找)
specify a JDBC isolation level
hibernate.connection.isolation 1|2|4|8
隔离级别是用一个字节存储的
0001 1
0010 2
0100 4
1000 8
-->
<property name="hibernate.connection.isolation">4</property>
<!-- 使用getCurrentsession必须配置一下
注意:当你使用getCurrentsession时,不需要你手动关闭session,系统会帮你关闭
-->
<property name="hibernate.current_session_context_class">thread</property>
HQL 查询(简单多表查询 不复杂的查询)
查询所有对象
String HQL = “from User”; 跟着的是类名 项目里 只有
按条件查询 HQL不会出现表中字段 id 代表的是属性名
String HQL = “from User where id = 1”;
查询方法
Query query = session.createQuery(HQL);
返回结果(预见结果)
集合 list()
单个 uniqueResult()
/**
* HQL查询
*/
@Test
public void fun1() {
String hql = "from User";
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
Query query = session.createQuery(hql);
//预见一下结果(单数据)
// User user = (User) query.uniqueResult();
// System.out.println(user);
List<User> list = query.list();
System.out.println(list);
transaction.commit();
session.close();
}
问号?占位符
因为面向对象的查询 这里的id 指的是 实体类中的属性名
String HQL = "from User where id = ? and username = ?";
Query query = session.createQuery(HQL);
赋值参数的时候 参数1 占位符的索引 注意:HQL索引从0开始的
query.setParameter(0, 2);
query.setParameter(1, "www1");
/**
* 问号占位符
*/
@Test
public void fun2() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
String hql="from User where id=?";
Query query = session.createQuery(hql);
//给语句中的问号赋值,索引从零开始
query.setParameter(0, 2);
User user = (User) query.uniqueResult();
System.out.println(user);
transaction.commit();
session.close();
}
冒号:占位符(注意冒号后面别来空格兄弟)
String HQL = “from User where id = :ww1 and username = :ww2”;
/**
* 冒号占位符
*/
@Test
public void fun3() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
//冒号后面相当于给这个冒号占位符起了个别名
//注意:冒号后边不要有空格
String hql="from User where id=:ww";
Query query = session.createQuery(hql);
//直接使用别名给占位符赋值
query.setParameter("ww", 2);
System.out.println(query.uniqueResult());
transaction.commit();
session.close();
}
分页查询
String HQL = “from User”;
Query query = session.createQuery(HQL);
limit ?,? 相同 起始 和 最大显示
query.setFirstResult(2);
query.setMaxResults(2);
/**
* 分页
*/
@Test
public void fun4() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
String hql="from User";
Query query = session.createQuery(hql);
//设置起始和最大显示
query.setFirstResult(2);
query.setMaxResults(2);
//接收结果
List list = query.list();
System.out.println(list);
transaction.commit();
session.close();
}
Criteria无语句查询(单表查询)
Criteria criteria = session.createCriteria(User.class);
List list = criteria.list();
需要预见结果 使用单对象返回
User user = (User) criteria.uniqueResult();
System.out.println(user);
/**
* 无语句查询
*/
@Test
public void fun5() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(User.class);
List list = criteria.list();
System.out.println(list);
transaction.commit();
session.close();
}
添加查询条件
criteria.add(Restrictions.eq(“id”, 2));
User user = (User) criteria.uniqueResult();
System.out.println(user);
HQL运算符 QBC运算符 含义
= Restrictions.eq() 等于
> Restrictions.gt() 大于
>= Restrictions.ge() 大于等于
< Restrictions.lt() 小于
<= Restrictions.le() 小于等于
is null Restrictions.isnull() 等于空值
is not null Restrictions.isNotNull() 非空值
like Restrictions.like() 字符串模式匹配
and Restrictions.and() 逻辑与
or Restrictions.or() 逻辑或
not Restrictions.not() 逻辑非
in(列表) Restrictions.in() 等于列表中的某一个值
between x and y Restrictions.between() 闭区间xy中的任意值
/**
* 按条件查询
*/
@Test
public void fun6() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(User.class);
//添加一个查询条件
// criteria.add(Restrictions.eq("id", 1));
// User user = (User) criteria.uniqueResult();
// System.out.println(user);
criteria.add(Restrictions.gt("id", 4));
transaction.commit();
session.close();
}
查询总行数
criteria.setProjection(Projections.rowCount());
/**
* 查询有多少记录数
*/
@Test
public void fun7() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(Projections.rowCount());
//一般返回值是个数的,通常都使用大Long来接收
Long l = (Long) criteria.uniqueResult();
System.out.println(l);
transaction.commit();
session.close();
}
原生sql查询(复杂的多表查询)
String sql = “select * from user where id=?”;
SQLQuery query = session.createSQLQuery(sql);
query.setParameter(0, 3);
预见返回结果集
注意:返回数据的类型
/**
* 原生sql查询 注意:返回结果跟对象没有关系
*/
@Test
public void fun8() {
Session session = HibernateUtils.getSession();
Transaction transaction = session.beginTransaction();
String sql = "select * from user where id=?";
Query query = session.createSQLQuery(sql);
query.setParameter(0, 3);
// List<Object[]> list = query.list();
// for (Object[] objects : list) {
// System.out.println(objects);
// }
//一条记录就是一个Object数组
Object[] object = (Object[]) query.uniqueResult();
System.out.println(object);
transaction.commit();
session.close();
}