【HIbernate学习】HIbernate保存更新操作(四)

HIbernate中有save()、persist()、saveOrUpdate()3种方法可以进行保存操作,外加SQL插入语句的执行,总共四种实现插入操作的方式。现在我们就来讲解下它们的使用和区别。

保存操作

  • save()

@Test
	public void saveForNew() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setName("张三");
			student.setAge("21");
			student.setId("23");
			Serializable id_s = session.save(student);
			System.out.println(id_s);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
4028bcc267ca6c4d0167ca6c4f360000
Hibernate: insert into Student (AGE, NAME, id) values (?, ?, ?)

 save()方法返回Serializable类型的数据库标识符,与数据库里面的值一致。如果实体中有定义主键生成策略,则指定ID的值将无效,但不报错。

@Test
	public void saveForGet() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student = session.get(Student.class, "4028bcc267ca6c4d0167ca6c4f360000");
			student.setName("wanglaosi3");
			session.save(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
Hibernate: update Student set AGE=?, NAME=? where id=?

 当实体不是新建,而是从数据库获取的持久态数据,save()方法不是执行保存操作,而是更新。 

  • persist()

@Test
	public void persistForNew() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setName("张三");
			student.setAge("21");
			session.persist(student);
			System.out.println(student.getId());
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
4028bcc267ca73e20167ca73e4250000
Hibernate: insert into Student (AGE, NAME, id) values (?, ?, ?)

  persist()方法没有返回值。

@Test
	public void persistForNew() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setName("张三");
			student.setAge("21");
			student.setId("22");
			session.persist(student);
			System.out.println(student.getId());
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
org.hibernate.PersistentObjectException: detached entity passed to persist: com.hibernate.demo.entity.Student

注意:当实体里面有设置主键生成策略时,方法中不能再给实体赋值,否则会报错。 

@Test
	public void persistForGet() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student = session.get(Student.class, "4028bcc267ca6c4d0167ca6c4f360000");
			student.setName("wanglaosi");
			session.persist(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
Hibernate: update Student set AGE=?, NAME=? where id=?

当实体不是新建,而是从数据库获取的持久态数据,与save()方法一样persist()方法不是执行保存操作,而是更新。  

  • insert语句

@Test
	public void saveBySql() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			String sql = "insert into Student (id,name,age) values (?,?,?)";
			Query query = session.createSQLQuery(sql);
			query.setString(0, "22");
			query.setString(1, "张三");
			query.setString(2, "22");
			query.executeUpdate();
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: insert into Student (id,name,age) values (?,?,?)

 因为HIbernate里面没有hql新增操作,所以语句操作只有sql。

更新操作

  • update()

@Test
	public void updateFromGet() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = session.load(Student.class, "22");
			student.setName("李四");
			session.update(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
Hibernate: update Student set AGE=?, NAME=? where id=?

注意:如果获取的ID不存在会报错,获取实体的方式不同报错也不相同,后面讲查询操作的时候再详细讲解。

  • get()方法报错信息
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
java.lang.NullPointerException
  • load()方法报错信息
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.hibernate.demo.entity.Student#22222]
  • update Sql语句 

@Test
	public void updateBySql() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			String sql = "update Student set name=? where id=?";
			Query query = session.createSQLQuery(sql);
			query.setString(0, "王五");
			query.setString(1, "2222");
			query.executeUpdate();
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: update Student set name=? where id=?

 注意:sql语句执行update操作,不会验证ID是否存在,所以不会报错。

  • update Hql语句

@Test
	public void updateByHql() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			String hql = "update Student set name=? where id=?";
			Query query = session.createQuery(hql);
			query.setString(0, "赵六");
			query.setString(1, "21");
			query.executeUpdate();
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
十二月 25, 2018 4:06:24 下午 org.hibernate.hql.internal.ast.HqlSqlWalker generatePositionalParameter
WARN: [DEPRECATION] Encountered positional parameter near line 1, column 62 in HQL: [update com.hibernate.demo.entity.Student set name=? where id=?].  Positional parameter are considered deprecated; use named parameters or JPA-style positional parameters instead.
Hibernate: update Student set NAME=? where id=?

 注意:hql语句执行update操作,不会验证ID是否存在,所以不会报错。但是会有一段警告信息。这是因为HIbernate4.1之后对于HQL中查询参数的占位符做了改进,如果仍然用老式的占位符会有类似如下的告警信息。

// 解决updateByHql的占位符警告
	@Test
	public void updateByHqlWithOutWarn() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			String hql = "update Student set name=:name where id=:id";
			Query query = session.createQuery(hql);
			query.setParameter("name", "赵四");
			query.setParameter("id", "21");
			query.executeUpdate();
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: update Student set name=? where id=?

 更新保存操作

  • saveOrUpdate()

@Test
	public void saveOrUpdateByNew() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setName("王四33");
			student.setAge("21");
			student.setId("4028bcc267ca6c4d0167ca6c4f360000");
			session.saveOrUpdate("Student", student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

saveOrUpdate方法有2种用户

  • 不设置ID值时,执行保存操作。
Hibernate: insert into Student (AGE, NAME, id) values (?, ?, ?)
  • 设置ID时,执行更新操作。
Hibernate: update Student set AGE=?, NAME=? where id=?
  • 当实体不是新建,而是从数据库获取的持久态数据时,执行更新操作。
@Test
	public void saveOrUpdateByGet() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student = session.get(Student.class, "4028bcc267ca6c4d0167ca6c4f360000");
			student.setName("王四33");
			session.saveOrUpdate("Student", student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
Hibernate: update Student set AGE=?, NAME=? where id=?

注意:如果设置的ID在数据库中没有对应数据的时会报错。

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
  • merge()

现在说一个神奇的merge()方法。先来看例子

  • 新建实体,不设置ID
@Test
	public void mergeForNew_NoId() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setAge("22");
			student.setName("wanglaosi3");
			session.merge(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: insert into Student (AGE, NAME, id) values (?, ?, ?)
  • 新建实体,设置ID,ID不存在
@Test
	public void mergeForNew_IdNoExist() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setId("23");
			student.setAge("22");
			student.setName("wanglaosi3");
			session.merge(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
Hibernate: insert into Student (AGE, NAME, id) values (?, ?, ?)
  • 新建实体,设置ID,ID存在
@Test
	public void mergeForNew_IdExist() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setId("22");
			student.setAge("22");
			student.setName("wanglaosi3");
			session.merge(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
Hibernate: update Student set AGE=?, NAME=? where id=?
  • 查询实体
@Test
	public void mergeForGet() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student = session.get(Student.class, "4028bcc267ca7fa80167ca7faa100000");
			student.setName("wanglaosi3");
			session.merge(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
Hibernate: select student0_.id as id1_0_0_, student0_.AGE as AGE2_0_0_, student0_.NAME as NAME3_0_0_ from Student student0_ where student0_.id=?
Hibernate: update Student set AGE=?, NAME=? where id=?

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值