Hibernate使用自定义主键生成器@TableGenerator和数据库自身生成器的性能测试

Hibernate提供实现类:org.hibernate.id.MultipleHiLoPerTableGenerator
碰到一个问题:
org.hibernate.id.IdentifierGeneratorHelper类里面的方法:
value:当前值,
factor:model类定义的allocationSize = 100小1,及时99(第一次传入的信息)
public IntegralDataTypeHolder multiplyBy(long factor) {
checkInitialized();
value *= factor;
return this;
}
,从这里可以看到启动服务器的时候第一次执行到这里,就发现表的主键是tb_generator(保存主键信息)表的gen_value的allocationSize倍数。那么会浪费掉很多主键值。
上面的方法被org.hibernate.id.enhanced.OptimizerFactory的public synchronized Serializable generate()调用,maxLo同时初始化这个变量,这个变量maxLo+1就是factor。


hibernate中自定义主键生成器:[url]http://panyongzheng.iteye.com/blog/1827786[/url]
探索 Hibernate 新 TableGenerator 机制 [url]http://www.ibm.com/developerworks/cn/java/j-lo-tablegenerator/index.html?ca=drs-[/url]
探索 Hibernate 新 TableGenerator 机制 [url]http://www.itpub.net/thread-1822509-1-1.html[/url]

Hibernate的主键生成策略与并发测试[url]http://blog.sina.com.cn/s/blog_56d8ea900100xb8h.html[/url]
一些重要的知识,可以在这里看到.

SpringMVC3.x, Hiberante4, sql server 2008, 数据库的VM内存2G, 本机的web环境内存8G(VM在本机上建立的), j2ee环境option内存:1G. 服务器:jetty, idea采用非调试启动.
这里不想讨论为什么使用@TableGenerator, 因为没必要,只是比较性能而已.

在运行是, 没有手动session.flush()等操作.

使用自定义主键生成器的service
pojo的主键定义示例:
@GeneratedValue(strategy = GenerationType.TABLE,generator="customer_gen")
@TableGenerator(name = "customer_gen",
table="tb_generator",
pkColumnName="gen_name",
valueColumnName="gen_value",
pkColumnValue="testtable_PK"
)

注意,没有设定allocationSize属性,默认是50.
@Override
public void saveTestData(int sum) {
/*
DELETE FROM dbo.testtable3;
DELETE FROM dbo.testtable2;
DELETE FROM dbo.testtable1;
DELETE FROM dbo.testtable;
*/
Date d1 = new Date();
//单表
for(int i=0; i<sum; i++){
Testtable t = new Testtable();
t.setCode("Test"+i);
testtableDao.save(t);
//System.out.println("自定义主键生成 记录:"+i+" 单表:"+(new Date()).toString());
}
System.out.println("完成单表操作");


//关联
for(int i=0; i<sum; i++){
Testtable1 p = new Testtable1();
p.setCode("P"+i);
p = testtable1Dao.save(p);

Testtable2 c = new Testtable2();
c.setTesttable1(p);
c.setCode("C"+i);
testtable2Dao.save(c);
//System.out.println("自定义主键生成 记录:"+i+" 关联:"+(new Date()).toString());
}
System.out.println("完成关联操作");

//映射
for(int i=0;i<sum; i++){
Testtable t = new Testtable();
t.setCode("T"+i);
t = testtableDao.save(t);

Testtable2 c = new Testtable2();
c.setCode("C"+i);
c = testtable2Dao.save(c);

Testtable3 m = new Testtable3();
m.setCode("M"+i);
m.setTesttable(t);
m.setTesttable2(c);
m = testtable3Dao.save(m);
//System.out.println("自定义主键生成 记录:"+i+" 映射:"+(new Date()).toString());
}
System.out.println("完成映射操作");
System.out.println("Over......");
Date d2 = new Date();
long t = d2.getTime() - d1.getTime();
System.out.println("service耗时=" + (t / 1000) + "s");

}


使用数据库自己的主键生成器的service
pojo的主键定义示例:
@GeneratedValue(strategy = GenerationType.AUTO)

@Override
public void saveTestData(int sum) {
/*
DELETE FROM dbo.atabletest3;
DELETE FROM dbo.atabletest2;
DELETE FROM dbo.atabletest1;
DELETE FROM dbo.atabletest;
*/
Date d1 = new Date();
//单表
for(int i=0; i<sum; i++){
Atabletest t = new Atabletest();
t.setCode("Test"+i);
atabletestDao.save(t);
//System.out.println("数据库主键生成 记录:"+i+" 单表:"+(new Date()).toString());
}
System.out.println("完成单表操作");


//关联
for(int i=0; i<sum; i++){
Atabletest1 p = new Atabletest1();
p.setCode("P"+i);
p = atabletest1Dao.save(p);

Atabletest2 c = new Atabletest2();
c.setAtabletest1(p);
c.setCode("C"+i);
atabletest2Dao.save(c);
//System.out.println("数据库主键生成 记录:"+i+" 关联:"+(new Date()).toString());
}
System.out.println("完成关联操作");


//映射
for(int i=0;i<sum; i++){
Atabletest t = new Atabletest();
t.setCode("T"+i);
t = atabletestDao.save(t);

Atabletest2 c = new Atabletest2();
c.setCode("C"+i);
c = atabletest2Dao.save(c);

Atabletest3 m = new Atabletest3();
m.setAtabletest(t);
m.setAtabletest2(c);
m.setCode("M"+i);
m = atabletest3Dao.save(m);
//System.out.println("数据库主键生成 记录:"+i+" 映射:"+(new Date()).toString());
}
System.out.println("完成映射操作");
System.out.println("Over......");
Date d2 = new Date();
long t = d2.getTime() - d1.getTime();
System.out.println("service耗时=" + (t / 1000) + "s");
}



调用service的controller方法
@RequestMapping("/test")
public ModelAndView test(@RequestParam("flag") int flag, @RequestParam("sum") int sum) {
if (flag == 1) {
Date d1 = new Date();
testtableManager.saveTestData(sum);
Date d2 = new Date();

long t = d2.getTime() - d1.getTime();
System.out.println("使用自定义主键生成器");
System.out.println("记录数:"+(sum*6)+" 耗时=" + (t / 1000) + "s");
} else if (flag == 0) {
Date d1 = new Date();
atabletestManager.saveTestData(sum);
Date d2 = new Date();

long t = d2.getTime() - d1.getTime();
System.out.println("使用数据库主键生成器");
System.out.println("记录数:"+(sum*6)+" 耗时=" + (t / 1000) + "s");
} else {

}

return null;
}



[color=red][b]测试结果: [/b][/color]
10万级别的,自定义要快一点, .
1万级别的,数据库自己的主键要快一点, .
1000条级别的,自定义要快一点 .

60w条数据:
使用自定义主键生成器:
service耗时=142s 耗时=1195s, service耗时=130s 耗时=1587s
使用数据库主键生成器
service耗时=974s 耗时=1284s, service耗时=971s 耗时=1662s

6w条数据:
使用自定义主键生成器:
service耗时=13s 耗时=94s, service耗时=12s 耗时=92s, service耗时=12s 耗时=104s
使用数据库主键生成器
service耗时=89s 耗时=92s, service耗时=82s 耗时=85s, service耗时=90s 耗时=93s

6000条数据:
使用自定义主键生成器:
service耗时=1s 耗时=10s, service耗时=1s 耗时=10s, service耗时=1s 耗时=11s
使用数据库主键生成器
service耗时=9s 耗时=10s, service耗时=10s 耗时=12s, service耗时=8s 耗时=10s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值