Play Framework + Java的批量操作

Play虽然很快捷,但也终究是存在不足之处,当批量操作时,只能用调用JPA去执行原生SQL,
本人这里写了批量修改与批量新增的操作这两种操作。

网上查了很多,基本都是

//查到的第一种
 for (int i = 0; i < list.size(); i++) {
     em.persist(list.get(i));
     if (i % 100 == 0) {//一次一百条插入
         em.flush();
         em.clear();
     }
 }
 //查到的第二种
 for(DvdRateConfig rate : set) {  
    if(i%100==0) {  
         System.out.println(">>>>>>>>>>>>>>>>>>>>>>>flush");  
         JPA.em().flush();  
         JPA.em().clear();  
     }  
     rate.save();  
 }  

两种方式都是调用flush更新到数据库,无非就是以
insert in to table values(…)
insert in to table values(…)
.
.
.
这种方式每100条执行一次,但从代码来看,以每一百条提交,虽然比单个提交效率提高很多,但也并不是我想要的结果(insert in to table values(…),(…)),所以还是需要JPA执行原生SQL,下面介绍批量新增与更新的批量操作:
1批量新增

/**
 * insert into test (admin_id, subject_id, update_time,status,name) values(...),(...);
 */
public static void testis() {
	List<Test1> list = new ArrayList<Test1>();
	for (int i = 0; i < 10; i++) {
		Test1 t = new Test1(); 
		t.admin_id = 1L;
		t.subject_id = 1L;
		t.status = 2;
		t.update_time = new Date();
		t.name = "'测试增加"+(i+1)+"号'";
		list.add(t);
	}
	
	StringBuffer insertSql = new StringBuffer();
	insertSql.append("insert into test (admin_id, subject_id, update_time,status,name) values");
	for (int i = 0; i < list.size(); i++) {
		
		insertSql.append("(");
		insertSql.append(list.get(i).admin_id+",");
		insertSql.append(list.get(i).subject_id+",");
		insertSql.append("str_to_date('"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(list.get(i).update_time).toString()+"','%Y-%m-%d %H:%i:%s'),");
		insertSql.append(list.get(i).status+",");
		insertSql.append(list.get(i).name); 
		insertSql.append(")");
		if(i!=list.size()-1){
			insertSql.append(",");
		}
	}
	Query createNativeQuery = JPA.em().createNativeQuery(insertSql.toString()); 
	int executeUpdate = createNativeQuery.executeUpdate();
	System.out.println(executeUpdate);//影响条数
	
}

2批量修改

/**
 * 
 * UPDATE test
 *     SET name = CASE id 
 *         WHEN 426 THEN '测试修改426'
 * 		   WHEN 427 THEN '测试修改427'
 *     END
 * WHERE id IN (426,427)
 */
public static void testus() {
	List<Test1> list = new ArrayList<Test1>();
	for (int i = 0; i < 10; i++) {
		Test1 t = new Test1(); 
		t.id = 456+Long.parseLong(i+"");
		t.admin_id = 2L;
		t.subject_id = 3L;
		t.status = 2;
		t.update_time = new Date();
		t.name = "'测试修改"+(i+100)+"号'";
		list.add(t);
	}
	
	String updateSql = "update test set admin_id = case id adminIdWhenThen end, subject_id = case id subjectIdWhenThen end, name =  case id nameWhenThen end where id in (whereIds)";
	StringBuffer adminIdWhenThen = new StringBuffer();
	StringBuffer subjectIdWhenThen = new StringBuffer();
	StringBuffer nameWhenThen = new StringBuffer();
	StringBuffer whereIds = new StringBuffer();
			
	for (int i = 0; i < list.size(); i++) {
		adminIdWhenThen.append(" when "+list.get(i).id+" then "+list.get(i).admin_id);
		subjectIdWhenThen.append(" when "+list.get(i).id+" then "+list.get(i).subject_id);
		nameWhenThen.append(" when "+list.get(i).id+" then "+list.get(i).name+"");
		whereIds.append(list.get(i).id);
		if(i != list.size()-1){
			whereIds.append(",");
		}
	}
	updateSql = updateSql.replace("adminIdWhenThen", adminIdWhenThen.toString()).replace("subjectIdWhenThen", subjectIdWhenThen.toString())
									  .replace("nameWhenThen", nameWhenThen.toString()).replace("whereIds", whereIds.toString());
	
	Query createNativeQuery = JPA.em().createNativeQuery(updateSql.toString()); 
	int executeUpdate = createNativeQuery.executeUpdate();
	System.out.println(executeUpdate);
}

需要特别注意,这里有几处坑:
1、createNativeQuery是执行原生SQL的方法,createQuery是执行HQL语句的方法。
2、拼接SQL时,属性为字符时,应该用’'或""包住,完全按照SQL规范,例:‘测试’
3、同上,属性为时间类型时,需要SimpleDateFormat格式化一下,再用STR_TO_DATE(str,format)转换一下,特别需要注意,这里不能用双引号包住,如果是"2018-11-20 10:10:10"这种格式会报类型错误,因为数据库是dateTime类型,所以需要转换。
3.1、附上mysql时间类型转换:
STR_TO_DATE(str,format)–字符转时间
DATE_FORMAT(date,format)–时间转字符
%Y:代表4位的年份
%y:代表2为的年份
%m:代表月, 格式为
%d:代表月份中的天数
%H:代表小时,格式为(00……23)
%h: 代表小时,格式为(01……12)
%i: 代表分钟
%S:代表 秒
4、如果数据量大时,需要分批操作,可以调用以下方法来手动批量提交
JPA.em().getTransaction().begin();
JPA.em().getTransaction().commit();
JPA.em().getTransaction().rollback();

猜你喜欢

转载自blog.csdn.net/qq_38529889/article/details/84306368