Hibernate的批量更新与删除(&&JDBC)

更新&&删除

语法格式:(HQL)

update  |     delete from? <ClassName> [where where_conditions]

1>在from子句中,from关键字是可选的,即完全可以不写from关键字

2>在from子句中,只能有一个类名,可以在该类名后指定别名

3>不能在批量HQL语句中使用连接,显示或者隐式的都不行,但可以在where子句中使用子查询

4>整个where子句是可选的,where子句的语法sql语句中where子句的语法完全相同

5>Query.executeUpdate()方法返回一个整型值,该值是受此操作影响的记录数量,由于hibernate的底层操作实际上是由JDBC完成的,因此,如果有批量update或delete操作被转换成多条update或delete语句,(关联或者继承映射),该方法只能返回最后一条sql语句影响的记录行数,不是所有的记录行数,需要注意;


一,批量更新(两种方式)

1,使用Hibernate直接进行批量更新

(1)方式1:(Hibernate的HQL直接支持update/delete的批量更新语法)

<span style="font-size:18px;">package com.anlw.util;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class SessionUtil {
	Configuration conf = null;
	ServiceRegistry st = null;
	SessionFactory sf = null;
	Session sess = null;
	Transaction tx = null;

	public void HIbernateTest() {
		conf = new Configuration().configure();
		st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
		sf = conf.buildSessionFactory(st);
		try {
			sess = sf.openSession();
			tx = sess.beginTransaction();
			//在HQL查询中使用update进行批量更新,下面的的语句是HQL语句,不是sql语句
			Query query = sess.createQuery("update Student set name = 'www'");
			query.executeUpdate();
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			sess.close();
			sf.close();
		}
	}

	public static void main(String[] args) {
		new SessionUtil().HIbernateTest();
	}
}
</span>
(2)方式2:(强烈不推荐)

<span style="font-size:18px;">package com.anlw.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.CacheMode;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;

import com.anlw.entity.Student;

public class SessionUtil {
	Configuration conf = null;
	ServiceRegistry st = null;
	SessionFactory sf = null;
	Session sess = null;
	Transaction tx = null;

	public void HIbernateTest() {
		conf = new Configuration().configure();
		st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
		sf = conf.buildSessionFactory(st);
		try {
			sess = sf.openSession();
			tx = sess.beginTransaction();
			//查询表中的所有数据
			ScrollableResults student = sess.createQuery("from Student")
					.setCacheMode(CacheMode.IGNORE)
					.scroll(ScrollMode.FORWARD_ONLY);
			int count = 0;
			while(student.next()){
				Student s = (Student)student.get(0);
				s.setName("haha");
				if(++count%3 == 0){
					sess.flush();
					sess.clear();
				}
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			sess.close();
			sf.close();
		}
	}

	public static void main(String[] args) {
		new SessionUtil().HIbernateTest();
	}
}
</span>
通过这种方式,虽然可以执行批量更新,但效果非常不好,执行效率不高,需要先执行数据查询,然后再执行数据更新,而且这种更新将是逐行更新,即每更新一行记录,都要执行一条update语句,性能非常低;

2,绕过Hibernate,调用JDBC API

(1)方式1:

<span style="font-size:18px;">package com.anlw.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;

public class SessionUtil {
	Configuration conf = null;
	ServiceRegistry st = null;
	SessionFactory sf = null;
	Session sess = null;
	Transaction tx = null;

	public void HIbernateTest() {
		conf = new Configuration().configure();
		st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
		sf = conf.buildSessionFactory(st);
		try {
			sess = sf.openSession();
			tx = sess.beginTransaction();
			//执行Work对象指定的操作,即调用Work对象的execute()方法
			//Session会把当前使用的数据库连接传给execute()方法
			sess.doWork(new Work() {
				
				@Override
				public void execute(Connection arg0) throws SQLException {//需要注意的是,不需要调用close()方法关闭这个连接
					String sql = "update student set name = 'oracle'";
					//创建一个Satement对象
					Statement st  = arg0.createStatement();
					//调用JDBC的update进行批量更新
					st.executeUpdate(sql);
				}
			});
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			sess.close();
			sf.close();
		}
	}

	public static void main(String[] args) {
		new SessionUtil().HIbernateTest();
	}
}
</span>
(2)方式2:

<span style="font-size:18px;">package com.anlw.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;

public class SessionUtil {
	Configuration conf = null;
	ServiceRegistry st = null;
	SessionFactory sf = null;
	Session sess = null;
	Transaction tx = null;

	public void HIbernateTest() {
		conf = new Configuration().configure();
		st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
		sf = conf.buildSessionFactory(st);
		try {
			sess = sf.openSession();
			tx = sess.beginTransaction();
			//执行Work对象指定的操作,即调用Work对象的execute()方法
			//Session会把当前使用的数据库连接传给execute()方法
			sess.doWork(new Work() {
				
				@Override
				public void execute(Connection arg0) throws SQLException {//需要注意的是,不需要调用close()方法关闭这个连接
					String sql = "update student set name = ? where name=?";
					PreparedStatement ps = arg0.prepareStatement(sql);
					for(int i=0;i<10;i++){
						ps.setString(1,"tom");
						ps.setString(2, "oracle");
						ps.addBatch();
					}
					ps.executeBatch();
					
				}
			});
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			sess.close();
			sf.close();
		}
	}

	public static void main(String[] args) {
		new SessionUtil().HIbernateTest();
	}
}
</span>

二,批量删除(两种方式)

1,使用Hibernate直接进行批量删除

(1)方式1:(Hibernate的HQL直接支持update/delete的批量更新语法)

<span style="font-size:18px;">package com.anlw.util;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class SessionUtil {
	Configuration conf = null;
	ServiceRegistry st = null;
	SessionFactory sf = null;
	Session sess = null;
	Transaction tx = null;

	public void HIbernateTest() {
		conf = new Configuration().configure();
		st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
		sf = conf.buildSessionFactory(st);
		try {
			sess = sf.openSession();
			tx = sess.beginTransaction();
			//在HQL查询中使用delete进行批量删除,下面的的语句是HQL语句,不是sql
			Query query = sess.createQuery("delete Student");//也可以是delete from,from关键字是可选的,可以不要,加条件的时候可以指定类的别名
			query.executeUpdate();
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			sess.close();
			sf.close();
		}
	}

	public static void main(String[] args) {
		new SessionUtil().HIbernateTest();
	}
}
</span>

(2)方式2:(强烈不推荐)

<span style="font-size:18px;">package com.anlw.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.CacheMode;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;

import com.anlw.entity.Student;

public class SessionUtil {
	Configuration conf = null;
	ServiceRegistry st = null;
	SessionFactory sf = null;
	Session sess = null;
	Transaction tx = null;

	public void HIbernateTest() {
		conf = new Configuration().configure();
		st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
		sf = conf.buildSessionFactory(st);
		try {
			sess = sf.openSession();
			tx = sess.beginTransaction();
			//查询表中的所有数据
			ScrollableResults student = sess.createQuery("from Student")
					.setCacheMode(CacheMode.IGNORE)
					.scroll(ScrollMode.FORWARD_ONLY);
			int count = 0;
			while(student.next()){
				Student s = (Student)student.get(0);
				sess.delete(s);
			}
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			sess.close();
			sf.close();
		}
	}

	public static void main(String[] args) {
		new SessionUtil().HIbernateTest();
	}
}
</span>
通过这种方式,虽然可以执行批量删除,但效果非常不好,执行效率不高,需要先执行数据查询,然后再执行数据删除,而且这种删除将是逐行删除,即每删除一行记录,都要执行一条delete语句,性能非常低;

2,绕过Hibernate,调用JDBC API

(1)方式1:

<span style="font-size:18px;">package com.anlw.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;

import com.anlw.entity.Student;

public class SessionUtil {
	Configuration conf = null;
	ServiceRegistry st = null;
	SessionFactory sf = null;
	Session sess = null;
	Transaction tx = null;

	public void HIbernateTest() {
		conf = new Configuration().configure();
		st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
		sf = conf.buildSessionFactory(st);
		try {
			sess = sf.openSession();
			tx = sess.beginTransaction();
			sess.doWork(new Work() {
				
				@Override
				public void execute(Connection arg0) throws SQLException {
					String sql = "delete from student where age > 5"; //mysql中删除语句不能省略from
					Statement st = arg0.createStatement();
					st.executeUpdate(sql);
				}
			});
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			sess.close();
			sf.close();
		}
	}

	public static void main(String[] args) {
		new SessionUtil().HIbernateTest();
	}
}
</span>
2)方式2:

<span style="font-size:18px;">package com.anlw.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;

import com.anlw.entity.Student;

public class SessionUtil {
	Configuration conf = null;
	ServiceRegistry st = null;
	SessionFactory sf = null;
	Session sess = null;
	Transaction tx = null;

	public void HIbernateTest() {
		conf = new Configuration().configure();
		st = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
		sf = conf.buildSessionFactory(st);
		try {
			sess = sf.openSession();
			tx = sess.beginTransaction();
			sess.doWork(new Work() {
				
				@Override
				public void execute(Connection arg0) throws SQLException {
					String sql = "delete from student where age = ?"; //mysql中删除语句不能省略from
					PreparedStatement ps = arg0.prepareStatement(sql);
					for(int i=0;i<10;i++){
						if(i%2 == 0){
							ps.setInt(1, i);
							ps.addBatch();
						}
						ps.executeBatch();
					}
				}
			});
			tx.commit();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			sess.close();
			sf.close();
		}
	}

	public static void main(String[] args) {
		new SessionUtil().HIbernateTest();
	}
}
</span>






  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值