Hibernate5的基本使用

主流的orm框架之一、与mybatis框架类似,java web开发常用的框架

本文参考3W学习方法来叙述内容。

一、What

1、什么是Hibernate?

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架。
–引用自百度百科

二、Why

1、Hibernate的特点?

  • 将对数据库的操作转换为对Java对象的操作,从而简化开发。通过修改一个“持久化”对象的属性从而修改数据库表中对应的记录数据。
  • 有丰富的映射方式将Java对象之间的关系转换为数据库表之间的关系。
  • 屏蔽不同数据库实现之间的差异。在Hibernate中只需要通过“方言”的形式指定当前使用的数据库,就可以根据底层数据库的实际情况生成适合的SQL语句。

三、How

1、怎样掌握Hibernate?

1.1、了解六个API

  • Session
    • 执行被持久化对象的CRUD操作
    • 非线程安全
  • SessionFactory
    • 数据存储源的代理,创建Session对象
    • 每个数据库指定一个SessionFactory
  • Transaction
    • 统一事务的操作
  • Query
    • 对持久对象进行查询(HQL语言或本地数据库的SQL语句)
  • Criteria
    • 与Query接口非常类似,执行面向对象的标准化查询
  • Configuration
    • 对Hibernate 进行配置
    • 首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。

1.2、使用步骤

1.2.1、获取SessionFactory的实例对象

主要两种方式:

  • 通过Configuration对象构建,前提是创建了hibernate.cfg.xml配置文件(默认放在src根目录下)
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
// 指定配置文件路径
SessionFactory sessionFactory = new Configuration().configure("classpath:hibernate.cfg.xml").buildSessionFactory();
  • spring自动注入方式,spring的xml配置文件中声明sessionFactory的bean
<!-- dataSource DruidDataSource对应更换为使用的数据源类-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="maxActive" value="${druid.pool.maxActive}"/>
    <property name="initialSize" value="1" />
    <property name="minIdle" value="1" />
    <!-- 配置获取连接等待超时的时间 -->
    <property name="maxWait" value="60000" />
    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="60000" />
    <property name="minEvictableIdleTimeMillis" value="120000" />
    <property name="validationQuery" value="SELECT 1" />
    <property name="testOnBorrow" value="false" />
    <property name="testOnReturn" value="false" />
    <property name="testWhileIdle" value="true" />
    <property name="keepAlive" value="true" />
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" destroy-method="destroy">
    <property name="dataSource"  ref="dataSource"/>
    <property name="packagesToScan" value="com.breaker.jst"/>
    <!-- <property name="configLocation" value="classpath:hibernate.cfg.xml"/> -->
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
            <prop key="hibernate.query.substitutions">true 'Y', false 'N'</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.format_sql">false</prop>
            <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
            <!-- Hibernate Search index directory -->
            <prop key="hibernate.search.default.indexBase">target/index</prop>
            <prop key="current_session_context_class">thread</prop>
        </props>
    </property>
</bean>
// 自动注入SessionFactory
@Autowired
private SessionFactory sessionFactory;
1.2.2、获取Session的实例对象
 sessionFactory.getCurrentSession();
 // 当需要打开多个session时、采用openSession方法
 sessionFactory.openSession();
1.2.3、操作数据库

主要有三种方式:

HQL方式

HQL没有表和字段的概念,只有类、对象和属性的概念,即只操作java对象就相当于操作表。
注意:表名大小写不敏感,对象名大小写敏感
(1) 以"?"作为占位符,按索引入参

// from后的"User"为java类名,sql中对应的才是表名
String hql = "from User where id = ? ";
Query query = session.createQuery(hql);
// 索引从0开始
query.setInteger(0,666);
Object obj = query.uniqueResult();
User user = (User) obj ;
session.close();

(2)以变量名称作为占位符,按名称入参

// from后的"User"为java类名,sql中对应的才是表名
String hql = "from User where id = :uid ";
Query query = session.createQuery(hql);
query.setInteger("uid",666);
Object obj = query.uniqueResult();
User user = (User) obj ;
session.close();
Criteria方式

Criteria是一种比HQL更面向对象的查询方式。
(1)旧方式(5.2版本后不推荐)

Criteria criteria = session.createCriteria(Cat.class);
criteria.add(Restrictions.eq("name", "tom"));
List<Cat> list = criteria.list();

(2)5.2版本后推荐方式

// Create CriteriaBuilder
CriteriaBuilder builder = session.getCriteriaBuilder();
// Create CriteriaQuery
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
// 设置where条件
criteria.where(builder.like(root.get("loginName"), "%i%"));
// 创建query 查询
Query<User> query = session.createQuery(criteria);
// 返回结果
List<User> list = query.list();
原生SQL

违背了hibernate的跨平台特点,不宜维护,不面向对象,不推荐使用。

String sql = "select * from user where id = :uid";
NativeQuery query = session.createNativeQuery(sql);
query.setParameter("uid", 5);
List<Object[]> list = query.list();
List<User> userList = new ArrayList();
for(Object[] objs : list) {
	User user = new User();
	user.setId(objs[0].toString());
	user.setUsername(objs[1].toString());
	userList.add(user);
}
session.close();

2、常见使用场景

2.1、HQL 设置参数

// from后的"User"为java类名,sql中对应的才是表名
String hql = "from User where id = :uid ";
Query query = session.createQuery(hql);
query.setInteger("uid",666);
Object obj = query.uniqueResult();
User user = (User) obj ;
session.close();
// from后的"User"为java类名,sql中对应的才是表名
String hql = "from User where id = ?";
Query query = session.createQuery(hql);
query.setParameter(0,666);
Object obj = query.uniqueResult();
User user = (User) obj ;
session.close();

2.2、Criteria 多条件查询、排序、分页

// 上文获取session实例      
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
List<Predicate> predicateList = new ArrayList<>();
List<Order> orderList = new ArrayList<>();
predicateList.add(builder.equal(root.get("id"), 123);
predicateList.add(builder.like(root.get("name"), "zhangs"));
orderList.add(builder.desc(root.get("name")));
orderList.add(builder.asc(root.get("id"))      
Predicate[] predicates = predicateList.toArray(new Predicate[predicateList.size()]);
// 多个条件拼接
criteria.where(builder.and(predicates));
Order[] orders = orderList.toArray(new Order[orderList.size()]);
// 多个排序
criteria.orderBy(orders);
Query<User> query = session.createQuery(criteria);
// 分页,第1页,每页10条数据
query.setFirstResult(0);
query.setMaxResults(10);
List<User> result = query.list();
session.close();

2.3、原生SQL 多条件查询、排序、分页

StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("SELECT * FROM test_user WHERE 1 ");
// listBO是查询条件的对象
if (StringUtils.isNotEmpty(listBO.getUserName())) {
    sqlBuilder.append(" AND `name` LIKE '%:userName%'");
}
if (listBO.getStatus() != null) {
    sqlBuilder.append(" AND status = :status");
}
if (listBO.getOrderBy() != null) {
    sqlBuilder.append(" ORDER BY :orderBy :sort,id ASC ");
}
if (listBO.getOffset() != null && listBO.getLimit() != null) {
    sqlBuilder.append(" LIMIT :offSet,:limit");
}

Session session = null;
try {
    session = sessionFactory.openSession();
    NativeQuery query = session.createNativeQuery(sqlBuilder.toString());
    if (StringUtils.isNotEmpty(listBO.getUserName())) {
        query.setParameter("userName", listBO.getUserName());
    }
    if (listBO.getStatus() != null) {
        query.setParameter("status", listBO.getStatus());
    }
    if (listBO.getOrderBy() != null) {
        query.setParameter("orderBy", listBO.getOrderBy());
        query.setParameter("sort", listBO.getSort());
    }
    if (listBO.getOffset() != null && listBO.getLimit() != null) {
        query.setParameter("offSet", listBO.getOffset());
        query.setParameter("limit", listBO.getLimit());
    }
    query.addEntity(User.class);
    return query.list();
} catch (Exception e) {
    logger.error("query condition error listBO: {}", listBO);
    throw e;
} finally {
    if (session != null) {
        session.close();
    }
}

2.4、原生SQL count查询

String sql = "SELECT count(*) FROM test_user WHERE `name`=:name ";
Session session = null;
try {
    session = sessionFactory.openSession();
    NativeQuery query = session.createNativeQuery(sql);
    query.setParameter("name", name);
    return ((Number)query.uniqueResult()).intValue();
} catch (Exception e) {
    throw e;
} finally {
    if (session != null) {
        session.close();
    }
}

2.5、Criteria count查询

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Long> criteria = builder.createQuery(Long.class);
Root<User> root = criteria.from(User.class);
criteria.select(builder.count(root));
Query<Long> query = session.createQuery(criteria);
Long total = query.getSingleResult()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值