1. 持久化类
持久化类就是一个Poo类,这个类建立与数据库中的表映射关系之后,就是持久化类。
持久化类 = Poo类+ xxx.hbm.xml
持久化类在编写时,需要遵循javabean的规范,除此之外,还需要添加一个主键的标识属性,一般为id。
1.2 Hibernate持久化对象的状态
瞬时态:Transient Object
没有持久化标识OID, 没有被纳入到Session对象的管理。也就是刚new出了一个对象。
持久态:Persistent Object
有持久化标识OID,已经被纳入到Session对象的管理.使用save或者load方法保存此对象,就是持久态了。保存过程中,id值会自动生成。
脱管态:Detached Object
有持久化标识OID,没有被纳入到Session对象的管理。比如session操作完对象以后,session被释放。
持久化的对象因为已经被session使用save或者load方法操作过,因此会缓存在session对象中(session是一级缓存)。具有自动更新数据库的能力。即只要修改了持久化对象的,不用调用session的update方法,也会自动修改数据库中的值。
2. 数据库的主键生成策略
1. increment:适用于short,int,long作为主键.不是使用的数据库自动增长机制.
* Hibernate中提供的一种增长机制.
* 先进行查询 :select max(id) from user;
* 再进行插入 :获得最大值+1作为新的记录的主键.
* 问题:不能在集群环境下或者有并发访问的情况下使用.
2. identity:适用于short,int,long作为主键。但是这个必须使用在有自动增长数据库中.采用的是数据库底层的自动增长机制.
* 底层使用的是数据库的自动增长(auto_increment).像Oracle数据库没有自动增长.
3. sequence:适用于short,int,long作为主键.底层使用的是序列的增长方式.
* Oracle数据库底层没有自动增长,想自动增长需要使用序列.
4. uuid:适用于char,varchar类型的作为主键.
* 使用随机的字符串作为主键.
5. native:本地策略.根据底层的数据库不同,自动选择适用于该种数据库的生成策略.(short,int,long)
* 如果底层使用的MySQL数据库:相当于identity.
* 如果底层使用Oracle数据库:相当于sequence.
6. assigned:主键的生成不用Hibernate管理了.必须手动设置主键.
一般采用mysql采用native方式生成自增长int类型的主键。
3. 使用Query方式查询
public class QueryTest {
private SessionFactory factory;
@Before
public void first(){
// 先加载配置文件
Configuration config = new Configuration();
// 默认加载src目录下的配置文件
config.configure();
// 创建SessionFactory对象
factory = config.buildSessionFactory();
}
/**
* 查询所有的记录
*/
@Test
public void queryAll(){
Session session = factory.openSession();
//Student是POJO类的类名称,对应数据库中的students。一定得是java类名,不能直接写数据库的表名。
Query query = session.createQuery("from Student");
List<Student> list = query.list();
System.out.println(list);
}
/**
* 条件查询的常见写法
*/
@Test
public void query_Tiaojian(){
Session session = factory.openSession();
//Student是POJO类的类名称,对应数据库中的students。一定得是java类名,不能直接写数据库的表名。
Query query = session.createQuery("from Student where name = ?");
query.setString(0, "关羽");
List<Student> list = query.list();
System.out.println(list);
}
/**
* 条件查询的另一种写法
*/
@Test
public void query_Tiaojian2(){
Session session = factory.openSession();
//Student是POJO类的类名称,对应数据库中的students。一定得是java类名,不能直接写数据库的表名。
Query query = session.createQuery("from Student where age>:nianling");
query.setInteger("nianling", 20);
List<Student> list = query.list();
System.out.println(list);
}
}
createQuery中的参数是一个字符串,类似于sql语句,但出现的单词是java类或者java类的属性,不能直接使用表名和表的字段。
如果着这样写是报错的:
//students 是数据库中的表名
Query query = session.createQuery("from students where age>:nianling");
4. 使用Criteria接口方式查询
public class QueryTest {
private SessionFactory factory;
@Before
public void first(){
// 先加载配置文件
Configuration config = new Configuration();
// 默认加载src目录下的配置文件
config.configure();
// 创建SessionFactory对象
factory = config.buildSessionFactory();
}
@Test
public void criteriaAll(){
Session session = factory.openSession();
Criteria criteria = session.createCriteria(Student.class);
List<Student> list = criteria.list();
System.out.println(list);
}
@Test
public void criteriaA_tiaojian(){
Session session = factory.openSession();
Criteria criteria = session.createCriteria(Student.class);
criteria.add(Restrictions.eq("name", "小乔"));
List<Student> list = criteria.list();
System.out.println(list);
}
//多条件查询
@Test
public void criteriaA_tiaojian2(){
Session session = factory.openSession();
Criteria criteria = session.createCriteria(Student.class);
criteria.add(Restrictions.gt("id", 3));
criteria.add(Restrictions.gt("age", 22));
List<Student> list = criteria.list();
System.out.println(list);
/**
* 使用别名,投影插叙,排序,分页查询
*/
@Test
public void other_query(){
Session session = factory.openSession();
//使用别名进行查询
List list=session.createQuery("from Student s").list();
System.out.println(list);
//投影查询,只查询每条记录的name属性
List list1=session.createQuery("select s.name from Student s").list();
System.out.println(list1);
//按年龄进行升序查询,语法和sql基本一致
List list2=session.createQuery("select s.name from Student s order by age").list();
System.out.println(list2);
//按年龄进行降序查询,语法和sql基本一致
List list3=session.createQuery("select s.name from Student s order by age desc").list();
System.out.println(list3);
/**
* 分页查询
* setFirstResult(a) -- 从哪条记录开始,如果查询是从第一条开启,值是0
* setMaxResults(b) -- 每页查询的记录条数
*/
List list4 = session.createQuery("select s.name from Student s").setFirstResult(1).setMaxResults(2).list();
System.out.println(list4);
}
/**
* 使用聚合函数
*/
@Test
public void juheHashu_Query(){
Session session = factory.openSession();
//使用count查询总的记录数
List<Number> list = session.createQuery("select count(s) from Student s").list();
Long count = list.get(0).longValue();
System.out.println(count);
//使用sum查询age的总和
List<Number> list2 = session.createQuery("select sum(s.age) from Student s").list();
Long count2 = list2.get(0).longValue();
System.out.println(count2);
}
/**
* 离线查询,使用的是DetachedCriteria接口进行查询,离线条件查询对象在创建的时候,
* 不需要使用Session对象,只是在查询的时候使用Session对象即可。
*/
@Test
public void lixian_Query(){
Session session = factory.openSession();
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Student.class);
//设置查询条件
detachedCriteria.add(Restrictions.eq("sex", "男"));
List list = detachedCriteria.getExecutableCriteria(session).list();
System.out.println(list);
}
}
criteria接口查询比较适合条件查询。
4.1常用的Restrictions方法
Restrictions.eq 等于
Restrictions.allEq 使用Map,使用key/value进行多个等于的比对
Restrictions.gt 大于 >
Restrictions.ge 大于等于 >=
Restrictions.lt 小于 <
Restrictions.le 小于等于 <=
Restrictions.between 对应SQL的BETWEEN子句
Restrictions.like 对应SQL的LIKE子句
Restrictions.in 对应SQL的in子句
Restrictions.and and关系
Restrictions.or or关系