Mybatis框架学习笔记 --- [动态sql的使用]
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis框架学习笔记 --- [动态sql的使用]相关的知识,希望对你有一定的参考价值。
mybatis3版本的文档 -->mybatis文档
写在前面
Ok,也是进行到动态sql这部分了;
需要说明的是,后来我又给员工表添加了一个记录年龄的列,当然在员工类中也添加了属性以及它的getset方法;构造方法;toString();这些也都加上这个属性了.
ml
1. if 标签与 where 标签
使用 if标签
可以对条件进行判断;
一般是结合在其他标签中使用;
where 标签
可以动态地添加where
关键字 ,并且可以做到 自动去除后面不符合条件时 的and
或者or
关键字
<where>
元素会进行判断,如果它包含的标签中有返回值的话,它就插入一个where
。
如果标签返回的内容是以AND
或OR
开头,它会自动去除掉AND
或OR
。
比如说,我要设置两个查询条件,姓名和性别筛选查询人员的信息,但是也可以不通过这两个条件进行查询,也可以一个条件去查询,而不使用另一个条件;
当然你可以写4个SQL语句进行处理;
但这时用动态SQL查询的话,还是比较方便的,只需要写一次sql语句就能同时兼顾这四种情况.
在实例中看看效果
Ok,在EmployeeMapper
职工类的持久层接口写个方法;根据年龄和性别动态查询员工的信息;
//根据条件动态查询员工列表; 姓名/性别; @Param()为参数作注解,到时候SQL那边就用注解里面的名称;
List<Employee> getEmpByNameOrAge(@Param("name") String name, @Param("sex")String sex);
在EmployeeMapper.xml
中添加对应的sql;
<?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.xiaozhi.mapper.EmployeeMapper">
<!--定义映射关系map-->
<resultMap id="empmap" type="employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="sex" property="sex"/>
<!--关联部门表-->
<association property="dept" javaType="dept">
<result column="dname" property="name"/>
</association>
<!--关联用户管理表-->
<association property="user" javaType="user">
<result column="account" property="account"/>
</association>
</resultMap>
<!--根据姓名/性别动态查询员工-->
<select id="getEmpByNameOrAge" resultMap="empmap">
SELECT
e.`id`,
e.`name`,
e.`sex`,
e.`age`,
d.`name` dname ,
u.`account`
FROM t_employee e
LEFT JOIN t_dept d ON e.`deptID`=d.`id`
LEFT JOIN t_user u ON u.`id`=e.`optionId`
<where>
<if test="name != null & name !='' ">
e.name = #{name}
</if>
<if test="sex != null & sex !='' ">
and e.sex= #{sex}
</if>
</where>
</select>
</mapper>
当然;在核心配置文件mybatis-config.xml
里面还要配置员工的mapper映射文件地址;
(我这个是之前配置了的)
测试使用;
这里也是直接把上次的那个页面查询框改了一下;
Mybatis框架学习笔记(5) —[多表关联查询 连接到前端页面显示]
OK,就从service
包下的EmployeeService
来一步步修改吧;
public class EmployeeService {
//根据姓名/性别动态查询员工;
public List<Employee> getEmpByNameOrAge(String name,String sex){
//调用工具类;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
//调用方法;
List<Employee> list = mapper.getEmpByNameOrAge(name, sex);
//关闭sqlSession;
sqlSession.close();
return list;
}
}
servlet
包下的EmployeeServlet
public class EmployeeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out=null;
//获取到标记参数;
String mark = req.getParameter("mark");
if(mark.equals("empList")){
try{
//请求编码;响应解码;
resp.setContentType("text/html;charset=utf-8");
//会以流的方式返回;
out = resp.getWriter();
//获取参数;
String name = req.getParameter("name");
String sex = req.getParameter("sex");
System.out.println("正在查询姓名为--:"+name+"性别为==>"+sex);
//调用服务层处理;
EmployeeService employeeService = new EmployeeService();
List<Employee> empByNameOrAge = employeeService.getEmpByNameOrAge(name, sex);
//控制台输出测试;
//empByNameOrAge.forEach(System.out::println);
//不为空就发送出去;
if(!empByNameOrAge.isEmpty()){
out.print(new Gson().toJson(empByNameOrAge));
}else {
out.print(0);//-->不存在,提示信息
}
}catch (Exception e){
e.printStackTrace();
out.print(500);//-->服务器错误;
}
}
}
}
当然,没使用到注解的话,这里还要手动配置一下;web.xml
<!--配置员工servlet-->
<servlet>
<servlet-name>empServlet</servlet-name>
<servlet-class>com.xiaozhi.servlet.EmployeeServlet</servlet-class>
</servlet>
<!--servlet映射-->
<servlet-mapping>
<servlet-name>empServlet</servlet-name>
<url-pattern>/do/emp</url-pattern>
</servlet-mapping>
employee.html
员工的列表访问页面;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>员工列表</title>
<!--部署jquery-->
<script src="js/jquery.1.8.3.min.js" type="text/javascript"></script>
<script type="text/javascript">
//页面打开时发送请求;这里不传递姓名和性别查询条件;
$(function () {
$.get("do/emp", {mark:"empList"}, function (res) {
//测试获取的数据;
//console.log(res)
if(res==500){
alert("抱歉,服务器出了点问题");
}else if(res==0){
//弹框提示;
alert("抱歉,暂时没有员工!")
}else {
//拼接存入表格;
var str2="";
for (var i = 0; i < res.length; i++) {
str2+="<tr align='center'>";
str2+="<td>"+(i+1)+"</td>";
str2+="<td>"+res[i].name+ "</td>";
str2+="<td>"+res[i].sex+ "</td>";
str2+="<td>"+res[i].dept.name+ "</td>";
str2+="<td>"+res[i].user.account+ "</td>";
str2+="</tr>";
}
$("#table").append(str2);
}
}, "json");
});
//点击搜索时,查询员工;
function getEmp(){
//先获取到输入框的值
var name = $("input[name='name']").val();
var sex = $("input[name='sex']").val();
//发送请求;进行查询;注意携带姓名或性别
$.get("do/emp",{mark:"empList",name:name,sex:sex},function (res){
//测试响应的数据;
console.log(res)
if(res==500){
alert("抱歉,服务器出了点问题");
}else if(res==0){
//清除表格的信息;
$("tr:gt(0)").remove();
//弹框提示;
alert("该员工不存在!!!");
}else {
//同样地,先清除全部的信息;
$("tr:gt(0)").remove();
//拼接显示数据;
var str4="";
for (var i = 0; i < res.length; i++) {
str4 += "<tr align='center'>";
str4 += "<td>" + (i+1) + "</td>";
str4 += "<td>" + res[i].name + "</td>";
str4 += "<td>" + res[i].sex + "</td>";
str4 += "<td>" + res[i].dept.name + "</td>";
str4 += "<td>" + res[i].user.account + "</td>";
str4 += "</tr>";
}
$("#table").append(str4);
}
},"json");
}
//点击全部员工,刷新页面;
function getAll(){
location.reload();
}
</script>
</head>
<body>
<form style="width: 1080px" id="form">
<label>
姓名:<input type="text" name="name" placeholder="请输入要查询的员工姓名:"/>
性别:<input type="text" name="sex" placeholder="请输入要查询的员工性别:"/>
</label>
<input type="button" value="搜索" onclick="getEmp()"/>
<!--当然为了能够调回之前的全部员工,再次加载一次这个页面-->
<input type="button" value="显示全部员工" onclick="getAll()">
</form>
<br/>
<!--显示的表格-->
<table width="100%" border="1" cellspacing="0" id="table">
<th>编号</th>
<th>员工姓名</th>
<th>员工性别</th>
<th>所属部门</th>
<th>操作人</th>
</table>
</body>
</html>
配置号tomcat服务器后,Ok启动,看看效果
(1)首次访问时,这时的查询是不带条件的;
所以这边接收到的也是null空值,所以不会去拼接where子句
试试用姓名查询;
(1)这里接收到了姓名,以及空字符串性别; 根据姓名去进行了查询;但是查询时没有拼接性别哦;
这时因为之前在写SQL语句时,在<if>标签内加了条件判断
(3)试试只输入性别进行查询
接收到的姓名为空字符串;则在查询时只根据性别条件进行查询,<where>标签去掉了and关键字
(4)根据姓名和性别查询
当然,姓名和性别都被作为条件进行了查询
(5)那么打开了页面后,不输入查询条件,直接查询呢,这时就会直接查询出所有的员工,因为接收到的姓名和性别的输入框都是空的字符串
由于接收到了空字符串,所以自动去掉了后面的where查询条件
其实,不使用的<where>
标签,也能做到动态SQL的查询;也算是一种奇技淫巧了;
直接在查询条件时拼接一段成立的条件,比如说在where 查询条件后拼接 1=1
;防止后面的条件若都不符合就查询输出所有的数据;
那就试试吧;
在EmployeeMapper.xml
中修改SQL语句;把之前的暂时注释掉;
<!--根据姓名/性别动态查询员工 奇技淫巧-->
<select id="getEmpByNameOrAge" resultMap="empmap">
SELECT
e.`id`,
e.`name`,
e.`sex`,
e.`age`,
d.`name` dname ,
u.`account`
FROM t_employee e
LEFT JOIN t_dept d ON e.`deptID`=d.`id`
LEFT JOIN t_user u ON u.`id`=e.`optionId`
where 1=1
<if test="name != null & name !='' ">
and e.name = #{name}
</if>
<if test="sex != null & sex !='' ">
and e.sex= #{sex}
</if>
</select>
查询试试;
例如仅通过性别为条件进行查询
查询效果还是不错的
2.trim标签
自定义 trim 元素来定制 where 元素
使用trim标签也可以完成where子句的拼接,以及and/or这种关键字的去除
这时prefix="where" 表示可拼接的前缀
;prefixOverrides= "and|or"表示若出现这些关键字 根据情况就自动去除掉
OK,那就试试吧,注释掉之前的查询SQL;
<!--使用trim标签 -->
<!--根据姓名/性别动态查询员工-->
<select id="getEmpByNameOrAge" resultMap="empmap">
SELECT
e.`id`,
e.`name`,
e.`age`,
e.`sex`,
d.`name` dname ,
u.`account`
FROM t_employee e
LEFT JOIN t_dept d ON e.`deptID`=d.`id`
LEFT JOIN t_user u ON u.`id`=e.`optionId`
<trim prefix=以上是关于Mybatis框架学习笔记 --- [动态sql的使用]的主要内容,如果未能解决你的问题,请参考以下文章