讲师:钟昕灵,叩丁狼教育高级讲师。原创文章,转载请注明出处。
在上面的章节中,我们使用Hibernate完成了基本的CRUD,并对相关操作的执行流程进行了分析,相信大家对Hibernate的简单使用有了一定的了解,那么,接下来,我们来了解一下Hibernate中常用的API.
1. Configuration
- Configuration conf = new Configuration();
创建配置Configuration对象,同时加载classpath路径下的名称为hibernate.properties的文件
常用方法: - Configuration configure();
如果创建Configuration对象后不调用该方法,hibernate是默认加载classpath下的hibernate.properties文件
调用该方法表示加载classpath下名称为hibernate.cfg.xml的配置文件 - Configuration configure(String configureFileName);
如果在我们的项目中配置文件的名称不是使用默认的名称,那么可以指定记载的配置文件名称 - Configuration addResource(String resourceName)
通常,我们在hibernate.cfg.xml文件中会指定加载的映射文件
<mapping resource="cn/wolfcode/_01_hello/User.hbm.xml" />
如果不使用上面这种配置文件的方式,我们还可以使用addResource方法指定要加载的映射文件
conf.addResource("cn/wolfcode/_01_hello/User.hbm.xml");
- Configuration addClass(Class persistentClass);
加载映射文件也可以使用该方法实现,如下
conf.addClass(User.class);
此时hibernate会找和User类同路径的名称为User.hbm.xml的映射文件
- SessionFactory buildSessionFactory();
创建SessionFactory对象
2. SessionFactory
SessionFactory负责管理Session,管理连接池,管理Hibernate二级缓存以及预定义的SQL语句。
SessionFactory是一个重量级的(创建该对象的时候需要加载较多的资源文件,或者说创建对象比较耗时), 线程安全的对象(允许多线程并发访问),基于此,通常在一个hibernate应用中,我们只需要一个SessionFactory对象,所以,我们可以使用如下来创建SessionFactory对象
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
//当前工具类被加载的时候,执行该静态代码块初始化SessionFactory对象
sessionFactory =
new Configuration()
.configure()//加载classpath中的hibernate.cfg.xml文件
.buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
HibernateUtil.getSessionFactory() 能够保证在一个应用中只有一个SessionFactory对象
常用API:
Session openSession();从连接池中获取一个连接对象,构造Session对象
Session getCurrentSession();获取和当前线程绑定的连接对象(ThreadLocal),构造Session对象
3. Session
Session是Hibernate程序与数据库之间的桥梁。完成CRUD的操作。Session是一个单线程的对象(线程不安全),需要每个访问数据库的操作创建一个单独的Session对象; 内部维护了Hibernate的一级缓存。
常用API:
- Serializable save(Object object);
执行保存操作,hibernate会根据传入的参数对象,拼接出对应的INSERT语句,在事务中进行 - void delete(Object object);
执行删除数据操作,将需要删除数据的主键信息封装到一个对象中,然后hibernate为我们自动的生成对应的DELETE语句,在事务中进行 - void update(Object object);
执行更新操作,将需要更新的数据封装到一个对象中,然后hibernate为我们生成对应的UPDATE语句,在事务中进行 - Object get(Class clazz, Serializable id);
执行单行数据的查询,传入要查询数据的类型,和数据对应的主键id,返回查询到的数据,将其封装到指定类型的对象中,不在事务中进行 - Query createQuery(String queryString);
创建查询对象,执行传入的HQL语句
如:SELECT u FROM User u
这里的User是Java中的User类,而不是数据库中的user表 - CriteriaBuilder getCriteriaBuilder();
Criteria构建器,用来创建Criteria对象,Criteria是一种比hql更面向对象的查询方式 - NativeQuery createNativeQuery(String sqlString)
创建本地SQL查询对象,执行传入的SQL语句,这种方式可以执行按需求的,高效率的SQL语句,缺点是会和使用的数据库高度耦合
4. Transaction
hibernate中的事务管理器,封装事务管理的基本操作
void begin();开启事务
void commit();提交事务
void rollback();回滚事务
void boolean isActive();判断当前事务是否是活动有效的
在这里,我们只是将事务相关的API进行了简单的罗列出来,在后面,我们会单独有一节的内容来讨论Hibernate中事务管理相关的内容
5. Query
以面向对象的思想执行数据的各种查询操作
Query query = session.createQuery(hqlString);//hqlString:hibernate提供的hibernate查询语言(Hibernate Query Language)
通过以下案例来熟悉一下Query对象的使用:
- 查询user表中的所有数据(包含所有的列)
String hql = "FROM User";
List<User> list = session.createQuery(hql).list();
注:
- 大家在写hql的时候,可以和之前写过的sql进行对比,sql出现的表或者列分别对应这里的类或者属性,所以在写的时候需要多加注意
- 查询所有的列的数据可以使用如上的简写方式,等同于下面的hql
String hql = "SELECT uid,uusername,upassword,uage,uhiredate";
- list()方法表示查询多条数据,将结果封装到List集合中
- hibernate最终会将结合对应的映射文件,将hql解析为sql(把类名转换为表名,把属性名转换为列名等)
- 查询user表中的所有数据(包含部分的列,name/age/hiredate)
String hql = "SELECT uname,uage,uhiredate FROM User";
List<User> list = session.createQuery(hql).list();
- 查询单条数据
在Query中提供了两个方法用来获取并封装单条数据或单个数据的结果集
uniqueResult() 和 getSingleResult()
// 查询一行数据将其封装成一个User类型的对象
User user = (User) session.createQuery("FROM User WHERE uusername = ?")
.setParameter(0, "Neld").uniqueResult();
//查询user表中的总记录数
long count = (long) session.createQuery("select count(uid) FROM User").uniqueResult();
- 为查询设置查询条件需要的参数
如果hql的执行需要参数的话,我们可以和sql语句一样的是写方式,使用?作为占位符,然后在执行之前设置参数
// 使用索引为指定位置的占位符设置参数(从0开始)
Query setParameter(int position, Object value);
// 使用参数的名称为参数赋值
Query setParameter(String paramName, Object value);
方式一:使用索引为参数赋值
List<User> list = session.createQuery("FROM User WHERE age >= ? AND age <= ?")
.setParameter(0, 10)// 0,表示第一个?占位符
.setParameter(1, 20)
.list();
方式二:为参数命名,然后为指定名称的参数赋值,直接将?替换为:参数名的格式
List<User> list = session.createQuery("FROM User
WHERE age >= :minAge AND age <= :maxAge")
.setParameter("minAge", 10)
.setParameter("maxAge", 20).list();
方式二在关键字查询中使用的较多(多个参数需要的是相同的数据),如:
List<User> list = session.createQuery("FROM Product
WHERE name LIKE :keyword OR brandName LIKE :keyword")
.setParameter("keyword", "%e%")//此时只需要为名称为keyword的参数赋值即可
.list();
- 分页查询
Query setFirstResult(int startPosition);//设置查询的第一条数据的索引,从0开始
Query setMaxResults(int maxResult);//设置一页最多显示数据的条数
List<User> list = session.createQuery(
"FROM Product WHERE name LIKE :keyword OR brandName LIKE :keyword")
.setParameter("keyword","%n%")
.setFirstResult(0)//从索引为0的数据开始查询
.setMaxResults(2)//每页最多显示两条数据
.list();
在mysql中对应的sql: LIMIT ?, ?
6. Criteria
主要为了解决多条件查询问题,以面向对象的方式添加条件,无需拼接HQL语句
Criteria criteria = session.createCriteria(User.class);
createCriteria()方法在hibernate5.2之后已经标注为过期,建议使用JAP中的Criteria实现
在此,我们姑且先用用该方法,简单认识一下Criteria对象的使用.例子和上面的一样,目的是通过对比学习效果更直接
- 查询user表中的所有数据(包含所有的列)
List<User> list = session.createCriteria(User.class).list();
- 查询单条数据
User user2 = (User) session.createCriteria(User.class)
.add(Restrictions.eq("uusername", "Neld"))//为查询添加过滤条件
.uniqueResult();//查询得到单行数据,并封装在一个对象中
- 为查询设置各种条件
List<User> users =
session.createCriteria(User.class)
// 设置根据uusername的模糊查询,MatchMode.ANYWHERE表示包含设置的参数即可,等同于: %n%
.add(Restrictions.like("uusername", "n", MatchMode.ANYWHERE))
// 设置根据uage的范围查询,相当于sql中的between...and
.add(Restrictions.between("uage", 10, 20))
// 设置根据uhiredate的范围查询(greater equals),相当于sql中的: >=
.add(Restrictions.ge("uhiredate", d))
.list();
- 分页查询
同Query对象中的分页实现的方式一样
List<User> users = session.createCriteria(User.class)
.setFirstResult(0)
.setMaxResults(2)
.list();
最后补充一下QBC(Query By Criteria)中的常用限定方法
限定方法 | 描述 |
---|---|
Restrictions.eq | equal,等于 |
Restrictions.allEq | 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq 的效果 |
Restrictions.gt | 大于 |
Restrictions.ge | 大于等于 |
Restrictions.lt | less-than, < 小于 |
Restrictions.le | less-equal <= 小于等于 |
Restrictions.between | 对应SQL的between子句 |
Restrictions.like | 对应SQL的LIKE子句 |
Restrictions.in | 对应SQL的in子句 |
Restrictions.and | and 关系 |
Restrictions.or | or 关系 |
Restrictions.isNull | 判断属性是否为空,为空则返回true 相当于SQL的 is null |
Restrictions.isNotNull | 与isNull相反 相当于SQL的 is not null |
Restrictions.sqlRestriction | SQL限定的查询 |
Order.asc | 根据传入的字段进行升序排序 |
Order.desc | 根据传入的字段进行降序排序 |
MatchMode.EXACT | 字符串精确匹配.相当于"like 'value'" |
MatchMode.ANYWHERE | 字符串在中间匹配.相当于"like '%value%'" |
MatchMode.START | 字符串在最前面的位置.相当于"like 'value%'" |
MatchMode.END | 字符串在最后面的位置.相当于"like '%value'" |
7. NativeQuery
这是5.2之后新API,同之前的SQLQuery作用一致,执行传入的SQL语句,因为是直接使用sql语句,相信大家是很熟悉的了,这里我们将上面的一个栗子换成使用NativeQuery对象来实现
String sql = "SELECT * FROM user
WHERE username LIKE ? AND age BETWEEN ? AND ? LIMIT ?, ?";
List<Object[]> list2 = session.createNativeQuery(sql)
.setParameter(1, "%n%")
.setParameter(2, 10)
.setParameter(3, 20)
.setParameter(4, 0)
.setParameter(5, 2)
.list();
这里返回的是一个List<Object[]>,hibernate是将没行数据封装在一个Object[]数组中的,所以,需要从数据中获取我们需要的数据
小结
这一节,我们对Hibernate中的常用API作了一个简单的整理和分析,希望对大家在Hibernate的基本API的使用上有所帮助, 可以把这一节的内容当做参考资料来使用
WechatIMG7.jpeg
网友评论