第一节 复习
单表查询 :使用的select的属性 resultType
resultType属性的取值
a)查询结果为List集合 ,取值为List集合中泛型的数据类型 (别名)
b)查询结果为单个对象 , 取值为对象类型的(别名)
多表查询
resultMap标签的作用:
(1)用于手动映射
(2)N+1方式的多表查询
(3)表连接查询
一对一 :association 标签 查询的返回值类型使用 javaType属性
一对多 :collection标签 查询的返回值类型使用 是ofType属性
第二节、Mybatis动态sql语句拼接
一、if标签
if标签的作用:用于条件判断
接口
package com.bjsxt.mapper;
import com.bjsxt.entity.Emp;
import java.util.List;
public interface EmpMapper {
public List<Emp> query(String ename, String job);
}
<?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.bjsxt.mapper.EmpMapper">
<select id="query" resultType="emp">
select * from emp where
<if test="param1!=null and param1!=''">
and ename=#{param1}
</if>
<if test="param2!=null and param2!=''">
and job=#{param2}
</if>
</select>
</mapper>
第一个参数使用param1,第二个参数使用param2,依次类推
如果不想使用param1,则可以在接口中定义方法是,给形参使用注解起别名(相当于实参的名称)
public List<Emp> queryByJob(@Param("empjob") String job);
<select id="queryByJob" resultType="emp">
select * from emp where 1=1
<if test="empjob!=null and empjob!=''">
and job=#{empjob}
</if>
</select>
测试
package com.bjsxt.test;
import com.bjsxt.entity.Emp;
import com.bjsxt.mapper.EmpMapper;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class Test {
public static void main(String[] args) {
//(1)获取session对象
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
//(2)接口 "new"实现类
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
//(a)第一种情况,查询全部
//List<Emp> query = mapper.query("", "");
//(b)第二种情况,根据姓名查询
// List<Emp> query = mapper.query("SMITH", "");
//(c)第三种情况,根据职位查询
// List<Emp> query = mapper.query("", "CLERK");
//(d)第四情况,根据姓名和职位一起查询
// List<Emp> query = mapper.query("JAMES", "CLERK");
List<Emp> list = mapper.queryByJob("");
System.out.println(list);
//(3)关闭session
sqlSession.close();
}
}
二、where_set_trim
where标签:会自动的增加where关键字,并且会把第一个and 进行删除
接口中的方法
public List<Emp> queryByJob(@Param("empjob") String job);
mapper.xml文件
<select id="queryByJob" resultType="emp">
select * from emp
<where>
<if test="empjob!=null and empjob!=''">
and job=#{empjob}
</if>
</where>
</select>
set标签: 用于修改 update 表名 set 。。。。
set关键字会自动的增加set关键字,并且会把最后一个逗号去掉
<?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.bjsxt.mapper.DeptMapper">
<!--如果方法的参数是基本数据类型 或String类型时,使用{0},#{1}索引,或者param1....
如果方法的参数只有一个,而且是基本数据类型或字段串时, #{可以任意写}
如果方法的参数只有一个而且是对象时,在mapper.xml中,而是使用对象的属性名称-->
<update id="update">
update dept
<set>
<if test="dname!=null and dname!=''">
dname=#{dname},
</if>
<if test="loc!=null and loc!=''">
loc=#{loc},
</if>
deptno=#{deptNo}
</set>
where deptno=#{deptNo}
</update>
</mapper>
trim标签,也是用于修改
public int update2(Dept dept);
<update id="update2">
update dept
<trim prefix="set" prefixOverrides=",">
<if test="dname!=null and dname!=''">
dname=#{dname},
</if>
<if test="loc!=null and loc!=''">
loc=#{loc},
</if>
deptno=#{deptNo}
</trim>
where deptno=#{deptNo}
</update
package com.bjsxt.test;
import com.bjsxt.entity.Dept;
import com.bjsxt.entity.Emp;
import com.bjsxt.mapper.DeptMapper;
import com.bjsxt.mapper.EmpMapper;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class TestUpdate {
public static void main(String[] args) {
//(1)获取session对象
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept dept=new Dept(21,"","");
// int update = mapper.update(dept);
int update = mapper.update2(dept);
sqlSession.commit();
System.out.println(update);
//(3)关闭session
sqlSession.close();
}
}
三、foreach标签
(5)foreach标签 (限定条件的取值范围 进行遍历)
collection :两个 list, array (如果方法的参数是一个数组时,使用array)
open :打开
close:关闭
separator :分隔
item:迭代主量
接口中 方法 (foreach就是遍历方法的参数【方法中的参数是一个信合】)
public List<Emp> queryJob(List<String>jobs );
mapper.xml文件
<select id="queryJob" resultType="emp">
select * from emp where job in
<!--collection 的取值只能有两个list,或者是array,指是方法中参数-->
<foreach collection="list" open="(" close=")" separator="," item="empjob">
#{empjob}
</foreach>
</select>
package com.bjsxt.test;
import com.bjsxt.entity.Emp;
import com.bjsxt.mapper.EmpMapper;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
public class TestQuery {
public static void main(String[] args) {
//(1)获取session对象
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<String> jobs =new ArrayList<String>();
jobs.add("CLERK");
jobs.add("SALESMAN");
jobs.add("MANAGER");
List<Emp> list = mapper.queryJob(jobs);
System.out.println(list);
//(3)关闭session
sqlSession.close();
}
}
四、bind标签
复习:
(1) 标签
(2)自动添加where关键字,去掉第一个and
(3)用于修改, 自动添加set关键字,去掉最后一个逗号
(4)用于修改
(5)标签,用于循环遍历,遍历的内容是谁?查询方法中的参数,这个参数是集合或者是数组,所以 foreach标签中的collection属于的取值为array或list
(6)bind标签 :用于模糊查询
需求:查询员工姓名中含有"A"的员工信息 ,如果姓名的值为null或"",则表示查询全部
a)如果方法的参数是基本数据类型或String,可以使用索引 0,1,…
b)如果方法的参数是基本数据类型或String,而且需要使用到其它的标签进行判断,需要使用param1,param2…
c)如果方法的参数是基本数据类型或String,而且参数只有一个,{可以任意写内容}
d)如果方法的参数是基本数据类型或String,而且参数只有一个,而且需使用其它的标签进行判断,需要使用注解为参数起别名
e)如果方法的参数是对象,则使用对象类型的属性名称
接口:
public List<Emp> queryByName(@Param("empname") String ename);
public List<Emp> queryByNameBind(@Param("empname") String ename);
mapper.xml文件
<select id="queryByName" resultType="emp">
select * from emp
<where>
<if test="empname!=null and empname!=''">
ename like '%${empname}%'
</if>
</where>
</select>
<select id="queryByNameBind" resultType="emp">
select * from emp
<where>
<if test="empname!=null and empname!=''">
<bind name="abc" value="'%'+empname+'%'"></bind>
ename like #{abc}
</if>
</where>
</select>
queryByName :底层走的是Statement ,使用的字符串的拼接
queryByNameBind :底层走的是PreparedStatement ,使用的是占位符 ?
五、sql_include_choose
(7)sql :相同的sql语句写了N多遍,太麻烦了,就可以使用sql标签进行提取
(8)include :使用include标签进行引用
<select id="queryByNameBind" resultType="emp">
<include refid="myemp"></include>
<where>
<if test="empname!=null and empname!=''">
<bind name="abc" value="'%'+empname+'%'"></bind>
ename like #{abc}
</if>
</where>
</select>
<sql id="myemp">
select * from emp
</sql>
(9)choose标签,多分支结构
特点:第一个条件成立,则不再判断后续条件,如果第一个条件不成立,才会去判断第二个条件
public List<Emp> query2(String ename, String job);
<select id="query2" resultType="emp">
<include refid="myemp"></include>
<where> <!--自动添加where关键字-->
<choose>
<when test="param1!=null and param1!=''">
and ename =#{param1}
</when>
<when test="param2!=null and param2!=''">
and job=#{param2}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
以上查询有三种情况,查询全部,根据姓名查询,根据职位查询
必会的标签
(1)if
(2)where
(3)set
(4)bind
(5)foreach
第三节、Mybatis中的分页查询
一、传统查询
三层的调用关系
(1)数据访问层
package com.bjsxt.mapper;
import com.bjsxt.entity.Emp;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface EmpMapperPage {
public List<Emp> queryPage(int index,int size);
}
<?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.bjsxt.mapper.EmpMapperPage">
<select id="queryPage" resultType="emp">
select * from emp limit #{0},#{1}
</select>
</mapper>
(2)业务逻辑层
package com.bjsxt.service;
import com.bjsxt.entity.Emp;
import java.util.List;
public interface EmpService {
public List<Emp> pageSearch(int page, int size);
}
package com.bjsxt.service.impl;
import com.bjsxt.entity.Emp;
import com.bjsxt.mapper.EmpMapperPage;
import com.bjsxt.service.EmpService;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class EmpServiceImpl implements EmpService {
@Override
public List<Emp> pageSearch(int page, int size) {
//计算
int index=(page-1)*size;
//(1)获取sqlSession
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
EmpMapperPage mapper = sqlSession.getMapper(EmpMapperPage.class);
List<Emp> list = mapper.queryPage(index, size);
sqlSession.close();//关闭
return list;
}
}
(1)界面层
package com.bjsxt.test;
import com.bjsxt.entity.Emp;
import com.bjsxt.mapper.EmpMapper;
import com.bjsxt.service.EmpService;
import com.bjsxt.service.impl.EmpServiceImpl;
import com.bjsxt.util.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
import java.util.Scanner;
public class TestPage {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入要显页的页数:");
int page=input.nextInt();
System.out.println("请输入每页要显示的条数:");
int size=input.nextInt();
//调用业务层
EmpService empService=new EmpServiceImpl();
List<Emp> list = empService.pageSearch(page, size);
for(Emp emp:list){
System.out.println(emp);
}
}
}
二、使用插件
使用插件来实现分页查询的步骤
(1)导入jar包
mybatis.xml文件的配置
<!--配置分页查询的插件-->
<plugins> <!--完整的包名+类名-->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"></property>
<!--如果当前的size 等于0就不再进行分页-->
<property name="pageSizeZero" value="true"></property>
<!--开启合理化分页-->
<property name="reasonable" value="true"></property>
</plugin>
</plugins>
(2)数据访问层 mapper
public List<Emp>queryAll();
<select id="queryAll" resultType="emp">
select * from emp
</select>
(3)业务逻辑层
public List<Emp> pageSearch2(int page, int size);
@Override
public List<Emp> pageSearch2(int page, int size) {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
EmpMapperPage mapper = sqlSession.getMapper(EmpMapperPage.class);
//在调用查询全部的方法之前使用插件
PageHelper.startPage(page,size);
List<Emp> list = mapper.queryAll();
sqlSession.close();
return list;
}
(4)界面层
与传统分页一样