使用maven的pom.xml导入Jar包
1、需要导入Spring所需的Jar包、Hibernate相关的Jar包
//Spring所需的Jar包
spring-beans、spring-context、spring-core、spring-orm、spring-tx
//Hibernate相关的Jar包
antlr、classmate、dom4j、hibernate-core、hibernate-jpa、jandex、javassist、jboss-logging、jboss-transaction
//数据库连接Jar包
mysql-connector-java
//数据库连接池jar包
com.mchange.C3P0
2、pom.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zbt</groupId>
<artifactId>environment_springhibertnate</artifactId>
<version>1.0-SNAPSHOT</version>
<name>environment_springhibertnate</name>
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!-- hibernate 需要的12个jar包
antlr、classmate、dom4j、hibernate-core、hibernate-jpa
jandex、javassist、jboss-logging、jboss-transaction、mysql、-->
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml</groupId>
<artifactId>classmate</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.15.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jandex</artifactId>
<version>2.0.3.Final</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.22.0-GA</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.1_spec</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<!-- 配置com.mchange/c3p0连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!--配置Spring相关的Jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
</build>
</project>
2、Hibernate映射文件
2.1、编写Student类实体类
public class Student
{
private int id;
private String firstName;
private String lastName;
private String address;
private String phone;
public Student() {
}
public Student(int id,String firstName,String lastName,String address,String phone){
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.phone = phone;
}
//省略了属性的getters方法和setters方法以及toString方法
}
2.2、Hibernate的映射文件Student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zbt">
<class name="Student" table="student">
<id name="id" column="id">
<generator class="identity"/>
</id>
<property name="firstName" column="firstname"/>
<property name="lastName" column="lastname"/>
<property name="address" column="address"/>
<property name="phone" column="phone"/>
</class>
</hibernate-mapping>
2.3、数据库配置文件–jdbc.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/pagination
jdbc.user=root
jdbc.password=?????
3、Spring上下文配置
3.1、数据库接入层代码
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Created by luckyboy on 2018/6/29.
*/
public class StudentDao {
private SessionFactory sessionFactory;
public StudentDao(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
}
3.2、配置文件applicationConfig.xml
- 3.2.1、使用c3p0配置数据源
<!-- 使用配置文件的方式需要指明配置文件jdbc.properties的位置-->
<context:property-placeholder location="classpath:/jdbc.properties"/>
<!--使用c3p0数据源配置数据库连接的相关信息-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
- 3.2.2、将数据源注入到SessionFactory当中
<!--使用hibernateProperties + DataSource的方式取代hibernate.cfg.xml文件-->
<bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>Student.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
</props>
</property>
</bean>
- 3.2.3、将sessionFactory注入到StudentDao中
//第一种方式:这里使用的是配置的方式将SessionFactory注入StudentDao中
<bean id="studentDao" class="com.zbt.StudentDao">
<constructor-arg name="sessionFactory" ref="mySessionFactory"/>
</bean>
//第二种方式:使用注解的方式在StudentDao类上添加@Repositroy、在SessionFactory属性上添加@Autowired
@Repository(value="studentDao")
public class StudentDao {
@Autowired
private SessionFactory sessionFactory;
}
- 3.2.4、配置Spring事务管理
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
- 3.2.5、配置包扫描和注解驱动(因为使用了@Transactional注解)
<context:component-scan base-package="com.zbt"/>
<tx:annotation-driven/>
- 3.2.6、最终的Spring上下文配置文件applicationConfig.xml
<?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: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-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd ">
<!--使用c3p0配置 使用配置文件的方式需要指明配置文件的位置-->
<context:component-scan base-package="com.zbt"/>
<tx:annotation-driven/>
<context:property-placeholder location="classpath:/jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--使用hibernateProperties + DataSource的方式取代hibernate.cfg.xml文件-->
<bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>Student.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
</props>
</property>
</bean>
<bean id="studentDao" class="com.zbt.StudentDao">
<constructor-arg name="sessionFactory" ref="mySessionFactory"/>
</bean>
<!--将事务交给Spring管理-->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
</beans>
上面就是所做的就是环境搭建完成了。下面使用Hibernate的查询语句进行增删改查操作
4、Hibernate查询语句
在StudentDao中添加Hibernate查询方法,在TestStudent中添加测试方法
4.1、实现添加一个Student对象到数据库中
/**
* 使用Session.save(Object object)方法保存某一个对象到数据库中
* @param stu
*/
@Transactional
public void saveStudent(Student stu){
this.sessionFactory.openSession().save(stu);
}
测试代码
@Test
public void testSaveStudent(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
Student stu = new Student(1,"YU","Delaing","HeNan","1345678912");
stuDao.saveStudent(stu);
}
输出结果
Hibernate: insert into student (firstname, lastname, address, phone) values (?, ?, ?, ?)
4.2、更新Student的某一个属性
/**
* 根据旧的用户名更改成新的用户名
* @param newName
* @param oldName
*/
@Transactional
public void updateStudent(String newName,String oldName){
String hqlUpdate="update Student s set s.firstName= :newName where s.firstName = :oldName";
this.sessionFactory.getCurrentSession().createQuery(hqlUpdate).
setParameter("newName",newName).
setParameter("oldName",oldName).executeUpdate();
}
测试代码
@Test
public void testUpdateStudentFisrtName(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
String newFirstName = "Zou";
String oldFirstName = "Yu";
stuDao.updateStudent(newFirstName,oldFirstName);
}
输出结果
Hibernate: update student set firstname=? where firstname=?
4.3、根据Student属性查询
/**
* 根据用户的id进行查询,返回一个Student对象,如果不存在则返回null
* 下面使用了两种通过id查询用户的方式,第一种是通过
* 第一种:Session.get(Class<T> class,Serializable id)这种方式只适合用于对id进行查询
* 第二种:createQuery(hql).setParameter(int position,Object val)注意这里的position的位置是从0开始的;适合对多个属性进行联合查询
* @param id
* @return
*/
@Transactional
public Student getStudentById(int id){
String sql = "select student from Student student where id= :id";
return (Student) this.sessionFactory.getCurrentSession().createQuery(sql,Student.class).setParameter("id",id).uniqueResult();
}
测试代码
@Test
public void testGetStudentById(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
Object object = stuDao.getStudentById(10);
System.out.println(object.toString());
}
输出结果
Hibernate: select student0_.id as id1_0_, student0_.firstname as firstnam2_0_, student0_.lastname as lastname3_0_, student0_.address as address4_0_, student0_.phone as phone5_0_ from student student0_ where student0_.id=?
Student{id=10, firstName='Zhao', lastName='Gao', address='Hunan', phone='12345678912'}
4.5、删除Student信息
/**
* 通过firstName来删除数据库中对应的数据
* @param firstName
*/
@Transactional
public void deleteStudentByFirstName(String firstName){
String sql = "delete from Student student where student.firstName=:firstName";
this.sessionFactory.getCurrentSession().createQuery(sql).setParameter("firstName",firstName).executeUpdate();
}
测试代码
@Test
public void testdeleteStudentByFirstName(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
stuDao.deleteStudentByFirstName("Zou");
}
输出结果
Hibernate: delete from student where firstname=?
4.6、查询所有的Student信息
/**
* 使用Session.createQuery(String sql)的方式进行查询,
* 返回一个Query,调用Query.list() 方法返回Student对象
* 注意:from子句后面跟的是我们Student这个类的类名,而不是数据库名
*
* @return
*/
@Transactional
public List<Student> queryStudent(){
String sql="select student from Student student";
Query query = this.sessionFactory.getCurrentSession().createQuery(sql);
return query.list();
}
测试代码
@Test
public void queryStudentByHql(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
List<Student> strList = stuDao.queryStudent();
if(strList != null){
for(Student str: strList){
System.out.println(str.toString());
}
}else{
System.out.println("strList is null");
}
}
输出结果
Hibernate: select student0_.id as id1_0_, student0_.firstname as firstnam2_0_, student0_.lastname as lastname3_0_, student0_.address as address4_0_, student0_.phone as phone5_0_ from student student0_
Student{id=4, firstName='Wu', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=5, firstName='Zhou', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=6, firstName='Sun', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=7, firstName='Li', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=8, firstName='Liu', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=9, firstName='Wang', lastName='Tao', address='Hunan', phone='12345678912'}
Student{id=10, firstName='Zhao', lastName='Gao', address='Hunan', phone='12345678912'}
Student{id=11, firstName='Li', lastName='Mazi', address='Hunan', phone='12345678912'}
Student{id=12, firstName='Zhang', lastName='Mazi', address='Hunan', phone='12345678912'}
Student{id=13, firstName='Zheng', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=14, firstName='Wang', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=15, firstName='Zeng', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=16, firstName='Qiu', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=17, firstName='Dan', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=18, firstName='Hua', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=19, firstName='Mao', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=20, firstName='Li', lastName='Feng', address='GuangXi', phone='12345678998'}
Student{id=28, firstName='Zou', lastName='Delaing', address='HeNan', phone='1345678912'}
4.7、如果返回的我们查询的对象不存在,返回的List对象不是Null
@Transactional
public List<Student> queryStudentByLastName(String lastName){
String hql = "select s from Student as s where lastName= :lastName";
return (List<Student>) this.sessionFactory.getCurrentSession().createQuery(hql).setParameter("lastName",lastName).list();
}
@Test
public void testQueryStudentByLastName(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
List<Student> list = stuDao.queryStudentByLastName("Die");
if(list == null){
System.out.println("当前用户不存在,返回的List对象为空");
}
if(list.size() == 0){
System.out.println("当前用户不存在,但是返回的List对象不为null");
}
}
输出结果
Hibernate: select student0_.id as id1_0_, student0_.firstname as firstnam2_0_, student0_.lastname as lastname3_0_, student0_.address as address4_0_, student0_.phone as phone5_0_ from student student0_ where student0_.lastname=?
当前用户不存在,但是返回的List对象不为空
4.8、使用聚集函数count()查询database中Student的数量
需要注意的是我们这里返回的是Long类型的数据,不要用Integer类型的数据
@Transactional
public Long countStudent(){
String hql = "select count(id) as total from Student";
return (Long)this.sessionFactory.getCurrentSession().createQuery(hql).uniqueResult();
}
测试代码
@Transactional
public Long countStudent(){
String hql = "select count(id) as total from Student";
return (Long)this.sessionFactory.getCurrentSession().createQuery(hql).uniqueResult();
}
输出结果
Hibernate: select count(student0_.id) as col_0_0_ from student student0_
the number of studne in database is : 18
4.9、使用Hibernate实现分页查询,主要用到的Query中的两个方法
Query.setFirstResult(int row) //设置查询的起始行,从零开始,0表示第一行,和Limit中的第一个参数一致
Query.setMaxResult(int row)//设置返回的最大行数
@Transactional
public List<Student> getLimitStudents(int pageNum,int pageSize){
String hql = "select s from Student as s";
Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
query.setFirstResult(pageNum*pageSize);//设置起始行
query.setMaxResults(pageSize);//设置查询最大的返回结果
return query.list();
}
测试代码
@Test
public void testGetLimitStudent(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
int pageNum = 0;
int pageSize = 5;
List<Student> stus = stuDao.getLimitStudents(pageNum,pageSize);
for(Student stu:stus){
System.out.println(stu.toString());
}
}
输出结果
Hibernate: select student0_.id as id1_0_, student0_.firstname as firstnam2_0_, student0_.lastname as lastname3_0_, student0_.address as address4_0_, student0_.phone as phone5_0_ from student student0_ limit ?
Student{id=4, firstName='Wu', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=5, firstName='Zhou', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=6, firstName='Sun', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=7, firstName='Li', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=8, firstName='Liu', lastName='BaiTao', address='Hunan', phone='12345678912'}
我们看一下使用Mysql的LIMIT关键字查询结果,与上面的结果是一样的。
mysql> select *from student limit 0,5;
+----+-----------+----------+---------+-------------+
| id | firstname | lastname | address | phone |
+----+-----------+----------+---------+-------------+
| 4 | Wu | BaiTao | Hunan | 12345678912 |
| 5 | Zhou | BaiTao | Hunan | 12345678912 |
| 6 | Sun | BaiTao | Hunan | 12345678912 |
| 7 | Li | BaiTao | Hunan | 12345678912 |
| 8 | Liu | BaiTao | Hunan | 12345678912 |
+----+-----------+----------+---------+-------------+
4.10、使用POJO的方式封装特定的对象
@Transactional
public List<Student> queryStudentByLastName(String lastName){
String hql = "select new Student(id,firstName) from Student as s where lastName= :lastName";
return (List<Student>) this.sessionFactory.getCurrentSession().createQuery(hql).setParameter("lastName",lastName).list();
}
注意上面我们使用了 new Student(id,firstName)将我们查询的结果进行封装了,
select new Student(id,firstName) from Student as s where lastName= :lastName"
这种情况下我们必须要在Student中添加相应的构造方法
public Student(int id,String firstName){
this.id = id;
this.firstName = firstName;
}
测试代码
@Test
public void testQueryStudentByLastName(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
List<Student> list = stuDao.queryStudentByLastName("Mazi");
for(Student stu:list){
System.out.println(stu.toString());
}
}
输出结果
Student{id=11, firstName='Li', lastName='null', address='null', phone='null'}
Student{id=12, firstName='Zhang', lastName='null', address='null', phone='null'}
4.11、使用Hibernate执行批量插入数据
@Transactional
public void batchInsertStudents(List<Student> stuList){
Session session = this.sessionFactory.getCurrentSession();
for(int i = 0 ;i<stuList.size();i++){
session.save(stuList.get(i));
if(i%20 == 0){
session.flush();
session.clear();
}
}
}
测试代码
@Test
public void testBatchInsert(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
List<Student> stuList = new ArrayList<Student>(10000);
for(int i = 0;i<10000;i++) {
Student stu = new Student(i, "firstName" + i, "lastName" + i, "address" + i, "phone" + i);
stuList.add(stu);
}
stuDao.batchInsertStudents(stuList);
}
从结果我们可以看到,返回的Student对象确实只封装了我们想要的信息