1、输入映射
通过parameterType指定输入参数的类型,类型可以是简单类型、hashMap和破解哦的包装类型。
传递pojo的包装对象:
- 定义包装类型pojo
package pojo;
import java.util.List;
/**
* Student类的pojo包装对象
*/
public class StudentQueryVo {
// 在这里包装所有的查询条件
// 学生
// 使用扩展类继承Student类
private StudentCustom studentCustom;
public StudentCustom getStudentCustom() {
return studentCustom;
}
public void setStudentCustom(StudentCustom studentCustom) {
this.studentCustom = studentCustom;
}
// 其他查询条件。。。。。
private List<Integer> snos;
public List<Integer> getSnos() {
return snos;
}
public void setSnos(List<Integer> snos) {
this.snos = snos;
}
}
- 扩展类
package pojo;
/**
* Student类的扩展类
*/
public class StudentCustom extends Student {
}
- Mapper.xml
通过studentQueryVo包装类包装查询时所用到的所有信息(类),作为参数传入,在sql中调用其中的属性即可
sutdentCustom指的是StudentQueryVo的成员变量名。
<!-- 用户信息综合查询 -->
<!--
通过studentQueryVo包装类包装查询时所用到的所有信息(类),作为参数传入
在sql中调用其中的属性即可
-->
<select id="findStudentList" parameterType="StudentQueryVo" resultType="StudentCustom">
select *
from test_mybatis.student
where sage = #{studentCustom.sage}
and saddress = #{studentCustom.saddress};
</select>
- Mapper.java
/**
* 用户信息的综合查询
* 通过studentQueryVo包装类包装查询时所用到的所有信息(类),作为参数传入
* 在sql中调用其中的属性即可
* @param studentQueryVo 查询时会用到的所有信息所包装成的包装类
* @return 因为不确定查询的字段值,所以使用扩展类(或其容器)来接收查询结果
* @throws Exception
*/
public List<StudentCustom> findStudentList(StudentQueryVo studentQueryVo) throws Exception;
- 测试代码
@Test
public void TestfindStudentList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
//构造包装类
StudentQueryVo studentQueryVo = new StudentQueryVo();
//包装类的成员变量Student扩展类
StudentCustom studentCustom = new StudentCustom();
studentCustom.setSage(18);
studentCustom.setSaddress("xa");
studentQueryVo.setStudentCustom(studentCustom);
//查询
List<StudentCustom> studentCustomList = studentMapper.findStudentList(studentQueryVo);
for(StudentCustom studentCustom1 : studentCustomList){
System.out.println(studentCustom1);
}
sqlSession.close();
}
2、输出映射
输出映射有两种方式:
- resultType:
- 使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
- 如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
- 只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
输出简单类型时:查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。
输出pojo对象还是pojo列表取决于接口中设定方法的返回值
- resultMap
mybatis中使用resultMap完成高级输出结果映射。(一对多,多对多)
resultMap使用方法:-
定义resultMap
-
使用resultMap作为statement的输出映射类型
<!-- 使用id为toStudent的resultMap将sno_映射为Student.sno,sage_映射为Student.sage --> <resultMap id="toStudent" type="Student"> <id column="sno_" property="sno"/> <result column="sage_" property="sage"/> </resultMap> <!-- resultMap输出映射 --> <select id="findStudentListResultMap" parameterType="StudentQueryVo" resultMap="toStudent"> select sno sno_, sage sage_ from test_mybatis.student where sage > #{studentCustom.sage} and saddress = #{studentCustom.saddress}; </select>
- 接口
/** * 通过resultMap进行输出映射,将不可识别的字段名映射为Student对象 * @param studentQueryVo 查询时会用到的所有信息所包装成的包装类 * @return * @throws Exception */ public List<Student> findStudentListResultMap(StudentQueryVo studentQueryVo) throws Exception;
- 测试代码 略
- 测试结果
-
小结
• 使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
• 如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
3、动态sql
mybatis核心,对sql语句进行灵活的操作,通过表达式进行判断是否进行拼接,组装。
-
if判断
- Mapper.xml中使用where标签和if标签对查询条件进行判断
每一个if内test属性是拼接的条件,标签内设置拼接的字符串,用and开头
where可以自动去掉第一个and
<!-- 动态sql --> <select id="findStudentListDynamicSQL" parameterType="StudentQueryVo" resultType="StudentCustom"> select * from test_mybatis.student <where> <include refid="selectStudentWhere"/> <!-- 这里可能再调用其他的sql片段 --> </where> </select>
- 接口
/** * 使用动态sql * @param studentQueryVo 查询时会用到的所有信息所包装成的包装类 * @return 因为不确定查询的字段值,所以使用扩展类(或其容器)来接收查询结果 * @throws Exception */ public List<StudentCustom> findStudentListDynamicSQL(StudentQueryVo studentQueryVo) throws Exception;
- 测试
@Test public void findStudentListDynamicSQL() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); //构造包装类 StudentQueryVo studentQueryVo = new StudentQueryVo(); //包装类的成员变量Student扩展类 StudentCustom studentCustom = new StudentCustom(); //studentCustom.setSname("en"); //studentCustom.setSage(19); //studentCustom.setSaddress("xa"); List<Integer> snos = new ArrayList<>(); snos.add(1); snos.add(4); snos.add(7); studentQueryVo.setStudentCustom(studentCustom); studentQueryVo.setSnos(snos); //查询 List<StudentCustom> studentCustomList = studentMapper.findStudentListDynamicSQL(studentQueryVo); for(StudentCustom studentCustom1 : studentCustomList){ System.out.println(studentCustom1); } sqlSession.close(); }
- Mapper.xml中使用where标签和if标签对查询条件进行判断
-
sql片段
将又将编写好的动态sql判断代码抽取出来,则称一个sql片段。在其他的statement中就可以引用该sql片段。
- 定义、使用(在sql片段中不要写进where标签,后面使用sql片段时可能会同时使用多个sql片段,where会重复,造成语法错误)
<!-- sql片段 --> <sql id="selectStudentWhere"> <if test="studentCustom != null"> <if test="studentCustom.sname != null and studentCustom.sname != ''"> and sname like '%${studentCustom.sname}%' </if> <if test="studentCustom.sage != null and studentCustom.sage != ''"> and sage = #{studentCustom.sage} </if> <if test="studentCustom.saddress != null and studentCustom.saddress != ''"> and saddress = #{studentCustom.saddress} </if> </if> </sql> <!-- 动态sql --> <select id="findStudentListDynamicSQL" parameterType="StudentQueryVo" resultType="StudentCustom"> select * from test_mybatis.student <where> <include refid="selectStudentWhere"/> <!-- 这里可能再调用其他的sql片段 --> </where> </select>
-
foreach标签
向sql传递数组或List,mybatis使用foreach解析,foreach可以将数组或list中的元素取出来进行拼接。拼接出的串作为查询条件。如“id in(1,2,3)”或“and(id = 1 or id = 2 or id = 3)”。(高亮部分为拼接内容)
- 使用方法
<if test="snos != null"> <!-- 使用foreach拼接查询条件 如“id in(1, 2, 3)”或“and(id = 1 or id = 2 or id = 3)” collection:指定输入 对象中集合属性 item:每个遍历生成对象中 open:开始遍历时拼接的串 close:结束遍历时拼接的串 separator:遍历的两个对象中需要拼接的串 --> <foreach collection="snos" item="sno" open="and (" close=")" separator="or"> <!-- 需要进行拼接的串 --> sno = #{sno} </foreach> <!-- 实现id in(1, 2, 3) --> <foreach collection="snos" item="sno" open="and sno in (" close=")" separator=","> #{sno} </foreach> </if>
需要在包装类StudentQueryVo中设置成员变量List<Integer> snos
private List<Integer> snos; public List<Integer> getSnos() { return snos; } public void setSnos(List<Integer> snos) { this.snos = snos; }
- 测试
@Test public void findStudentListDynamicSQL() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); //构造包装类 StudentQueryVo studentQueryVo = new StudentQueryVo(); //包装类的成员变量Student扩展类 StudentCustom studentCustom = new StudentCustom(); //studentCustom.setSname("en"); //studentCustom.setSage(19); //studentCustom.setSaddress("xa"); List<Integer> snos = new ArrayList<>(); snos.add(1); snos.add(4); snos.add(7); studentQueryVo.setStudentCustom(studentCustom); studentQueryVo.setSnos(snos); //查询 List<StudentCustom> studentCustomList = studentMapper.findStudentListDynamicSQL(studentQueryVo); for(StudentCustom studentCustom1 : studentCustomList){ System.out.println(studentCustom1); } sqlSession.close(); }