logo头像

一路过来,不过游牧自己。。

SSM之MyBatis(四)


在实际查询活动中,会牵涉到很多的查询条件,或者有动态的SQL和一些模糊的查询,那是如何去做到的呢?如姓名的模糊匹配,年龄规定要在哪个区间,这样的都是比较有限制的查询!还有如果对一系列的操作采用存储过程的形式应该怎么去做?下面看看如何去做!

先提需求,然后根据需求去用代码去讲解!

一、 动态SQL与模糊查询

1、提出需求:

实现多条件查询用户(姓名模糊匹配, 年龄在指定的最小值到最大值之间),比如查询姓名带o的,查询年龄在13-19岁的,这都是模糊查询!

2、准备数据表和数据:

1
2
3
4
5
6
7
8
9
create table d_user(  
id int primary key auto_increment,
name varchar(10),
age int(3)
);

insert into d_user(name,age) values('Tom',12);
insert into d_user(name,age) values('Bob',13);
insert into d_user(name,age) values('Jack',18);

这里创建了一张d_user的表,有两个属性,一个name,一个age!

2、创建User(表实体类)

1
2
3
4
5
public class User{
private int id;
private String name;
private int age;
}

3.创建ConditionUser(查询条件实体类)

1
2
3
4
5
public class ConditionUser{
private String name;
private int minAge;
private int maxAge;
}

4、写userMapper.xml(映射文件)

写一个userMapper.xml文件

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.day03_mybatis.test6.userMapper">
<select id="getUser" parameterType="com.day03_mybatis.test6.ConditionUser" resultType="com.day03_mybatis.test6.User">
select * from d_user where age>=#{minAge} and age&lt;=#{maxAge}
<if test='name!="%null%"'>and name like #{name}</if>
</select>
</mapper>

如上所示,我们可以知道输入参数是:parameterType ConditionUser这个类中的minAge和maxAge作为参数传入!返回是个User,姓名匹配是and name like #{name}这种匹配方式!

5、写UserTest(测试)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class UserTest {

public static void main(String[] args) throws IOException {

Reader reader = Resources.getResourceAsReader("conf.xml");

SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

SqlSession sqlSession = sessionFactory.openSession();

String statement = "com.atguigu.day03_mybatis.test6.userMapper.getUser";

List<User> list = sqlSession.selectList(statement, new ConditionUser("%a%", 1, 12));

System.out.println(list);
}
}

如图,可以查询出带名字中带a和年龄在1-12岁之间的数据!

6、总结:MyBatis中可用的动态SQL标签

if choose(when,otherwise) trim(where,set) foreach

二、调用存储过程

1、提出需求

查询得到男性或女性的数量, 如果传入的是0就女性否则是男性!就是说,如果传入0,查询女性的数量,如果传入1,查询男性的数量

2、准备数据库表和存储过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
create table p_user(  
id int primary key auto_increment,
name varchar(10),
sex char(2)
);

insert into p_user(name,sex) values('A',"男");
insert into p_user(name,sex) values('B',"女");
insert into p_user(name,sex) values('C',"男");

#创建存储过程(查询得到男性或女性的数量, 如果传入的是0就女性否则是男性)
DELIMITER $
CREATE PROCEDURE mybatis.ges_user_count(IN sex_id INT, OUT user_count INT)
BEGIN
IF sex_id=0 THEN
SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='女' INTO user_count;
ELSE
SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='男' INTO user_count;
END IF;
END
$

#调用存储过程
DELIMITER ;
SET @user_count = 0;
CALL mybatis.ges_user_count(1, @user_count);
SELECT @user_count;

如上所示,我们创建了一张p_user表,然后定义了一个存储过程,CREATE PROCEDURE mybatis.ges_user_count,这个名字是mybatis.ges_user_count,传入的用IN ,传入sex_id,输出用 OUT,用user_count,然后用IF判断,和Then去写,整个用SELECT···INTO去赋值,统计用Count,最后还有调用存储过程范例:
用CALL +过程名+传入参数!注意变量的传入方式!

3、创建表的实体类

1
2
3
4
5
public class User {
private String id;
private String name;
private String sex;
}

4、userMapper.xml

直接编写xml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
<mapper namespace="com.mybatis.test7.userMapper">
<!--
查询得到男性或女性的数量, 如果传入的是0就女性否则是男性
CALL mybatis.get_user_count(1, @user_count);
-->
<select id="getCount" statementType="CALLABLE" parameterMap="getCountMap">
call mybatis.get_user_count(?,?)
</select>
<parameterMap type="java.util.Map" id="getCountMap">
<parameter property="sex_id" mode="IN" jdbcType="INTEGER"/>
<parameter property="user_count" mode="OUT" jdbcType="INTEGER"/>
</parameterMap>
</mapper>

如上所示,调用存储过程,用statementType标识这是一个CALLABLE语句,然后参数是parameterMap,mode标识他是输入还是输出!jdbcType标识他是什么类型的数据!

5、测试调用

1
2
3
4
5
Map<String, Integer> paramMap = new HashMap<>();
paramMap.put("sex_id", 0);
session.selectOne(statement, paramMap);
Integer userCount = paramMap.get("user_count");
System.out.println(userCount);

我们将这种用键值的方式去存,这样就可以得到最后的count值

6、参数解释

(1)parameterMap:引用
(2)statementType:指定Statement的真实类型:CALLABLE执行调用过程的真实语句
(3):定义多个参数的键值对
(4)type:需要传递的参数的真实类型 java.util.Map
(5):指定一个参数key-value

多走路,多思考,越努力,越幸运!
———————————————YoungerFary

微信打赏

赞赏是不耍流氓的鼓励