`

ibatis 执行sqlserver存储过程

阅读更多
sqlserver 存储过程:
create procedure insert_normal_user
@userId int output,
@loginName nvarchar(80),
@password nvarchar(80),
@company nvarchar(80),
@roleId int,
@isEnable tinyint,
@hasCoInfo tinyint,
@financeToolType tinyint
as 
begin
--不生成影响行数
SET NOCOUNT ON;
insert into CN_NORMAL_USER 
(LOGIN_NAME,PASSWORD,COMPANY,ROLE_ID,IS_ENABLE,
 CREATE_TIME,UPDATE_TIME,HAS_CO_INFO,FINANCE_TOOL_TYPE)
values
(@loginName,@password,@company,@roleId,@isEnable,
 getDate(),getDate(),@hasCoInfo,@financeToolType);
select @userId=SCOPE_IDENTITY() ;
end


JDBC执行存储过程方法一:
Connection conn=getConnection();
		
Connection conn=getConnection();
		
CallableStatement  call=conn.prepareCall("{call insert_normal_user(?,?,?,?,?,?,?,?)}");
		
call.registerOutParameter(1,java.sql.Types.INTEGER);
		
call.setObject(2, "这是测试插入----");
call.setObject(3, "123");
call.setObject(4, "12");
call.setObject(5, 1);
call.setObject(6, 4);
call.setObject(7, 0);
call.setObject(8, 1);
call.executeUpdate();

System.out.println(call.getInt(1));
		
conn.close();


没有问题,如果将call.registerOutParameter(8,java.sql.Types.INTEGER);
改为call.registerOutParameter(1,-99999);会报错
Exception in thread "main" java.lang.NullPointerException
	at com.microsoft.sqlserver.jdbc.AppDTVImpl$SetValueOp.executeDefault(Unknown Source)
	at com.microsoft.sqlserver.jdbc.DTV.executeOp(Unknown Source)
	at com.microsoft.sqlserver.jdbc.AppDTVImpl.setValue(Unknown Source)
	at com.microsoft.sqlserver.jdbc.DTV.setValue(Unknown Source)
	at com.microsoft.sqlserver.jdbc.Parameter.getTypeDefinition(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.buildParamTypeDefinitions(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.buildPreparedStrings(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doPrepExec(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PreparedStatementExecutionRequest.executeStatement(Unknown Source)
	at com.microsoft.sqlserver.jdbc.CancelableRequest.execute(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeRequest(Unknown Source)
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate(Unknown Source)
	at com.caineng.util.ibatis.JDBC.main(JDBC.java:115)



JDBC执行存储过程方法二:
Connection conn=getConnection();
		
CallableStatement  call=conn.prepareCall("{call insert_normal_user(?,?,?,?,?,?,?,?)}");
		
call.registerOutParameter(1,-99999);
		
call.setObject(1, 1);// 新添加的语句
call.setObject(2, "这是测试插入----");
call.setObject(3, "123");
call.setObject(4, "12");
call.setObject(5, 1);
call.setObject(6, 4);
call.setObject(7, 0);
call.setObject(8, 1);

call.executeUpdate();
		
System.out.println(call.getInt(1));


如果设置call.registerOutParameter(1,-99999);再添加call.setObject(1, 1);则可以执行正确。

Ibatis执行存储过程一:
配置文件:
    <parameterMap class="NormalUser" id="normalUserParameterMap">
       <parameter property="userId"   javaType="Integer"  jdbcType="INTEGER" mode="OUT" />
       <parameter property="loginName"  mode="IN"/>
       <parameter property="password"   mode="IN"/>
       <parameter property="company"    mode="IN"/>
       <parameter property="roleId"     mode="IN" />
       <parameter property="isEnable"   mode="IN" />
       <parameter property="hasCoInfo"  mode="IN" />
       <parameter property="financeToolType" mode="IN"/>
    </parameterMap>
    
    <procedure id="insertNormalUserByProcedure" parameterMap="normalUserParameterMap">
    	{call insert_normal_user(?,?,?,?,?,?,?,?)}
    </procedure>


可以通过,如果将<parameter property="userId"   javaType="Integer"  jdbcType="INTEGER" mode="OUT" />
改为<parameter property="userId"   javaType="Integer"  jdbcType="int" mode="OUT" />则报错:
org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [0];   
--- The error occurred in sqlmaps/mssql/account/NormalUser.ibatis.xml.  
--- The error occurred while applying a parameter map.  
--- Check the CN_NORMAL_USER.normalUserParameterMap.  
--- Check the statement (update procedure failed).  
--- Cause: java.lang.NullPointerException; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred in sqlmaps/mssql/account/NormalUser.ibatis.xml.  
--- The error occurred while applying a parameter map.  
--- Check the CN_NORMAL_USER.normalUserParameterMap.  
--- Check the statement (update procedure failed).  
--- Cause: java.lang.NullPointerException

--- Cause: java.lang.NullPointerException; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:  
空指针和上面jdbc java代码中设置call.registerOutParameter(1,-99999);之后报的错一样。

Ibatis执行存储过程二:
    <parameterMap class="NormalUser" id="normalUserParameterMap">
       <parameter property="userId"   javaType="Integer"  jdbcType="int" mode="INOUT" />
       <parameter property="loginName"  mode="IN"/>
       <parameter property="password"   mode="IN"/>
       <parameter property="company"    mode="IN"/>
       <parameter property="roleId"     mode="IN" />
       <parameter property="isEnable"   mode="IN" />
       <parameter property="hasCoInfo"  mode="IN" />
       <parameter property="financeToolType" mode="IN"/>
    </parameterMap>
    
    <procedure id="insertNormalUserByProcedure" parameterMap="normalUserParameterMap">
    	{call insert_normal_user(?,?,?,?,?,?,?,?)}
    </procedure>

现在<parameter property="userId"   javaType="Integer"  jdbcType="int" mode="INOUT" />
将jdbcType="int" mode="INOUT" 可以通过,但是前提是传进来的对象NormalUser的userId属性不能为空。
联想到上面jdbc java代码中设置call.registerOutParameter(1,-99999);之后有加入代码call.setObject(1, 1);

引用
ibatis parameterMap的子元素parameter的属性jdbcType用于显式地指定给本属性(property)赋值的数据库字段的数据类型。
对于某些特定的操作,如果不指定字段的数据类型,某些JDBC Driver无法识别字段的数据类型。一个很好的例子是
PreparedStatement.setNull(int parameterIndex, int sqlType)方法,要求指定数据类型。如果不指定数据类型,
某些Driver可能指定为Types.Other或Types.Null。但是,不能保证所有的Driver都表现一致。对于这种情况,
SQL Map API允许使用parameterMap子元素parameter的jdbcType属性指定数据类型。
正常情况下,只有当字段可以为NULL时才需要jdbcType属性。另一需要指定jdbcType属性的情况是字段类型为日期时间类型的情况。
因为Java只有一个Date类型(java.util.Date),而大多数SQL数据库有多个-通常至少有3种。因此,
需要指定字段类型是DATE还是DATETIME。属性jdbcType可以是JDBC Types类中定义的任意参数的字符串值。
虽然如此,还是有某些类型不支持(即BLOB)。本节的稍后部分会说明架构支持的数据类型。
注意!大多数JDBC Driver只有在字段可以为NULL时需要指定jdbcType属性。因此,对于这些Driver,
只是在字段可以为NULL时才需要指定type属性。注意!当使用Oracle Driver时,如果没有给可以为NULL的字段指定jdbcType属性,
当试图给这些字段赋值NULL时,会出现“Invalid column type”错误。

附上Ibatis parameterMap的子元素parameter的属性jdbcType的解释

本人小菜,文笔欠佳,请见谅!



















分享到:
评论
2 楼 antlove 2014-03-15  
DXL_xiaoli 写道
java代码如何获取返回的值,需要特殊处理吗,利用对应类型接收之类的?
返回一个标识如何处理?
返回一个CData类型又如何处理?
初学请多指教

没明白你要问什么问题。
如果是问java如何操纵数据库。一下是一个jdbc的简单例子。希望对你有所帮助。
至于如何处理返回值为CData类型的数据,目前暂时暂时没有接触到。
package db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCTest {
	private static String user="";
	private static String password="";
	private static String url="";
	private static String driverClass="";
	static {
		try {
			Class.forName(driverClass);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	private Connection getDefaultConnection() {
		try {
			return DriverManager.getConnection(url, user, password);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	private void close(Statement statement){
		if(statement==null){
			return;
		}
		try {
			statement.close();
			statement.getConnection().close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		
	}
	
	public  void test(){
		Connection connection = getDefaultConnection();
		String sql ="select ID,USERNAME from student";
		PreparedStatement ps = null;
		try {
			ps = connection.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			while(rs.next()){
				int id = rs.getInt("ID");
				String username = rs.getString("USERNAME");
				System.out.println("id : "+id+",username : "+username);
			}
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}finally{
			close(ps);
		}
	}
}
1 楼 DXL_xiaoli 2014-03-15  
java代码如何获取返回的值,需要特殊处理吗,利用对应类型接收之类的?
返回一个标识如何处理?
返回一个CData类型又如何处理?
初学请多指教

相关推荐

    IBATIS调用存储过程

    IBATIS调用存储过程

    Spring中文帮助文档

    11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.2.9. 获取自动生成的主键 11.3. 控制数据库连接 11.3.1. DataSourceUtils类 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource类 ...

    Java面试宝典2010版

    3、存储过程与触发器必须讲,经常被面试到? 4、数据库三范式是什么? 5、说出一些数据库优化方面的经验? 6、union和union all有什么不同? 7.分页语句 8.用一条SQL语句 查询出每门课都大于80分的学生姓名 9.所有...

    Spring API

    11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.2.9. 获取自动生成的主键 11.3. 控制数据库连接 11.3.1. DataSourceUtils类 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource类 ...

    最新Java面试宝典pdf版

    3、存储过程与触发器必须讲,经常被面试到? 92 4、数据库三范式是什么? 94 5、说出一些数据库优化方面的经验? 95 6、union和union all有什么不同? 96 7.分页语句 97 8.用一条SQL语句 查询出每门课都大于80分的学生...

    Java面试笔试资料大全

    3、存储过程与触发器必须讲,经常被面试到? 92 4、数据库三范式是什么? 94 5、说出一些数据库优化方面的经验? 95 6、union和union all有什么不同? 96 7.分页语句 97 8.用一条SQL语句 查询出每门课都大于80分的学生...

    JAVA面试宝典2010

    3、存储过程与触发器必须讲,经常被面试到? 92 4、数据库三范式是什么? 94 5、说出一些数据库优化方面的经验? 95 6、union和union all有什么不同? 96 7.分页语句 97 8.用一条SQL语句 查询出每门课都大于80分的学生...

    Java面试宝典-经典

    3、存储过程与触发器必须讲,经常被面试到? 92 4、数据库三范式是什么? 94 5、说出一些数据库优化方面的经验? 95 6、union和union all有什么不同? 96 7.分页语句 97 8.用一条SQL语句 查询出每门课都大于80分的学生...

    java面试题大全(2012版)

    3、存储过程与触发器必须讲,经常被面试到? 92 4、数据库三范式是什么? 94 5、说出一些数据库优化方面的经验? 95 6、union和union all有什么不同? 96 7.分页语句 97 8.用一条SQL语句 查询出每门课都大于80分的学生...

    Java面试宝典2012版

    3、存储过程与触发器必须讲,经常被面试到? 92 4、数据库三范式是什么? 94 5、说出一些数据库优化方面的经验? 95 6、union和union all有什么不同? 96 7.分页语句 97 8.用一条SQL语句 查询出每门课都大于80分的...

    java面试宝典2012

    3、存储过程与触发器必须讲,经常被面试到? 101 4、数据库三范式是什么? 103 5、说出一些数据库优化方面的经验? 103 6、union和union all有什么不同? 104 7.分页语句 106 8.用一条SQL语句 查询出每门课都大于80分的...

    Java面试宝典2012新版

    3、存储过程与触发器必须讲,经常被面试到? 92 4、数据库三范式是什么? 94 5、说出一些数据库优化方面的经验? 95 6、union和union all有什么不同? 96 7.分页语句 97 8.用一条SQL语句 查询出每门课都大于80分的学生...

    Java 面试宝典

    会被执行,什么时候被执行,在 return 前还是后? .................................................... 25 39、下面的程序代码输出的结果是多少? ...............................................................

Global site tag (gtag.js) - Google Analytics