SpringData之 介绍 和 Spring 整合 Hibernate

1. Spring Data课程中的技术介绍

(1) 什么是Hibernate?

Hibernate是一个开源的对象关系映射框架,它对JDBC进行了非常轻量级的封装,

它将POJO与数据表建立映射关系,是一个全自动化的ORM框架。

Hibernate可以自动生成sql语句,使程序员可以以对象的编程思维操作数据库。 Hibernate可以适用于任何使用JDBC的场景既可以在java的客户端程序使用,也可以在Servlet/Jsp的Web应用中使用。

最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

(2) 什么是JPA?

JPA是Java persistence API的缩写,中文名是Java持久层API。

是JDK 5.0注解或Xml方式描述“对象-数据表”的映射关系,并将运行期的实体对象持久化到数据库中。

Sun引入新的JPA ORM 规范的原因有两个:

1 简化现有Java EE和Java SE应用开发工作;

2 整合ORM技术,实现天下归一。

(3) 什么是Hibernate JPA?

Hibernate在3.2之后根据JPA规范提供了一套操作持久层的API。

(4) 什么是Spring Data?

Spring data的任务是为数据访问提供一个熟悉和一致的,基于Spring的编程模型,同时仍然保留底层数据存储的特殊特征。

(5) 什么是Spring Data JPA?

Spring Data JPA,更大的Spring Data系列的一部分,
使得轻松实现基于JPA的存储库变得很容易。
本模块涉及对基于JPA的数据访问层的增强支持。
它使得构建Spring支持的应用程序使用数据访问技术更加容易。

(6) 什么是Spring Data Redis

Spring Data Redis是更大的Spring Data系列的一部分,它提供了从Spring应用程序轻松配置和访问Redis的能力。它提供了用于与商店交互的低级和高级抽象,将用户从基础设施问题中解放出来。

2 Spring 整合 Hibernate

一、 创建项目

普通的java项目

二、 在配置文件中定义框架整合

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd 
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd"> 
<!-- 配置读取 properties 文件的工具类 --> 
<context:property-placeholder 
location="classpath:jdbc.properties"/> 
<!-- 配置 c3p0 数据库连接池 --> 
<bean id="dataSource" 
class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
<property name="jdbcUrl" value="${jdbc.url}"/> 
<property name="driverClass" value="${jdbc.driver.class}"/> 
<property name="user" value="${jdbc.username}"/> 
<property name="password" value="${jdbc.password}"/> 
</bean> 
<!-- 配置 Hibernate 的 SeesionFactory --> 
<bean id="sessionFactory" 
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 
<property name="dataSource" ref="dataSource"/> 
<!-- hibernateProperties 属性:配置与 hibernate 相关的内容,如显示 
sql 语句,开启正向工程 --> 
<property name="hibernateProperties"> 
<props> 
<!-- 显示当前执行的 sql 语句 --> 
<prop key="hibernate.show_sql">true</prop> 
<!-- 开启正向工程 --> 
<prop key="hibernate.hbm2ddl.auto">update</prop> 
</props> 
</property> 
<!-- 扫描实体所在的包 --> 
<property name="packagesToScan"> 
<list> 
<value>com.bjsxt.pojo</value></list> 
</property> 
</bean> 
<!-- 配置 Hibernate 的事务管理器 --> 
<bean id="transactionManager" 
class="org.springframework.orm.hibernate5.HibernateTransactionManager"> 
<property name="sessionFactory" ref="sessionFactory"/> 
</bean> 
<!-- 配置开启注解事务处理 --> 
<tx:annotation-driven transaction-manager="transactionManager"/> 
<!-- 配置 springIOC 的注解扫描 --> 
<context:component-scan base-package="com.bjsxt"/> 
</beans> 

三、 通过 Hibernate 完成 CRUD 操作

1 创建数据库

2 编写实体类

(1) @Entity注解的作用是什么?

表示当前类是一个实体类。

(2) @Table注解的作用是什么?

1告诉Hibernate当前对象和名为name的数据表的有映射关系。

2同时如果开启了Hibernate的正向工程功能,生成的数据表名为name指定。

(3) @Id注解的作用是什么?

表示为数据表的主键

(4) @GeneratedValue注解的作用是什么?

指定主键生成策略,这里用的策略是自增长。

(5) @Column注解的作用是什么?

1告诉Hibernate当前对象的属性和数据表中的名为“Column中name”的字段是对应的,需要做映射处理。

2在正向工程中生成的数据表中也会生成这个字段。

@Entity 
@Table(name="t_users") 
public class Users implements Serializable{ 
@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY)//strategy=Gene 
rationType.IDENTITY 自增长 
@Column(name="userid") 
private Integer userid; 
@Column(name="username") 
private String username; 
@Column(name="userage") 
private Integer userage; 
public Integer getUserid() { 
return userid; 
}
public void setUserid(Integer userid) { 
this.userid = userid; 
}
public String getUsername() { 
return username; 
}
public void setUsername(String username) { 
this.username = username; 
}
public Integer getUserage() { 
return userage; 
}
public void setUserage(Integer userage) { 
this.userage = userage; 
} 
}

3 编写 UserDao 接口与接口实现类

3.1修改配置文件,添加 HibernateTemplate 的配置

<!-- 配置 HiberanteTemplate 对象 --> 
<bean id="hibernateTemplate" 
class="org.springframework.orm.hibernate5.HibernateTemplate"> 
<property name="sessionFactory" ref="sessionFactory"/> 
</bean> 

3.2接口实现类

(1) @Repository注解的作用是什么?

创建Dao层接口后实现接口时添加@Repository才能被Spring实例化出来。

Dao和实现类需要注意的:

这里我们需要使用Spring针对Hibernate操作的对象,封装了对Hibernate操作的模板叫HibernateTemplate。对于这个对象的使用有两种方式,

1 继承

2 再配置文件中配置,然后注解方式

<!-- 配置 HiberanteTemplate 对象 --> 
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
 <property name="sessionFactory" ref="sessionFactory"/>
 </bean> 


好处是不用继承,如果这里需要继承其他类就不方便了。

不管哪种方式都要注意,HibernateTemplate这个对象需要sessionFactory。HibernateDaoSupport中有个属性叫sessionFactory。

@Repository 
public class UsersDaoImpl implements UsersDao { 
@Autowired 
private HibernateTemplate hibernateTemplate; 
@Override 
public void insertUsers(Users users) { 
this.hibernateTemplate.save(users); 
}
@Override 
public void updateUsers(Users users) { 
this.hibernateTemplate.update(users); 
}
@Override 
public void deleteUsers(Users users) { 
this.hibernateTemplate.delete(users); 
}
@Override 
public Users selectUsersById(Integer userid) { 
return this.hibernateTemplate.get(Users.class, userid); 
} 
}

3.3编写测试代码

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("classpath:applicationContext.xml") 
public class UsersDaoImplTest { 
@Autowired 
private UsersDao usersDao; 
/**
* 添加用户 
*/ 
@Test 
@Transactional// 在测试类对于事务提交方式默认的是回滚。 
@Rollback(false)//取消自动回滚 
public void testInsertUsers(){ 
Users users = new Users(); 
users.setUserage(20); 
users.setUsername("张三"); 
this.usersDao.insertUsers(users); 
}
/**
* 更新用户 
*/ 
@Test 
@Transactional 
@Rollback(false) 
public void testUpdateUsers(){ 
Users users = new Users(); 
users.setUserid(2); 
users.setUserage(22); 
users.setUsername("李四"); 
this.usersDao.updateUsers(users); 
}
/**
* 根据 userid 查询用户 
*/ 
@Test 
public void testSelectUsersById(){ 
Users users = this.usersDao.selectUsersById(2); 
System.out.println(users);}
/**
* 删除用户 
*/ 
@Test 
@Transactional 
@Rollback(false) 
public void testDeleteUsers(){ 
Users users = new Users(); 
users.setUserid(2); 
this.usersDao.deleteUsers(users); 
} 
} 

四、 HQL 查询

HQL:Hibernate Query Language

HQL 的语法:就是将原来的 sql 语句中的表与字段名称换成对象与属性的名称就可以了

(1) 什么是HQL语言?

HQL是Hibernate Query Language(Hibernate 查询语言)的缩写,提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法。

Hibernate 查询语言(HQL)是一种面向对象的查询语言,类似于 SQL,但不是去对表和列进行操作,而是面向对象和它们的属性。 HQL 查询被 Hibernate 翻译为传统的 SQL 查询从而对数据库进行操作。

执行HQL查询的步骤:

1、获得HibernateSession对象

2、编写HQL语句

3、调用Session的createQuery方法创建查询对象

4、如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值

5、调用Query对象的list等方法返回查询结果。

(2) HQL语言的语法是什么?

就是将原来的 sql 语句中的表与字段名称换成对象与属性的名称就可以了

(3) getCurrentSession与openSession的区别?

1、getCurrentSession返回的是当前session,而openSession是创建一个新的session

2、getCurrentSession返回的session,当Transaction在commit时会自动关闭,而openSession返回的session必须显示调用session.close()进行关闭。

1 添加查询方法

@Override 
public List<Users> selectUserByName(String username) { 
//getCurrentSession:当前 session 必须要有事务边界,且只能处理唯一 
的一个事务。当事务提交或者回滚后 session 自动失效 
//openSession:每次都会打开一个新的 session.加入每次使用多次。则获 
得的是不同 session 对象。使用完毕后我们需要手动的调用 colse 方法关闭 session 
Session session = 
this.hibernateTemplate.getSessionFactory().getCurrentSession(); 
//sql:select * from t_users where username = 
Query query = session.createQuery("from Users where username 
= :abc");
Query queryTemp = query.setString("abc",username); 
return queryTemp.list(); 
} 
2 测试代码 
/*** HQL 测试 
*/ 
@Test 
@Transactional 
public void testSelectUserByName(){ 
List<Users> list = this.usersDao.selectUserByName("张三"); 
for (Users users : list) { 
System.out.println(users); 
} 
} 

五、 SQL 查询

1 添加查询方法

@Override 
public List<Users> selectUserByNameUseSQL(String username) { 
Session session = 
this.hibernateTemplate.getSessionFactory().getCurrentSession(); 
Query query = session.createSQLQuery("select * from t_users 
where username = ?").addEntity(Users.class).setString(0, username); 
return query.list(); 
} 

2 测试代码

@Test 
@Transactional 
public void testSelectUserByNameUseSQL(){ 
List<Users> list = this.usersDao.selectUserByNameUseSQL("张三 
"); 
for (Users users : list) { 
System.out.println(users); 
} 
} 

六、 QBC 查询

QBC:Query By Criteria1 添加查询方法

@Override 
public List<Users> selectUserByNameUseCriteria(String username) { 
Session session = 
this.hibernateTemplate.getSessionFactory().getCurrentSession(); 
//sql:select * from t_users where username = 张三 
Criteria c = session.createCriteria(Users.class); 
c.add(Restrictions.eq("username", username)); 
return c.list(); 
} 

2 测试代码


@Test 
@Transactional 
public void testSelectUserByNameUseCriteria(){ 
List<Users> list = this.usersDao.selectUserByNameUseCriteria(" 
张三"); 
for (Users users : list) { 
System.out.println(users); 
} 
}

SpringData 第二章 Spring 整合 Hibernate JPA

JPA:由 Sun 公司提供了一对对于持久层操作的标准(接口+文档)

Hibernate:是 Gavin King 开发的一套对于持久层操作的自动的 ORM 框架。

Hibernate JPA:是在 Hibernate3.2 版本那种提供了对于 JPA 的标准的实现。提供了一套按 照 JPA 标准来实现持久层开发的 API 。


Spring 整合 Hibernate JPA

1 创建项目:

2 在项目中导入 HIbernateJPA 相关的 jar 包

Hibernate-entitymanager-5.0.7-Final.jar

3 修改配置文件

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd 
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd"> 
<!-- 配置读取 properties 文件的工具类 --> 
<context:property-placeholder 
location="classpath:jdbc.properties"/> 
<!-- 配置 c3p0 数据库连接池 --> 
<bean id="dataSource" 
class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
<property name="jdbcUrl" value="${jdbc.url}"/> 
<property name="driverClass" value="${jdbc.driver.class}"/><property name="user" value="${jdbc.username}"/> 
<property name="password" value="${jdbc.password}"/> 
</bean> 
<!-- Spring 整合 JPA 配置 EntityManagerFactory--> 
<bean id="entityManagerFactory" 
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBe 
an"> 
<property name="dataSource" ref="dataSource"/> 
<property name="jpaVendorAdapter"> 
<bean 
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
<!-- hibernate 相关的属性的注入 --> 
<!-- 配置数据库类型 --> 
<property name="database" value="MYSQL"/> 
<!-- 正向工程 自动创建表 --> 
<property name="generateDdl" value="true"/> 
<!-- 显示执行的 SQL --> 
<property name="showSql" value="true"/> 
</bean> 
</property> 
<!-- 扫描实体的包 --> 
<property name="packagesToScan"> 
<list> 
<value>com.bjsxt.pojo</value> 
</list> 
</property> 
</bean> 
<!-- 配置 Hibernate 的事务管理器 --> 
<bean id="transactionManager" 
class="org.springframework.orm.jpa.JpaTransactionManager"> 
<property name="entityManagerFactory" 
ref="entityManagerFactory"/> 
</bean> 
<!-- 配置开启注解事务处理 --> 
<tx:annotation-driven transaction-manager="transactionManager"/> 
<!-- 配置 springIOC 的注解扫描 --> 
<context:component-scan base-package="com.bjsxt"/> 
</beans>


二、 Hibernate JPA 的 CRUD 操作

1 接口实现类

(1) @PersistenceContext注解的作用是什么?

注入的是实体管理器,执行持久化操作的,需要配置文件persistence.xml。

注入一堆保存实体类状态的数据结构,针对实体类的不同状态(四种,managedh或detached等)可以做出不同的反应(merge,persist等等),其实就是把数据从数据库里提出,然后在内存里处理的,再返回数据库的法则。

@Repository 
public class UsersDaoImpl implements UsersDao { 
@PersistenceContext(name="entityManagerFactory") 
private EntityManager entityManager; 
@Override 
public void insertUsers(Users users) { 
this.entityManager.persist(users); 
}
@Override 
public void updateUsers(Users users) { 
this.entityManager.merge(users); 
}
@Override 
public void deleteUsers(Users users) { 
Users u = this.selectUsersById(users.getUserid()); 
this.entityManager.remove(u); 
}
@Override 
public Users selectUsersById(Integer userid) { 
return this.entityManager.find(Users.class, userid); 
}
//Hibernate JPA 中的 HQL 语句
@Override 
public List<Users> selectUserByName(String username) { 
return this.entityManager.createQuery(" from Users where username = :abc")
    .setParameter("abc", username).getResultList(); 
}
//HibernateJPA 中的 SQL 语句 
@Override 
public List<Users> selectUserByNameUseSQL(String username) { 
return this.entityManager.createQuery("select *  from t_users where username = :abc")
         .setParameter("abc", username).getResultList(); 
}
//HibernateJPA 中 QBC 查询 
@Override 
public List<Users> selectUserByNameUseCriteria(String username) {
//CriteriaBuilder 对象:创建一个 CriteriaQuery,创建查询条件。 
CriteriaBuilder builber = this.entityManager.getCriteriaBuilder(); 
//CriteriaQuery 对象:执行查询的 Criteria 对象 
//select * from t_users 
CriteriaQuery<Users> query = builber.createQuery(Users.class); 
//获取要查询的实体类的对象 
Root<Users> root = query.from(Users.class); 
//封装查询条件 
Predicate cate = builber.equal(root.get("username"), username);
//select * from t_users where username = 张三 
query.where(cate); 
//执行查询 
TypedQuery<Users> typeQuery = this.entityManager.createQuery(query); 
return typeQuery.getResultList(); 
} 
} 

发布于 2019-08-20 17:56