mysql三种批量增加的性能分析
网络编程 2021-07-05 15:27www.168986.cn编程入门
最近在深入学习hibernate,在进行批量操作时,发现hibernate批量操作性能非常低.于是就想找一个性能较高的方法,在对jdbc、jdbcTemplate、hibernate进行测试后,发现jdbc的执行效率是最高的,jdbcTemplate也很相近,hibernate就不考虑了,惨不忍睹啊
狼蚁网站SEO优化把代码写出来,希望大家批评指正.
domain对象.在这里使用的注解的方式,都是比较新的版本.
User.java
package .bao.sample.s3h4.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import .bao.sample.base.domain.BaseDomain;
@Entity
@Table(name = "t_user")
public class User extends BaseDomain {
private static final long serialVersionUID = 1L;
private int id;
private String username;
private String password;
/
@Description 注解最好标记在get方法上.注意:采用一致的标记方式,注解是以Id的标记方式为准的,如果标记在get方法上,则忽略property上的注解.
@return
/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(nullable = false)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Column(nullable = false)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User() {
super();
}
public User(int id, String username, String password) {
super();
this.id = id;
this.username = username;
this.password = password;
}
}
接下来是Dao接口,继承一个BaseDao接口.
package .bao.sample.s3h4.dao;
import java.util.List;
import .bao.sample.base.dao.BaseDao;
import .bao.sample.s3h4.domain.User;
public interface UserBatchDao extends BaseDao<User> {
/
@Description 批量增加操作
@return -1:操作失败;0:执行正常;>0:执行成功的数目
/
public int batchAddUsingJdbc(List<User> users);
public int batchAddUsingHibernate(List<User> users);
public int batchAddUsingJdbcTemplate(List<User> users);
}
UserBatchDao的实现:
UserBatchDaoImpl
package .bao.sample.s3h4.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import javax.annotation.Resource;
import .hibernate.Session;
import .springframework.jdbc.core.BatchPreparedStatementSetter;
import .springframework.jdbc.core.JdbcTemplate;
import .springframework.orm.hibernate4.SessionFactoryUtils;
import .springframework.stereotype.Repository;
import .springframework.transaction.annotation.Transactional;
import .bao.sample.base.dao.BaseDaoImpl;
import .bao.sample.s3h4.domain.User;
/
@Description 三种批量增加方法,执行效率依次是jdbc、jdbcTemplate、hibernate.<br />jdbc和jdbcTemplate执行效率相近,不过jdbcTemplate可以使用事务注解控制,所以优先选择.
@author Bob hehe198504@126.
@date 2012-8-13
/
@Repository("userBatchDao")
public class UserBatchDaoImpl extends BaseDaoImpl<User> implements UserBatchDao {
@Resource
protected JdbcTemplate jdbcTemplate;
/
执行10W条记录,大致耗时15188ms
/
@Override
public int batchAddUsingJdbc(List<User> users) {
int result = 0;
Connection conn = null;
PreparedStatement pstmt = null;
String sql = "insert into t_user (username,password) values (?,?)";
try {
conn = SessionFactoryUtils.getDataSource(sessionFactory).getConnection();
conn.setAutoCommit(false);
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < users.size(); i++) {
int j = 1;
pstmt.setString(j++, users.get(i).getUsername());
pstmt.setString(j++, users.get(i).getPassword());
pstmt.addBatch();
}
pstmt.executeBatch();
conn.mit();
conn.setAutoCommit(true);
} catch (SQLException e) {
if (conn != null) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
} finally {
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return result;
}
/
执行10W条记录,大致耗时131203ms,大致是jdbc或jdbcTemplate的10倍.
/
@Override
// @Transactional(noRollbackFor = RuntimeException.class)
@Transactional
public int batchAddUsingHibernate(List<User> users) {
Session session = this.getSession();
for (int i = 0; i < users.size(); i++) {
session.save(users.get(i));
// 添加20条以后,强制入库
// clear()清空缓存
// postgres数据库的隔离级别是已提交读(Read mitted),
// 所以flush以后,数据看不到,只有mit后才能看到数据,
// 如果失败,rollback,前面的flush的数据不会入库
if (i % 20 == 0) {
session.flush();
session.clear();
}
}
return 0;
}
/
执行10W条记录,大致耗时15671ms
/
// @Transactional(noRollbackFor = RuntimeException.class)
@Transactional
public int batchAddUsingJdbcTemplate(List<User> users) {
String sql = "insert into t_user (username,password) values (?,?)";
final List<User> tempUsers = users;
final int count = users.size();
BatchPreparedStatementSetter pss = new BatchPreparedStatementSetter() {
// 为prepared statement设置参数。这个方法将在整个过程中被调用的次数
public void setValues(PreparedStatement pstmt, int i) throws SQLException {
int j = 1;
pstmt.setString(j++, tempUsers.get(i).getUsername());
pstmt.setString(j++, tempUsers.get(i).getPassword());
}
// 返回更新的结果集条数
public int getBatchSize() {
return count;
}
};
jdbcTemplate.batchUpdate(sql, pss);
return 0;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
}
外围的框架没有附上,有需要可以留言,我提供打包下载.
作者听雨轩
domain对象.在这里使用的注解的方式,都是比较新的版本.
User.java
代码如下:
package .bao.sample.s3h4.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import .bao.sample.base.domain.BaseDomain;
@Entity
@Table(name = "t_user")
public class User extends BaseDomain {
private static final long serialVersionUID = 1L;
private int id;
private String username;
private String password;
/
@Description 注解最好标记在get方法上.注意:采用一致的标记方式,注解是以Id的标记方式为准的,如果标记在get方法上,则忽略property上的注解.
@return
/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(nullable = false)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Column(nullable = false)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User() {
super();
}
public User(int id, String username, String password) {
super();
this.id = id;
this.username = username;
this.password = password;
}
}
接下来是Dao接口,继承一个BaseDao接口.
代码如下:
package .bao.sample.s3h4.dao;
import java.util.List;
import .bao.sample.base.dao.BaseDao;
import .bao.sample.s3h4.domain.User;
public interface UserBatchDao extends BaseDao<User> {
/
@Description 批量增加操作
@return -1:操作失败;0:执行正常;>0:执行成功的数目
/
public int batchAddUsingJdbc(List<User> users);
public int batchAddUsingHibernate(List<User> users);
public int batchAddUsingJdbcTemplate(List<User> users);
}
UserBatchDao的实现:
代码如下:
UserBatchDaoImpl
package .bao.sample.s3h4.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import javax.annotation.Resource;
import .hibernate.Session;
import .springframework.jdbc.core.BatchPreparedStatementSetter;
import .springframework.jdbc.core.JdbcTemplate;
import .springframework.orm.hibernate4.SessionFactoryUtils;
import .springframework.stereotype.Repository;
import .springframework.transaction.annotation.Transactional;
import .bao.sample.base.dao.BaseDaoImpl;
import .bao.sample.s3h4.domain.User;
/
@Description 三种批量增加方法,执行效率依次是jdbc、jdbcTemplate、hibernate.<br />jdbc和jdbcTemplate执行效率相近,不过jdbcTemplate可以使用事务注解控制,所以优先选择.
@author Bob hehe198504@126.
@date 2012-8-13
/
@Repository("userBatchDao")
public class UserBatchDaoImpl extends BaseDaoImpl<User> implements UserBatchDao {
@Resource
protected JdbcTemplate jdbcTemplate;
/
执行10W条记录,大致耗时15188ms
/
@Override
public int batchAddUsingJdbc(List<User> users) {
int result = 0;
Connection conn = null;
PreparedStatement pstmt = null;
String sql = "insert into t_user (username,password) values (?,?)";
try {
conn = SessionFactoryUtils.getDataSource(sessionFactory).getConnection();
conn.setAutoCommit(false);
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < users.size(); i++) {
int j = 1;
pstmt.setString(j++, users.get(i).getUsername());
pstmt.setString(j++, users.get(i).getPassword());
pstmt.addBatch();
}
pstmt.executeBatch();
conn.mit();
conn.setAutoCommit(true);
} catch (SQLException e) {
if (conn != null) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
} finally {
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return result;
}
/
执行10W条记录,大致耗时131203ms,大致是jdbc或jdbcTemplate的10倍.
/
@Override
// @Transactional(noRollbackFor = RuntimeException.class)
@Transactional
public int batchAddUsingHibernate(List<User> users) {
Session session = this.getSession();
for (int i = 0; i < users.size(); i++) {
session.save(users.get(i));
// 添加20条以后,强制入库
// clear()清空缓存
// postgres数据库的隔离级别是已提交读(Read mitted),
// 所以flush以后,数据看不到,只有mit后才能看到数据,
// 如果失败,rollback,前面的flush的数据不会入库
if (i % 20 == 0) {
session.flush();
session.clear();
}
}
return 0;
}
/
执行10W条记录,大致耗时15671ms
/
// @Transactional(noRollbackFor = RuntimeException.class)
@Transactional
public int batchAddUsingJdbcTemplate(List<User> users) {
String sql = "insert into t_user (username,password) values (?,?)";
final List<User> tempUsers = users;
final int count = users.size();
BatchPreparedStatementSetter pss = new BatchPreparedStatementSetter() {
// 为prepared statement设置参数。这个方法将在整个过程中被调用的次数
public void setValues(PreparedStatement pstmt, int i) throws SQLException {
int j = 1;
pstmt.setString(j++, tempUsers.get(i).getUsername());
pstmt.setString(j++, tempUsers.get(i).getPassword());
}
// 返回更新的结果集条数
public int getBatchSize() {
return count;
}
};
jdbcTemplate.batchUpdate(sql, pss);
return 0;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
}
外围的框架没有附上,有需要可以留言,我提供打包下载.
作者听雨轩
上一篇:mysql中合并两个字段的方法分享
下一篇:远程连接mysql数据库注意点记录
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程