第二章 Hibernate4 CRUD 操作
第一节:HibernateUtil 封装
第二节:XML 版CRUD 实现
第三节:注解版 CRUD 实现
第四节:Junit4 单元测试框架引入
前言:
目录
(2)XML版CRUD实现。在StudentTest.java里,写方法,进行CRUD
前言:
CRUD)(增删改查): 增加(Create)、读取(Retrieve)、更新(Update)和删除(Delete)
(还是使用的是之前的项目)
一:
1.为什么要封装一个HibernateUtil?
答案:因为很多代码需要重复使用,每次都要写的话,太过于麻烦,所以封装起来,更方便人使用。
(1)建立:HibernateUtil,封装代码
右键【src】-【Class】
Package : util
Name : HibernateUtil -【Finish】
其内容如下:
源代码如下:
package util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateUtil {
//再来定义一个不可变的调用如下方法:
private static final SessionFactory sessionFactory=buildSessionFactory();
//首先定义一个获取工厂的方法。
private static SessionFactory buildSessionFactory(){
Configuration configuration=new Configuration().configure(); // 实例化配置文件
ServiceRegistry serviceRegistry=new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); // 实例化服务登记
return configuration.buildSessionFactory(serviceRegistry); // 获取Session工厂
}
//实时获取当前的Session工厂
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
这样,之前的StudentTest.java就不用那么复杂了:
使用封装之后的方法,它变成了如下的模样:
测试并运行了一下依旧是没有问题的。去看了看数据库也是添加进了内容的。
(2)XML版CRUD实现。在StudentTest.java里,写方法,进行CRUD
【注】
为什么说这个是XML版本的,因为这个是根据之前 对象的hibernate配置文件 进行的实现, 就是那个 Student.hbm.xml 文件。
这个方法与注解版CRUD的实现对比,这种方法是比较麻烦一点的方法。
它是以面向对象的形式增删改查。
【1】增加操作:
代码如下:
结果如下:
其源代码为:
private void add(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Student s=new Student();
s.setName("张三");
session.save(s);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
【2】删除操作:
代码如下:
结果如下:
源代码如下:
private void update()//更新的话同样也是获得一个实体并对其进行操作。
{
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Student student=(Student)session.get(Student.class,Long.valueOf(2));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
student.setName("张三2");
session.save(student);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
【3】更新操作:
代码如下:
结果如下;
这个原因是因为我更新了一下刚才被删除的id为1的同学的名字,由于已经被删除了,数据库里面没有id为1的,所以报错了。
所以我把valueOf(1)给改成了valueOf(2)
数据库删除数据成功。
源代码如下:
private void update()//更新的话同样也是获得一个实体并对其进行操作。
{
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Student student=(Student)session.get(Student.class,Long.valueOf(2));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
student.setName("张三2");
session.save(student);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
【4】查询数据:
代码如下:
结果如下:
在查询操作里,会用到sql,这里用到的是hql,这是一种面向对象的sql。
查询成功:
源代码如下:
private void getAllStudent(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
//查询的话用一下sql,这里用的是hql,hql是面向对象的sql
String hql="from Student";//直接from一个类
Query query=session.createQuery(hql);//查询
List<Student> studentList= query.list();//获取所有查询的数据
//为了打印方便,在Student类里添加方法。然后再用foreach的方法遍历对象
for(Student student:studentList)
{
System.out.println(student);
}
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
(3)整个StudentTest.java源代码如下:
package service;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import model.Student;
import util.HibernateUtil;
public class StudentTest {
private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
//SessionFactory因为每个操作都有用到它,所以拿到外面来。
private void add(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Student s=new Student();
s.setName("张三");
session.save(s);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
private void delete(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Student student=(Student)session.get(Student.class,Long.valueOf(1));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
session.delete(student);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
private void update()//更新的话同样也是获得一个实体并对其进行操作。
{
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Student student=(Student)session.get(Student.class,Long.valueOf(2));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
student.setName("张三2");
session.save(student);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
private void getAllStudent(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
//查询的话用一下sql,这里用的是hql,hql是面向对象的sql
String hql="from Student";//直接from一个类
Query query=session.createQuery(hql);//查询
List<Student> studentList= query.list();//获取所有查询的数据
//为了打印方便,在Student类里添加方法。然后再用foreach的方法遍历对象
for(Student student:studentList)
{
System.out.println(student);
}
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
public static void main(String[] args) {
//调用添加操作:
StudentTest studentTest=new StudentTest();
//studentTest.add();
//studentTest.delete();
//studentTest.update();
studentTest.getAllStudent();
}
}
(4)注解版CRUD实现:
右键【model】- 【New】 - 【Class】
Name : Teacher
文件内容:
文件源代码:
package model;
public class Teacher {
private long id;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//为了打印方便,把toString的方法重写
@Override
public String toString() {
return "Teacher [id=" + id + ", name=" + name + "]";
}
}
将StudentTest.java里面的内容复制粘贴到 TeacherTest.java文件中来。
然后快速替换其中内容:
replace all.
按出如上选项框的快捷键 : 详情请看我这篇文章:
https://blog.****.net/HDZ1821/article/details/104377004
TeacherTest.java 源代码:
package service;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import model.Teacher;
import util.HibernateUtil;
public class TeacherTest {
private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
//SessionFactory因为每个操作都有用到它,所以拿到外面来。
private void add(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher s=new Teacher();
s.setName("张三");
session.save(s);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
private void delete(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher Teacher=(Teacher)session.get(Teacher.class,Long.valueOf(1));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
session.delete(Teacher);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
private void update()//更新的话同样也是获得一个实体并对其进行操作。
{
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher Teacher=(Teacher)session.get(Teacher.class,Long.valueOf(2));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
Teacher.setName("张三2");
session.save(Teacher);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
private void getAllTeacher(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
//查询的话用一下sql,这里用的是hql,hql是面向对象的sql
String hql="from Teacher";//直接from一个类
Query query=session.createQuery(hql);//查询
List<Teacher> TeacherList= query.list();//获取所有查询的数据
//为了打印方便,在Teacher类里添加方法。然后再用foreach的方法遍历对象
for(Teacher Teacher:TeacherList)
{
System.out.println(Teacher);
}
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
public static void main(String[] args) {
//调用添加操作:
TeacherTest TeacherTest=new TeacherTest();
TeacherTest.add();
//TeacherTest.delete();
//TeacherTest.update();
TeacherTest.getAllTeacher();
}
}
然后再去 项目的hibernate配置文件中 添加关联:
运行TeacherTest.java文件
添加操作运行成功:
删除操作运行成功:
更新操作运行成功:
查询操作运行成功:
数据库表:
(5)Junit4 单元测试:
(1)引入原因:
可以发现每次,当测试代码的时候,每次都需要注释掉部分语句,这样子是非常麻烦的。
来来回回的反复注释,反复测试非常麻烦。
(2)创建junit包
因此引入单元测试:(需要新引入一个junit的jar包)
右键【Hibernate01】- 【New】-【Folder】
Floder Name : junit4
将jar包复制粘贴进去,然后对其进行【build path】操作,使其添加到路径里面去。
(3)如何使用junit 配置需要测试的文件
要用它的话,得有个要求,就是方法名称必须是public
就拿TeacherTest.java来举例,那么它其中的private方法都要改成public方法。
TeacherTest.java的源代码便如下了:
package service;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import model.Teacher;
import util.HibernateUtil;
public class TeacherTest {
private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
//SessionFactory因为每个操作都有用到它,所以拿到外面来。
public void add(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher s=new Teacher();
s.setName("张三");
session.save(s);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
public void delete(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher Teacher=(Teacher)session.get(Teacher.class,Long.valueOf(1));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
session.delete(Teacher);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
public void update()//更新的话同样也是获得一个实体并对其进行操作。
{
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher Teacher=(Teacher)session.get(Teacher.class,Long.valueOf(2));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
Teacher.setName("张三2");
session.save(Teacher);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
public void getAllTeacher(){
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
//查询的话用一下sql,这里用的是hql,hql是面向对象的sql
String hql="from Teacher";//直接from一个类
Query query=session.createQuery(hql);//查询
List<Teacher> TeacherList= query.list();//获取所有查询的数据
//为了打印方便,在Teacher类里添加方法。然后再用foreach的方法遍历对象
for(Teacher Teacher:TeacherList)
{
System.out.println(Teacher);
}
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
public static void main(String[] args) {
//调用添加操作:
TeacherTest TeacherTest=new TeacherTest();
//TeacherTest.add();
//TeacherTest.delete();
//TeacherTest.update();
TeacherTest.getAllTeacher();
}
}
右键【TeacherTest.java】-【New】-【JUnit Test Case】
Name : TeacherTest2
Which method stubs would you like to creat? (都不勾选。)
【Next】-【选择你要单元测试的几个方法。】
-【add() delete() update() getAllTeacher()】-【Next】
可以发现,
生成出来的TeacherTest2里面并未自动添加测试方法,因此需要自己进一步的复制粘贴,手动添加方法。
自行手动添加代码之后的TeacherTest2.java文件 源代码为:
package service;
import static org.junit.Assert.*;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.Test;
import model.Teacher;
import util.HibernateUtil;
public class TeacherTest2 {
private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
//SessionFactory因为每个操作都有用到它,所以拿到外面来。
@Test
public void testAdd() {
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher s=new Teacher();
s.setName("张三");
session.save(s);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
@Test
public void testDelete() {
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher Teacher=(Teacher)session.get(Teacher.class,Long.valueOf(1));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
session.delete(Teacher);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
@Test
public void testUpdate() {
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
Teacher Teacher=(Teacher)session.get(Teacher.class,Long.valueOf(2));
//session的get方法,前面写类,后面写主键,再进行强制类型转换
Teacher.setName("张三2");
session.save(Teacher);
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
@Test
public void testGetAllTeacher() {
Session session=sessionFactory.openSession(); // 生成一个session
session.beginTransaction(); // 开启事务
//查询的话用一下sql,这里用的是hql,hql是面向对象的sql
String hql="from Teacher";//直接from一个类
Query query=session.createQuery(hql);//查询
List<Teacher> TeacherList= query.list();//获取所有查询的数据
//为了打印方便,在Teacher类里添加方法。然后再用foreach的方法遍历对象
for(Teacher Teacher:TeacherList)
{
System.out.println(Teacher);
}
session.getTransaction().commit(); // 提交事务
session.close(); // 关闭session
//sessionFactory.close(); // 关闭session工厂
}
}
(4)如何使用junit 开始测试 运行
左击【TeacherTest2前面的下拉按钮】- 右键【testAdd()】-
【Run As】 - 【1 JUnit Test】
这样就能测试程序了。
但是我发现了一个非常奇怪的点!就是我点击它点击完了叭!程序运行了吧!
他还给我报错!报错啊!
JUnit测试报空指针异常。其解决方式:请看我这篇博文:
https://blog.****.net/HDZ1821/article/details/104395997
按照如上方式弄了之后,就能跑成功了:成功图如下:
插入成功:
删除成功:
更新成功:
查询成功: