这一周我们都在学Hibernate,以下是我对Hibernate的总结。
一、Hibernate操作
Hibernate是面向对象的持久操作,Hibernate是一个开发源代码的对象关系映射框架,对JDBC进行了非常轻量级的对象封装,简化了JDBC繁琐的编码,将java对象与数据库表建立连接。Hibernate将java与数据库连接的过程:首先要为项目增添Hibernate支持,即添加jar包和编写配置文件,第二步是创建实体类,创建和配置映射文件,主要包括包括实体与表的映射,属性与主键的映射,属性与其他字段的映射,第三步是数据库操作:
public void hibernateTest() {
// 1、获取配置
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(cfg.getProperties()).buildServiceRegistry();
// 2、创建SessionFactory
SessionFactory factory = cfg.buildSessionFactory(serviceRegistry);
// 3、获取session
Session session = factory.openSession();
Transaction tx = session.getTransaction();
try {
// 4、开启事务
tx.begin();
Type tp = new Type("小说", "亚洲小说集");
// 5、保存Type对象
session.save(tp);
// 6、提交事务
session.getTransaction().commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
// 7、关闭session
session.close();
}
}
二、实体关联
实体之间的有关联关系和泛化关系,关联关系包括一对多关联、一对一关联、多对一关联和双向一对多关联。
Many-to-one:many的一端应持有one的一端的对象,在映射文件中体现为:
<many-to-one class="entity.Type" name="type">
<column name="type_id" />
</many-to-one>
Class后面是写的实体名,name后面是class的属性名,colum name是外键名。
One-to-many:one的一端应持有many端的对象集合,在映射文件中体现为:
<set name="records" sort="unsorted">
<key column="isbn" />
<one-to-many class="entity.Record" />
</set>
Many-to-many:双向一对多特别简单,就是同时配置了单向的一对多和单向的多对一。
此外我学习过程中遇到了联合主键且为外键的书写,在映射文件中体现为:
<composite-id >
<key-many-to-one name="book" column="isbn" class="entity.Book"
/>
<key-many-to-one name="stu" column="stu_id" class="entity.Student"
/>
</composite-id>
三、实体的三种状态
我感觉在Hibernate中最有难度的地方是实体对象的三种状态,瞬时状态(Transient)、持久状态(Persistent)和游离状态(Detached)。
四、HQL与Criteria查询
Hibernate 支持两种主要的查询方式:HQL和Criteria查询。HQL是一种面向对象的查询语言,其中没有表和字段的概念,有的是属性、类和对象的概念。HQL的操作需要四步:得到Session、编写HQL语句、创建Query对象,执行查询的得到结果。
我感觉HQL查询与SQL很相似,但是HQL是面向对象的,在HQL中比较新鲜的查询操作是分页操作和投影。
分页操作:
@Test
// 测试分页
public void pagerTest() {
String hqlString = "from Student";
Session session = HibernateUtil.currentSession();
//通过HibernateUtil的currentSession方法获得Session
Query query = session.createQuery(hqlString);
query.setFirstResult(10);
query.setMaxResults(10);
List<Student> students = query.list();
System.out.println(students);
}
投影操作:
@Test
// 投影的测试
public void projectionTest() {
Session s = HibernateUtil.currentSession();
//通过HibernateUtil的currentSession方法获得Session
String queryString = "select b.name,b.count from Book b";
//获得SQL语句
Query query = s.createQuery(queryString);
//创建Query对象
List l = query.list();
// 投影的结果:对象数组的集合——集合中的元素是对象数组
// System.out.println(l.get(0).getClass());
for (Object object : l) {
Object[] data = (Object[]) object;
System.out.println("name==" + data[0] + ",count==" + data[1]);
}
}
Criteria查询与HQL查询很类似,但是HQL是基于字符串的查询,因而更加灵活,我个人感觉Criteria比较好用一些。我感觉它的模糊查询比HQL更加好简洁。
@Override
public List<Book> findByNameLike(String name) throws Exception {
Session session=HibernateUtil.getSession();
//在HibernateUtil类中的getSession获取Session
Criteria criteria=session.createCriteria(Book.class);
criteria.add(Restrictions.like("name","%"+ name+"%"));
return criteria.list();//返回Book类型集合
}