论坛首页 Java企业应用论坛

ibatis中主键的返回

浏览 8081 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-04-24  
spring与ibatis整合后在getSqlMapClientTemplate()方法中提供了一系列CRUD方法,其中insert返回一个Object型的主键,一直用着都很正常,可是在oracle中增加了序列,又修改了配置文件,就一直抛NullPointException
<insert id="addPermission" parameterClass="Permission">
		INSERT INTO P_PERMISSION
		(PERMISSIONID,PERMISSIONINFO,PERMISSIONNAME,PERMISSIONENNAME,URL)
		VALUES
		(SEQ_P_PERMISSION.NEXTVAL,#permissionInfo#,#permissionName#,
                 #permissionEnName#,#url#)
</insert>

检查了数遍Dao跟Service,都没问题(就是怕类似少标点这样的小错误),而且数据也可以添加,就觉得应该是配置文件的问题,仔细查看了下文档,原来<insert>中还包含一个<selectKey>可以配置序列
<insert id="addPermission" parameterClass="Permission">
		<selectKey resultClass="int" keyProperty="permissionId">
			SELECT SEQ_P_PERMISSION.NEXTVAL FROM DUAL
		</selectKey>
		INSERT INTO P_PERMISSION
		(PERMISSIONID,PERMISSIONINFO,PERMISSIONNAME,PERMISSIONENNAME,URL)
		VALUES
		(#permissionId#,#permissionInfo#,#permissionName#,#permissionEnName#,#url#)
	</insert>

修改完毕,程序没问题啦。
-----------------分割线--------------------------------------
如果使用后生成主键的数据库,MySql,SQLServer配置文件应为
<insert id="addPermission" parameterClass="Permission">
		
		INSERT INTO P_PERMISSION
		(PERMISSIONID,PERMISSIONINFO,PERMISSIONNAME,PERMISSIONENNAME,URL)
		VALUES
		(#permissionId#,#permissionInfo#,#permissionName#,#permissionEnName#,#url#)
        <selectKey resultClass="int" keyProperty="permissionId">
			SELECT @@IDENTITY AS PERMISSIONID
		</selectKey>	
</insert>

当然,前提是PERMISSIONID字段被设置为自增属性
   发表时间:2008-04-24  
建议:
    <insert id="addPermission" parameterClass="Permission">           
        INSERT INTO P_PERMISSION   
        (PERMISSIONID,PERMISSIONINFO,PERMISSIONNAME,PERMISSIONENNAME,URL)   
        VALUES   
        (#permissionId#,#permissionInfo#,#permissionName#,#permissionEnName#,#url#)   
        <selectKey resultClass="int" keyProperty="permissionId">  
            SELECT SEQ_P_PERMISSION.CURRVAL FROM DUAL   
        </selectKey> 
    </insert>
1 请登录后投票
   发表时间:2008-04-24  
zelsa 写道
建议:
    <insert id="addPermission" parameterClass="Permission">           
        INSERT INTO P_PERMISSION   
        (PERMISSIONID,PERMISSIONINFO,PERMISSIONNAME,PERMISSIONENNAME,URL)   
        VALUES   
        (#permissionId#,#permissionInfo#,#permissionName#,#permissionEnName#,#url#)   
        <selectKey resultClass="int" keyProperty="permissionId">  
            SELECT SEQ_P_PERMISSION.CURRVAL FROM DUAL   
        </selectKey> 
    </insert>

why?
0 请登录后投票
   发表时间:2008-04-24  
zelsa 写道
建议:
    <insert id="addPermission" parameterClass="Permission">           
        INSERT INTO P_PERMISSION   
        (PERMISSIONID,PERMISSIONINFO,PERMISSIONNAME,PERMISSIONENNAME,URL)   
        VALUES   
        (#permissionId#,#permissionInfo#,#permissionName#,#permissionEnName#,#url#)   
        <selectKey resultClass="int" keyProperty="permissionId">  
            SELECT SEQ_P_PERMISSION.CURRVAL FROM DUAL   
        </selectKey> 
    </insert>


没有什么区别吧,不要用sequence的currval用nextval,sequence第一次被select 的currval为空
0 请登录后投票
   发表时间:2008-04-24  
kkndone 写道
zelsa 写道
建议:
    <insert id="addPermission" parameterClass="Permission">           
        INSERT INTO P_PERMISSION   
        (PERMISSIONID,PERMISSIONINFO,PERMISSIONNAME,PERMISSIONENNAME,URL)   
        VALUES   
        (#permissionId#,#permissionInfo#,#permissionName#,#permissionEnName#,#url#)   
        <selectKey resultClass="int" keyProperty="permissionId">  
            SELECT SEQ_P_PERMISSION.CURRVAL FROM DUAL   
        </selectKey> 
    </insert>

why?

这个我也很想知道为什么,麻烦举例说明
0 请登录后投票
   发表时间:2008-05-26  
这个应该是数据库的主键的前后生成顺序了,oracle的是前生成,而sqlserver则是后生成,所以应该顺序会有一定的影响的
0 请登录后投票
   发表时间:2008-07-03  
引用
这个应该是数据库的主键的前后生成顺序了,oracle的是前生成,而sqlserver则是后生成,所以应该顺序会有一定的影响的


是的,这是与数据库的主键的生成先后顺序有关的。对于Oracle是pre生成的,对于MySQL、SQLServer等是post生成的,那么为什么使用selectKey呢,如果不使用selectKey会有什么问题呢?
当持久化某个实体对象(如保存一个对象)时,如果我们不用selectKey,那么我们不会立刻得到实体对象的Id属性的,也就是数据表主键

Permission permission = new Permission();
permission.set...

permmisonDao.createPermission(permission);
assertNull(permission);


selectKey元素与其在父元素中的位置有关,Oracle的selectKey在前
<insert id="addPermission" parameterClass="Permission">  
	<selectKey resultClass="int" keyProperty="permissionId">  
		SELECT SEQ_P_PERMISSION.NEXTVAL FROM DUAL   
	</selectKey>  
	INSERT INTO P_PERMISSION (
		PERMISSIONID, PERMISSIONINFO, PERMISSIONNAME, PERMISSIONENNAME, URL
	) VALUES (
		#permissionId#, #permissionInfo#, #permissionName#, #permissionEnName#, #url#
	)   
</insert>


Mysql、SQLServer在后
 <insert id="addPermission" parameterClass="Permission">    
	INSERT INTO P_PERMISSION (
		PERMISSIONID, PERMISSIONINFO, PERMISSIONNAME, PERMISSIONENNAME, URL
	) VALUES (
		#permissionId#, #permissionInfo#, #permissionName#, #permissionEnName#, #url#
	)
	<selectKey resultClass="int" keyProperty="permissionId">  
		SELECT LAST_INSERT_ID()   
	</selectKey>
</insert>


像上面这样书写,与selectKey的位置联系得太紧密了,iBatis的sqlMap配置文件的selectKey元素有个type属性,可以指定pre或者post表示前生成还是后生成。
对于Oracle,表示为
  
<insert id="addPermission" parameterClass="Permission">  
	<selectKey resultClass="int" keyProperty="permissionId" type="pre">  
		SELECT SEQ_P_PERMISSION.NEXTVAL FROM DUAL   
	</selectKey>  
	INSERT INTO P_PERMISSION (
		PERMISSIONID, PERMISSIONINFO, PERMISSIONNAME, PERMISSIONENNAME, URL
	) VALUES (
		#permissionId#, #permissionInfo#, #permissionName#, #permissionEnName#, #url#
	)   
</insert>   


Mysql、SQLServer等表示为:
  
<insert id="addPermission" parameterClass="Permission">  
	<selectKey resultClass="int" keyProperty="permissionId" type="post">  
		SELECT LAST_INSERT_ID()
	</selectKey>  
	INSERT INTO P_PERMISSION (
		PERMISSIONID, PERMISSIONINFO, PERMISSIONNAME, PERMISSIONENNAME, URL
	) VALUES (
		#permissionId#, #permissionInfo#, #permissionName#, #permissionEnName#, #url#
	)   
</insert>   

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics