1:实体类为USER
public class User {
private Integer id;
private String name;
private String sex;
private Integer age;
}
2:在mysql数据库中建t_user表
CREATE TABLE `t_user` (
`id` int(10) NOT NULL,
`name` varchar(50) NOT NULL,
`sex` varchar(6) NOT NULL,
`age` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
3:无参数的存储过程,求记录总条数(没有out参数),要加DELIMITER
DROP PROCEDURE IF EXISTS pGetTotal;
DELIMITER//
CREATE PROCEDURE pGetTotal()
BEGIN
SELECT COUNT(id) FROM t_user;
END;
//
3-1:java代码调用存储过程
//求总数,方法有返回值
@Test
public void getTotal(){
Integer total = userServiceImple.getTotal();
System.out.println(total);
}
<!-- UserMapper.xml 中的配置,用户信息总数,要加上resultType="java.lang.Integer"指定返回值参数类型-->
<select id="getTotal" statementType="CALLABLE" resultType="java.lang.Integer" >
<![CDATA[
{call pGetTotal()}
]]>
</select>
4:带in参数的存储过程,根据id求ageDROP PROCEDURE IF EXISTS pFindUserAgeById;
DELIMITER//
CREATE PROCEDURE pFindUserAgeById(IN in_id INT)
BEGIN
SELECT age FROM t_user WHERE id=in_id;
END;
//
4-1:有返回值但没有out参数的存储过程,java方法需要返回值,xml配置中也需要设置返回值类型
@Test
public void findUserAgeById(){
User user=new User(5);
Integer age=userServiceImple.findUserAgeById(user);
System.out.println(age);
}
<!-- 根据id查询用户的年龄,没有out参数需要指定resultType-->
<select id="findUserAge" statementType="CALLABLE" parameterType="User" resultType="java.lang.Integer">
<![CDATA[
{call pFindUserAge(
#{id,mode=IN,jdbcType=INTEGER}
)}
]]>
</select>
5:带有in和out参数的存储过程,根据id求age
DROP PROCEDURE IF EXISTS pFindUserAgeById;
DELIMITER//
CREATE PROCEDURE pFindUserAgeById(IN in_id INT,OUT out_age INT)
BEGIN
SELECT age INTO out_age FROM t_user WHERE id=in_id;
END;
//
5-1:有in和out的存储过程,java方法不需要返回值,根据id求age,xm配置中并未设置返回值类型
@Test
public void findUserAgeById(){
User user=new User(3);
userServiceImple.findUserAgeById(user);
System.out.println(user.getAge());
}
<!-- 根据id查询用户的年龄,有out-->
<select id="findUserAgeById" statementType="CALLABLE" parameterType="User">
<![CDATA[
{call pFindUserAgeById(
#{id,mode=IN,jdbcType=INTEGER},
#{age,mode=OUT,jdbcType=INTEGER}
)}
]]>
</select>
6:返回一个集合的存储过程,比如分页
DROP PROCEDURE IF EXISTS pPageUser;
DELIMITER//
CREATE PROCEDURE pPageUser(IN pageStart INT,IN pageSize INT)
BEGIN
SELECT * FROM t_user LIMIT pageStart,pageSize;
END;
//
6-1:java代码调用时要指定返回集合
//分页查询
@Test
public void pageUser(){
Integer pageIndex=5;
Integer pageSize=5;
List<User> pageUser = userServiceImple.pageUser(pageIndex, pageSize);
for (User user : pageUser) {
System.out.println(user);
}
}
//将参数放入Map中
public List<User> pageUser(Integer pageIndex, Integer pageSize) {
Integer pageStart=pageSize*(pageIndex-1);
Map<String, Object> map=new HashMap<String, Object>();
map.put("pageIndex", pageIndex);17 map.put("pageStart", pageStart);
return userMapper.pageUser(map);
}
<!-- 用户信息分页 -->
<select id="pageUser" statementType="CALLABLE" parameterType="map" resultType="User">
<![CDATA[
{call pPageUser(
#{pageIndex,mode=IN,jdbcType=INTEGER},
#{pageSize,mode=IN,jdbcType=INTEGER}
)}
]]>
</select>
7:修改用户存储过程,需要指定字段的长度
DROP PROCEDURE IF EXISTS pUpdateUser
DELIMITER//
CREATE PROCEDURE pUpdateUser(IN in_id INT,IN in_name VARCHAR(50),IN in_sex VARCHAR(6),IN in_age INT)
BEGIN
UPDATE t_user SET NAME=in_name ,sex=in_sex,age=in_age WHERE id=in_id;
END;
//
7-1:xml配置中的参数类型必须全部大写
//修改用户信息
@Test
public void updateUser(){
User user=new User(4, "王wu", "男", 66);
userServiceImple.updateUser(user);
}
<!-- 修改用户信息 ,INTEGER必须大写-->
<update id="updateUser" statementType="CALLABLE" parameterType="User" >
<![CDATA[
{call pUpdateUser(
#{id,mode=IN,jdbcType=INTEGER},
#{name,mode=IN,jdbcType=VARCHAR},
#{sex,mode=IN,jdbcType=VARCHAR},
#{age,mode=IN,jdbcType=INTEGER}
)}
]]>
</update>
8:注意事项:mysql存储过程需要写DELIMITER//;
:存储过程需要标明字段长度;
:有out参数的存储过程调用时不需要返回值,无out参数的需要返回值;
:xml配置时,需要注明statementType="CALLABLE";
:#{id,mode=IN,jdbcType=INTEGER},jdbcType的数据类型必须全部为大写;
:<tx:method name="find*" propagation="REQUIRED"/>,使用存储过程调用数据库数据时,方法要设置为propagation="REQUIRED",不能为read-only="true"