一、Mybatis常用标签
1、mapper.xml文件
(1)mapper.xml文件概述
mapper接口的缺点:
接口中注释的写法是硬编码,不易于后期的维护,如果类中的属性名和数据库中的名字不一样则无相应的值,在实际项目中不推荐使用。
mapper.xml文件是mybatis中定义的sql映射的文件,相对于mapper接口的优势是(方便):
- 易于维护和管理,语法结构易读,方便进行调整、重构和扩展
- 易于定义分离关注原则(通过把SQL逻辑和业务逻辑分离)
- 分离SQL逻辑和业务逻辑有利于代码的模块化开发
(2)Mapper.xml文件的结构
示例:
首先需要配置文件:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/coolsharkhub?useSSL=false&serverTimeZone=Asia/Shanghai
spring.datasource.name=root
spring.datasource.password=root
logging.level.cn.highedu.boot3.mapper=debug
mybatis.mapper-locations=classpath:mapper/*.xml
建立实体类:
/**
* @document: 商品类别实体类
* 对应数据库中category表
* @Author:SmallG
* @CreateTime:2023/9/5+9:51
*/
public class Category {
private Long id;
private String name;
private Boolean display;
private Integer orderNum;
private LocalDateTime create;
private LocalDateTime update;
省略...
}
mapper接口:
@Mapper
public interface CategoryMapper {
/**
* 根据id查询商品类别
*/
Category getCategoryById(long id);
}
CategoryMapper.xml文件:
<?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="cn.highedu.boot3.mapper.CategoryMapper">
<select id="getCategoryById" resultType="cn.highedu.boot3.entity.Category">
select * from category where id = #{id}
</select>
</mapper>
测试文件:
@SpringBootTest //声明这是一个springboot的测试类
class CategoryMapperTest {
@Autowired
CategoryMapper categoryMapper;
@Test
void getCategoryById() {
Category category = categoryMapper.getCategoryById(1L);
System.out.println(category);
}
}
访问流程:
(3)下划线映射驼峰
修改一下配置文件:
#把数据库的下划线标识转换为类中的驼峰标识
mybatis.configuration.map-underscore-to-camel-case=true
2、Mybatis基础标签
(1)增删改查标签
共同的属性:
- id:指定标签对应的抽象方法的名称,是标签的必要属性,同一个Mapper.xml文件中不能有两个标签拥有相同的id值
- parameterType:输入参数的类型
- statementType:指定是否使用预处理语句,可选值为 STATEMENT、PREPARED、CALLABLE,默认为 PREPARED
特殊的属性:
1、select标签
- resultType:指定查询结果的数据类型,适用于查询结果与Java类完全匹配的情况
- resultMap:指定查询结果映射的规则,适用于查询结果不能直接映射到某个Java类的情况
2、insert标签
- useGeneratedKeys:表示是否使用自动生成的主键,默认为false。如果设置为true,则在插入数据时会返回主键值
- keyProperty:表示将自动生成的主键值赋值给哪个属性,需要与useGeneratedKeys一起使用
先写方法,后写操作
添加商品
编写mapper接口中的方法:
/**
* 保存一条商品类别记录
* @return 返回受影响的行数
*/
int insertCategory(Category category);
编写mapper.xml文件中的操作代码:
<!-- useGeneratedKeys返回生成的主键 -->
<insert id="insertCategory" useGeneratedKeys="true">
insert into category (name, order_num)
values (#{name}, #{orderNum})
</insert>
删除商品
mapper添加代码:
/**
* 根据id删除一条商品类别记录
* @param id 传入的id值
* @return 返回受影响的行数
*/
int deleteCategoryById(long id);
mapper.xml添加代码:
<!-- 删除一条商品类别记录 -->
<delete id="deleteCategoryById">
delete from category where id=#{id}
</delete>
测试代码:
@Test
void deleteCategoryById() {
int result = categoryMapper.deleteCategoryById(8L);
if (result>0){
System.out.println("成功删除了"+result+"条记录");
} else {
System.out.println("删除失败!");
}
}
修改商品
mapper接口添加代码:
/**
* 根据id修改display的值
* @param id 传入的id
* @return 返回受影响的行数
*/
int updateDisplayById(@Param("display") Integer display,@Param("id") long id);
mapper.xml配置文件添加代码:
<!-- 根据id修改display的值 -->
<update id="updateDisplayById">
update category set display=#{display} where id=#{id}
</update>
测试代码:
@Test
void updateDisplayById() {
int result = categoryMapper.updateDisplayById(0,5L);
if (result>0){
System.out.println("成功修改了"+result+"条数据");
}else {
System.out.println("修改失败");
}
}
查询商品
mapper接口代码:
/**
* 查询
* @return
*/
List<Category> listAllCategory();
mapper.xml代码:
<select id="listAllCategory" resultType="cn.highedu.boot3.entity.Category">
select * from category
</select>
测试代码:
@Test
void listAllCategory() {
List<Category> categories = categoryMapper.listAllCategory();
//函数式引用
categories.forEach(System.out::println);
}
(2)模糊查询
正常思路
mapper接口:
/**
* 根据名字模糊查询商品类别
* @param name 商品类别名称
* @return
*/
List<Category> listByName(String name);
mapper.xml代码:
<!-- 模糊查询 -->
<select id="listByName" resultType="cn.highedu.boot3.entity.Category">
select * from category where name like #{name}
</select>
测试代码:
@Test
void listByName() {
List<Category> categories = categoryMapper.listByName("%精品%");
categories.forEach(System.out::println);
}
改良查询(推荐使用)
mapper接口部分代码:
/**
* 根据名字模糊查询商品类别
* @param name 商品类别名称
* @return
*/
List<Category> listByName(String name);
mapper.xml部分代码:
<!-- 模糊查询 -->
<select id="listByName" resultType="cn.highedu.boot3.entity.Category">
select * from category where name like concat('%',#{name},'%')
</select>
测试代码:
@Test
void listByName() {
List<Category> categories = categoryMapper.listByName("精品");
categories.forEach(System.out::println);
}
(3)resultMap标签
当查询的结果无法简单的映射到一个Java类时(实体类的名称和数据库中的字段名不一致),可以使用resultMap标签。
public class UserLog {
private Long id;
private Long userId;
private String optType;
private LocalDateTime create; //数据库字段gmt_create
private LocalDateTime modified; //数据库字段gmt_modified
省略...get...set...构造...toString...
}
mapper接口:
@Mapper
public interface UserLogMapper {
/**
* 查询所有的用户日志
*/
List<UserLog> listAll();
}
mapper.xml配置文件:
<?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="cn.highedu.boot3.mapper.UserLogMapper">
<!-- 定义一个结果映射,主要是为了解决类中的属性名和数据库中的字段名不一致问题 -->
<resultMap id="UserLogMap" type="cn.highedu.boot3.entity.UserLog">
<!-- 主键映射 -->
<id column="id" property="id"></id>
<!-- 普通字段映射 -->
<!-- column表示数据库中的字段名 property表示类中的属性名 -->
<result column="user_id" property="userId"></result>
<result column="otp_type" property="optType"></result>
<result column="gmt_create" property="create"></result>
<result column="gmt_modified" property="modified"></result>
</resultMap>
<select id="listAll" resultMap="UserLogMap">
select * from user_log
</select>
</mapper>
测试类:
@SpringBootTest
class UserLogMapperTest {
@Autowired
UserLogMapper userLogMapper;
@Test
void listAll() {
List<UserLog> list = userLogMapper.listAll();
list.forEach(System.out::println);
}
}
3、封装关联查询结果
(1)association标签
’<‘association’>‘ 标签是用于定义对象之间关联关系的标签,主要用于处理一对一(One-to-One)的关联查询结果映射。“标签是用于定义对象之间关联关系的标签,主要用于处理一对一(One-to-One)的关联查询结果映射。
association标签的属性如下:
- property:指定Java类中的属性名,用于关联查询结果中的对应字段
- column:指定查询结果集合中的字段名
- javaType:指定关联的Java类型,代表关联属性的数据类型
多对一关系映射
创建实体:
/**
* @document: 商品实体类 对应数据库表product
* @Author:SmallG
* @CreateTime:2023/9/5+15:12
*/
public class Product {
private Long id;
private String title;
private String image;
private Double discount;
private Double price;
private Integer sales;
private Integer stock;
private Integer views;
private LocalDateTime created;//创建时间
private LocalDateTime updated; //修改时间
private Category category; //类别属性 对应数据库category_id;
省略...
}
mapper接口:
@Mapper
public interface ProductMapper {
/**
* 根据商品id查询商品
* @param id
* @return
*/
Product getById(Long id);
}
mapper.xml文件:
<?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="cn.highedu.boot3.mapper.ProductMapper">
<!-- 结果映射 -->
<resultMap id="ProductMap" type="cn.highedu.boot3.entity.Product">
<id column="id" property="id"></id>
<result column="title" property="title"></result>
<result column="image" property="image"></result>
<result column="discount" property="discount"></result>
<result column="price" property="price"></result>
<result column="sales" property="sales"></result>
<result column="stock" property="stock"></result>
<result column="views" property="views"></result>
<result column="created" property="created"></result>
<result column="updated" property="updated"></result>
<!--多对一关系-->
<!--property是类中的属性名,column是数据库的字段名-->
<!--javaType是类中属性的类型-->
<association property="category" column="category_id" javaType="cn.highedu.boot3.entity.Category">
<!--Category类中的属性与Category表的映射关系-->
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="display" property="display"></result>
<result column="order_num" property="orderNum"></result>
<result column="created" property="created"></result>
<result column="updated" property="updated"></result>
</association>
</resultMap>
<!--根据id查询一件商品信息-->
<select id="getById" resultMap="ProductMap">
select p.id,
p.title,
image,
discount,
price,
sales,
stock,
category_id,
views,
p.created,
p.updated,
c.id,
name,
display,
order_num,
c.created,
c.updated
from product p
join category c on p.category_id = c.id
where p.id = #{id}
</select>
</mapper>
(2)封装一对多查询结果
关联查询中一对多查询的结果,对应到Java类中一般在【一】的一方采用List集合的方式,关联【多】的一方的对象的集合。
在类别中添加对应的所有商品
在categoryMapper.xml中添加resultMap:
collection标签用于实现集合类型属性的自动封装。
<resultMap id="categoryMap" type="cn.highedu.boot3.entity.Category">
<!--Category类中的属性与Category表的映射关系-->
<result column="name" property="name"></result>
<result column="display" property="display"></result>
<result column="order_num" property="orderNum"></result>
<result column="created" property="created"></result>
<result column="updated" property="updated"></result>
<!--property是类中的属性 ofType是集合中数据的类型-->
<collection property="products" ofType="cn.highedu.boot3.entity.Product">
<!--Product映射关系-->
<id column="id" property="id"></id>
<result column="title" property="title"></result>
<result column="image" property="image"></result>
<result column="discount" property="discount"></result>
<result column="price" property="price"></result>
<result column="sales" property="sales"></result>
<result column="stock" property="stock"></result>
<result column="views" property="views"></result>
<result column="created" property="created"></result>
<result column="updated" property="updated"></result>
</collection>
</resultMap>
<!-- 根据类别id查询商品信息 -->
<select id="getByIdWithProducts" resultMap="CategoryMap">
select p.id,
p.title,
image,
discount,
price,
sales,
stock,
category_id,
views,
p.created,
p.updated,
c.id,
name,
display,
order_num,
c.created,
c.updated
from product p
join category c on p.category_id = c.id
where c.id = #{id}
</select>
CategoryMapper接口添加方法:
/**
* 根据id查询一个类别,同时查询出该类别所有的商品信息
* @param id 类别id
* @return 类别对象 包含商品的集合
*/
Category getByIdWithProducts(Long id);
测试方法:
@Test
void getByIdWithProducts() {
Category category = categoryMapper.getByIdWithProducts(2L);
System.out.println(category);
//查看类中 的products集合
category.getProducts().forEach(System.out::println);
}
(3)复用SQL语句(开发普遍应用)
<!-- 根据类别id查询商品信息 -->
<select id="getByIdWithProducts" resultMap="CategoryMap">
<!--使用sql片段 include(包含)-->
<include refid="queryProductAndCategory"></include>
where c.id =#{id}
</select>
<!-- 一段公共的sql片段,任何地方都可以引用 -->
<sql id="queryProductAndCategory">
select p.id,
p.title,
image,
discount,
price,
sales,
stock,
category_id,
views,
p.created,
p.updated,
c.id,
c.name,
display,
order_num,
c.created,
c.updated
from product p
join category c on p.category_id = c.id
</sql>
二、动态SQL
1、动态sql概述
在查询的时候根据业务需求有些条件有时传有时不传,sql语句可能产生动态变化,动态sql可以通过不同的条件产生不同的sql语句。
MyBatis提供了多种动态SQL标签,较为常用的四种如下所示:
1、if标签:用于判断某个条件是否满足,如果满足则执行某些操作。
2、choose标签:类似于Java中的switch语句,根据某个条件选择不同的分支,可以配合when和otherwise(除此以外)标签使用。
3、foreach标签:用于遍历集合(如List、Map等),根据集合中的元素动态构建SQL语句。
4、where标签:用于动态生成where语句,当where语句为空时,不会加入到最终的SQL语句中。
where和if标签示例
添加ProductMapper接口中的方法:
/**
* 商品信息查询 多条件查询 查询条件不股东
*
* @param title 商品标题---模糊查询
* @param minPrice 最小商品价格---范围查询
* @param maxPrice 最大商品价格
* @return 满足条件的所有商品
*/
List<Product> listProduct(@Param("title") String title,
@Param("minPrice") Double minPrice,
@Param("maxPrice") Double maxPrice);
mapper.xml查询语句:
<select id="listProduct" resultMap="ProductMap">
select *
from product
<!--where标签可以保证sql语句的正确性-->
<!--如果一个条件都不满足会智能的去掉where关键字 还可以去掉多余的and关键字-->
<where>
<!--if表示条件判断,test写具体逻辑 条件满足sql语句中加上相应的条件-->
<!--title不等于空值并且不能等于空字符串-->
<if test="title != null and title !=''">
title like concat('%',#{title},'%')
</if>
<!-->表示大于符号 <表示小于符号-->
<if test="minPrice != null">
and price >= #{minPrice}
</if>
<if test="maxPrice != null">
and price <= #{maxPrice}
</if>
</where>
</select>
测试代码:
@Test
void listProduct() {
//查询是没有maxPrice条件
List<Product> products = productMapper.listProduct("男",50.0,null);
products.forEach(System.out::println);
}
when标签示例
需求:开发一个查询商品列表的方法,接收字符串类型的orderType作为参数。其中:
- 如果传入的参数为“sales”,则按照销量降序排列
- 如果传入的参数为“views”,则按照浏览量降序排列
- 其他情况下,按stock库存量降序排列
mapper接口:
/**
* 根据不同的排序类别 查询后的商品数据
* @param orderType 根据价格流量销量排序
* @return 返回
*/
List<Product> listProductByOrder(String orderType);
xml配置文件:
<!--查询具有排序的商品信息-->
<select id="listProductByOrder" resultMap="ProductMap">
select *
from product
order by
<!--多分支 choose类似于java的switch-->
<choose>
<!--相当于case-->
<when test="orderType == 'price'">
price
</when>
<when test="orderType == 'views'">
views
</when>
<when test="orderType == 'sales'">
sales
</when>
</choose>
</select>
@Test
void listProductByOrder() {
productMapper.listProductByOrder("sales").forEach(System.out::println);
}
效果展示:
foreach标签示例
需求:开发一个查询商品的方法,接收Integer类型的集合作为参数,查询商品类别的id值与集合中数据值相同的商品信息。
mapper接口添加方法:
/**
* 根据商品id查多件商品
* @return
*/
List<Product> listProductByIds(@Param("ids") List<Integer> ids);
xml文件:
<!--根据多个id查询多个商品-->
<select id="listProductByIds" resultMap="ProductMap">
select *
from product
<if test="ids != null and ids.size() > 0">
where id in
<!--item为每个元素起个别名-->
<!--open 开始标识-->
<!--close 结束标识-->
<!--separator分割-->
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
</select>
测试代码:
@Test
void listProductByIds() {
productMapper.listProductByIds(List.of(2,3,4)).forEach(System.out::println);
}
效果展示:
set标签示例
mapper接口添加方法:
/**
* 修改类别的名称、display(是否显示)、orderNum(展示顺序)其中几个
* @param category
* @return
*/
int updateBySet(@Param("category") Category category);
xml添加操作:
<update id="updateBySet">
update category
<set>
<!--category.name(OGNL - 对象导航语言,默认调用对象相应的get方法取值)-->
<if test="category.name != null">
name=#{category.name},
</if>
<if test="category.display != null">
display=#{category.display},
</if>
<if test="category.orderNum != null">
order_num=#{category.orderNum}
</if>
</set>
where id = #{category.id}
</update>
测试方法:
@Test
void updateBySet() {
Category category = categoryMapper.getCategoryById(5L);
category.setName("ABC");
category.setDisplay(false);
category.setOrderNum(8);
int i = categoryMapper.updateBySet(category);
if (i > 0) {
System.out.println("修改成功");
} else {
System.out.println("修改失败");
}
}
效果展示:
修改成功
三、练习
1 MyBatis关联查询练习
请在Homework项目下新建一个Module,该Module为一个Spring Boot项目,命名为ssm_hw03,作为今天的课后作业项目。
首先,将课前资料中的sample1.sql文件中的数据导入到数据库中的ssm_hw01db数据库中。
表格的字段及关系如图所示:
表中的样例数据如图所示:
请基于上述数据库表和数据,在ssm_hw03项目中实现如下需求:
1、开发查询全部角色数据的方法,关联查询角色的坐骑数据。
2、开发查询全部国家数据的方法,关联查询该国家中的全部角色数据。
3、开发查询全部战役的方法,关联查询参加过该战役的全部角色数据。
提示:
1、仅需要完成持久层的开发和测试即可,必须有测试用例。
2、持久层可以仅声明一个HWMapper接口,对应HWMapper.xml文件。
实体类:
/**
* @document: 战役实体类
* @Author:SmallG
* @CreateTime:2023/9/5+18:36
*/
public class Battle {
private Integer id;
private String name;
private List<Character> characters;
省略...
}
/**
* @document: 角色实体类
* @Author:SmallG
* @CreateTime:2023/9/5+18:35
*/
public class Character {
private Integer id;
private String name;
private Horse horse;
省略...
}
/**
* @document: 国家实体类
* @Author:SmallG
* @CreateTime:2023/9/5+18:36
*/
public class Country {
private Integer id;
private String name;
private List<Character> characters;
省略...
}
/**
* @document: 坐骑实体类
* @Author:SmallG
* @CreateTime:2023/9/5+18:36
*/
public class Horse {
private Integer id;
private String name;
省略...
}
mapper接口:
@Mapper
public interface HWMapper {
/**
* 开发查询全部角色数据的方法,关联查询角色的坐骑数据。
* @return
*/
List<Character> getAll();
/**
* 开发查询全部国家数据的方法,关联查询该国家中的全部角色数据。
* @return
*/
List<Country> getAllCountry();
/**
* 查询全部战役的方法,关联查询参加过该战役的全部角色数据。
* @return
*/
List<Battle> getBattle();
}
mapper.xml配置文件:
<?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.example.ssm_hw03.mapper.HWMapper">
<resultMap id="getAllMap" type="com.example.ssm_hw03.entity.Character">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<association property="horse" javaType="com.example.ssm_hw03.entity.Horse">
<id column="hid" property="id"></id>
<result column="hname" property="name"></result>
</association>
</resultMap>
<select id="getAll" resultMap="getAllMap">
select t.id, t.name, h.id as hid, h.name as hname
from t_character t
join horse h on t.hid = h.id
</select>
<resultMap id="getAllCountry" type="com.example.ssm_hw03.entity.Country">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<collection property="characters" ofType="com.example.ssm_hw03.entity.Character">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
<association property="horse" javaType="com.example.ssm_hw03.entity.Horse">
<id column="hid" property="id"></id>
<result column="hname" property="name"></result>
</association>
</collection>
</resultMap>
<select id="getAllCountry" resultMap="getAllCountry">
select c1.id, c1.name, c2.id as cid, c2.name as cname, h.id as hid, h.name as hname
from country c1
join t_character c2 on c1.id = c2.cid
join horse h on h.id = c2.hid
</select>
<resultMap id="getBattleMap" type="com.example.ssm_hw03.entity.Battle">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<collection property="characters" ofType="com.example.ssm_hw03.entity.Character">
<id column="tid" property="id"></id>
<result column="tname" property="name"></result>
<association property="horse" javaType="com.example.ssm_hw03.entity.Horse">
<id column="hid" property="id"></id>
<result column="hname" property="name"></result>
</association>
</collection>
</resultMap>
<select id="getBattle" resultMap="getBattleMap">
select b.id, b.name, t.id as tid, t.name as tname, h.id as hid, h.name as hname
from battle b
join character_battle c on b.id = c.bid
join t_character t on c.cid = t.id
join horse h on h.id = t.hid;
</select>
</mapper>
测试类:
@SpringBootTest
class HWMapperTest {
@Autowired
HWMapper mapper;
@Test
void getAll() {
List<Character> all = mapper.getAll();
all.forEach(System.out::println);
}
@Test
void getAllCountry() {
mapper.getAllCountry().forEach(System.out::println);
}
@Test
void getBattle() {
mapper.getBattle().forEach(System.out::println);
}
}
2 MyBatis动态SQL练习
首先,将课前资料中的sample2.sql文件中的数据导入到数据库中的ssm_hw01db数据库中。
表格的字段及数据如图所示:
请基于上述数据库表和数据,在ssm_hw03项目中实现如下需求:
1、开发一个查询员工的方法:接收firstName, lastName和jobTitle三个参数,如果传入的参数不为null且不为空字符串,则使用该参数作为模糊查询的条件;如果传入的参数均为null,则默认查询全部员工信息。
2、开发一个查询员工的方法,接收字符串类型的startYear作为参数,格式为yyyy,如果传入的参数不为null且不为空字符串,则查询在startYear之后入职的员工,否则查询自2018年起入职的员工。
3、开发一个查询员工的方法,接收Integer类型的集合作为参数,查询员工的id值与集合中数据值相同的员工信息。
提示:
1、仅需要完成持久层的开发和测试即可,必须有测试用例。
2、持久层为EmployeeMapper接口,对应EmployeeMapper.xml文件。
实体类:
/**
* @document: 员工实体类
* @Author:SmallG
* @CreateTime:2023/9/5+21:33
*/
public class Employee {
private Integer id;
private String firstName;
private String lastName;
private Date dateOfBirth;
private Date hireDate;
private String jobTitle;
省略...
}
mapper接口:
@Mapper
public interface EmployeeMapper {
/**
* 接收firstName, lastName和jobTitle三个参数,
* 如果传入的参数不为null且不为空字符串,则使用该参数作为模糊查询的条件;
* 如果传入的参数均为null,则默认查询全部员工信息。
*
* @param firstName
* @param lastName
* @param jobTitle
* @return
*/
List<Employee> getEmployee1(@Param("firstName") String firstName,
@Param("lastName") String lastName,
@Param("jobTitle") String jobTitle);
/**
* 查询在指定年份及之后入职的员工
* 默认查询自2018年起入职的员工
*
* @return
*/
List<Employee> listEmployeeByYear(String startYear);
/**
* 查询ID与ids集合中数据值相同的员工信息
* 默认不返回任何信息
* 注意,必须添加@Param注解
*
* @return
*/
List<Employee> listEmployeeByIds(@Param("ids") List<Integer> ids);
}
mapper.xml配置文件:
<?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.example.ssm_hw03.mapper.EmployeeMapper">
<resultMap id="EmployeeMap" type="com.example.ssm_hw03.entity.Employee">
<id property="id" column="id"></id>
<result column="first_name" property="firstName"></result>
<result column="last_name" property="lastName"></result>
<result column="date_of_birth" property="dateOfBirth"></result>
<result column="hire_Date" property="hireDate"></result>
<result column="job_title" property="jobTitle"></result>
</resultMap>
<select id="getEmployee1" resultMap="EmployeeMap">
select *
from employee
<where>
<if test="firstName !=null and firstName != ''">
and firstName like concat('%',#{firstName},'%')
</if>
<if test="lastName !=null and lastName != ''">
and lastName like concat('%',#{lastName},'%')
</if>
<if test="jobTitle !=null and jobTitle != ''">
and jobTitle like concat('%',#{jobTitle},'%')
</if>
</where>
</select>
<select id="listEmployeeByYear" resultMap="EmployeeMap">
SELECT *
FROM employee
where
<choose>
<when test="startYear!=null and startYear!=''">
year(hire_date) >=#{startYear}
</when>
<otherwise>
year(hire_date) >=2018
</otherwise>
</choose>
</select>
<select id="listEmployeeByIds" resultMap="EmployeeMap">
SELECT * FROM employee where
<choose>
<when test="ids !=null and ids.size() !=0">
id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</when>
<otherwise>
1=2
</otherwise>
</choose>
</select>
</mapper>
测试类:
@SpringBootTest
class EmployeeMapperTest {
@Autowired
EmployeeMapper mapper;
@Test
void getEmployee1() {
mapper.getEmployee1(null,null,null).forEach(System.out::println);
}
@Test
void listEmployeeByYear() {
String startYear = "2016";
List<Employee> list = mapper.listEmployeeByYear(startYear);
list.forEach(System.out::println);
}
@Test
void listEmployeeByIds() {
List<Integer> ids = List.of(1,3,5);
List<Employee> list =mapper.listEmployeeByIds(ids);
list.forEach(System.out::println);
}
}