在其他地方我已经写过一个mySql存储过程的简单实现http://jianboli.blog.51cto.com/12075002/1884019
这里是java调用存储过程。
package com.lijianbo.procedure; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Types; /** * @author * 存储过程MySQL */ public class ProcedureMySql { public static final String DRIVER_CLASS = "com.mysql.jdbc.Driver"; public static final String URL = "jdbc:mysql://localhost:3306/test"; public static final String USERNAME = "root"; public static final String PASSWORD = "root"; public static void main(String[] args) throws Exception { // test1(); // test2(); testIdAdd(); } public static void test1() throws Exception { Class.forName(DRIVER_CLASS); Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); String sql = "{CALL test1(?)}"; //调用存储过程 CallableStatement cstm = connection.prepareCall(sql); //实例化对象cstm cstm.setString(1, "李"); //存储过程输入参数 cstm.execute(); // 执行存储过程 cstm.close(); connection.close(); } /** * 查询总的价格 * getTotalByUser2 * call getTotalByUser2(1, true, @total); -- 加税 *select @total; * @throws Exception */ public static void test2() throws Exception { Class.forName(DRIVER_CLASS); Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); String sql = "{CALL getTotalByUser2(?,?,?)}"; //调用存储过程 CallableStatement cstm = connection.prepareCall(sql); //实例化对象cstm cstm.setInt(1, 1); //设置第一个传入参数 cstm.setBoolean(2, true); //设置第二个传入参数 cstm.registerOutParameter(3, Types.DECIMAL); // 设置返回值类型 即返回值 cstm.execute(); // 执行存储过程 System.out.println(cstm.getString(3)); cstm.close(); connection.close(); } /** *id自增 * getTotalByUser2 * call getTotalByUser2(1, true, @total); -- 加税 *select @total; * @throws Exception */ public static void testIdAdd() throws Exception { Class.forName(DRIVER_CLASS); Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); String sql = "{CALL test1(?)}"; //调用存储过程 CallableStatement cstm = connection.prepareCall(sql); //实例化对象cstm cstm.setString(1, "测试"); //设置第一个传入参数 cstm.execute(); // 执行存储过程 cstm.close(); connection.close(); } }
存储过程既可以在java中调用,也可以在触发器中调用,欲知简单实现。可以参考我的上一篇文章“触发器的简单实现”。
http://jianboli.blog.51cto.com/12075002/1884180
Java在sql中调用存储过程:
参数封装:
//存储过程参数封装 BatchImportParam batchImportParam = new BatchImportParam(); batchImportParam.setDescn(descn); batchImportParam.setExportName(exportName); batchImportParam.setExportNo(exportNo); batchImportParam.setImportName(importName); batchImportParam.setOrderNo(orderNo); batchImportParam.setImportNo(importNo); batchImportParam.setCreateby(getCurrentUserId(request)); batchImportParam.setCardProductId(cardProductId); batchImportParam.setCardFaceId(cardFaceId); batchImportParam.setCardTotalCount(null);
/* * 调用存储过程,执行业务 */ //batchImportParam为调用存储 //过程的封装的参数类,这里也可以采用一个map,向map中传参数。 batchImportCardManager.batchImportCardAndUser(batchImportParam); //返回的参数,我们可以直接在参数集合中去 //直接获取 cardTotalCount = batchImportParam.getCardTotalCount(); System.err.println("==================存储过程成功导入总记录数为:"+cardTotalCount);
在BatchImportCardDAOImpl中我们采用select关键字查询。
@Override public Integer batchImportCardAndUser(BatchImportParam batchImportParam) { return getSqlSession().selectOne(getSqlMapNamespace() + ".batch_import_cardanduser",batchImportParam); }
在xml中调用存储过程。
<!-- 存储过程 --> <parameterMap id="map_r_process_order" type="java.util.HashMap"> <parameter property="importNo" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" /> <!-- 输入参数 --> <parameter property="importName" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" /> <parameter property="orderNo" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" /> <parameter property="exportNo" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" /> <parameter property="exportName" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" /> <parameter property="createby" jdbcType="INTEGER" javaType="int" mode="IN" /> <parameter property="descn" jdbcType="VARCHAR" javaType="java.lang.String" mode="IN" /> <parameter property="cardProductId" jdbcType="INTEGER" javaType="int" mode="IN" /> <parameter property="cardFaceId" jdbcType="INTEGER" javaType="int" mode="IN" /> <parameter property="cardTotalCount" jdbcType="INTEGER" javaType="int" mode="OUT" /> <!-- 返回参数 --> </parameterMap> <select id="batch_import_cardanduser" parameterMap="map_r_process_order" statementType="CALLABLE" > <![CDATA[ {call batch_import_cardanduser(?,?,?,?,?,?,?,?,?,?)} <!-- 问号个数必须要和参数的个数匹配 --> ]]> </select>
总结:其实这种在xml中调用也相当于上面的直接在方法中直接调用,都是需要传入参数,返回参数,只是表现形式不一样而已。
我这里只是一个示例,你可以参考里面的注释,具体存储过程的名字要根据你自己写的来修改。
时间:2016年12月20日16:59:13
-------------快速的向一张表中插入10万条数据,怎么做,用sql实现------------
最开始我想写一句插入的sql,直接循环插入多条数据,结果语法不正确。(sql只能执行一次,不能循环执行,调用一次执行一次)
INSERT INTO test1(id,name) VALUES(1+(SELECT MAX(t.id) FROM test1 t),CONCAT('admin',(SELECT MAX(t1.id)+1 FROM test1 t1))) WHERE ((SELECT MAX(id) from test1) < 10)后面百度、发现用存储过程比较方便,更易实现。
如下:
-- 存储过程 delimiter || create procedure myproc() begin declare num int ; set num = 1 ; while num < 100 do insert into test1(id, `name`) values (num, concat("name", num)) ; set num = num + 1 ; end while ; end|| -- 执行这个函数 call myproc() -- 删除这个存储过程 drop procedure myproc -- 清空表 DELETE from test1 -- 查询数据 SELECT * from test1
总结:存储过程更易写逻辑,难度更低。我们有时候写多条关联查询的时候,sql难度比较大,其实可以写存储过程来实现,只是后期维护难度大点。