以序列方式产生主键值
在Oracle数据库中创建一个seq_post_id序列,使用这个序列为t_post提供主键值,以下是创建seq_post_id的脚本:
create sequence seq_post_id increment by 1 start with 1;
接着,调整Spring的配置,使用OracleSequenceMaxValueIncrementer作为主键产生器:
<bean id="incre" class="org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer"> <property name="incrementerName" value="seq_post_id"/> ①指定序列名 <property name="dataSource" ref="dataSource"/> ②设置数据源 </bean> <bean id="postDao" parent="dao" class="com.baobaotao.dao.jdbc.PostJdbcDao"> <property name="lobHandler" ref="oracleLobHandler"/> <property name="incre" ref="incre"/> ③添加主键主键产生器 </bean>
以表方式产生主键值
在Mysql中创建一张用于维护t_post主键的t_post_id表,以下是创建该表及插入初始化的SQL脚本:
create table t_post_id(sequence_id int) type = MYISAM;
insert into t_post_id values(0);
由于主键维护表的并发访问量很大,所以最好将其声明为MYISAM类型,此外需要为该表提供初始值,以便后续主键值在此之上进行递增。
调整为MySql数据库后,我们仅需要对Spring配置进行小小的调整就可以了:
<bean id="incre" class="org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer"> <property name="incrementerName" value="t_post_id"/> ①设置维护主键的表名 <property name="columnName" value="sequence_id"/>②用于生成主键值的列名 <property name="cacheSize" value="10"/> ③缓存大小 <property name="dataSource" ref="dataSource"/> </bean> <bean id="postDao" parent="dao" class="com.baobaotao.dao.jdbc.PostJdbcDao"> <property name="lobHandler" ref="defaultLobHandler"/> <property name="incre" ref="incre"/> </bean>
incrementerName和columnName都很容易理解,cacheSize决定一次返回的主键个数,这里我们设置为10。当第一次通过MySQLMaxValueIncrementer# nextIntValue()获取主键值时,MySQLMaxValueIncrementer将使t_post_id. sequence_id递增10,而后续9次调用nextIntValue()方法时,都从缓存中获取主键值。直到第10次再次调用nextIntValue()方法时,才会再次将t_post_id. sequence_id字段值递增10,如此循环反复。
小结
主键的生产方式从产生地点上可以分为应用层产生和数据库产生两种方式。应用层借助数据库的序列或表产生主键,这种方式可以保证程序的可移植性和安全性,同时可以通过缓存机制提高运行效率。有些数据库支持数据表自增键的主键产生机制,在JDBC 3.0以前的版本中,无法通过Statement自动获取新增记录的对应主键。这时需要在插入数据后,马上执行一条数据库相关的主键获取SQL语句以得到对应的主键值,在数据库高并发的情况下,有可能获取到不正确的主键值。在这种情况下,在插入数据前事先在应用层准备好主键值是很好的备选方案。
