有关MyBatis的练习

目录

1. 配置文件实现CRUD

1.1 环境准备

1.2 查询所有数据

1.3 根据id查询详情

1.4 多条件查询

1.5 单条件动态查询

1.6 添加数据

1.7 修改

1.8 删除一行数据

1.9 批量删除

1.10 Mybatis参数传递

2. 注解实现CRUD


# 博学谷IT技术支持

目标:

  • 能够使用映射配置文件实现CRUD操作

  • 能够使用注解实现CRUD操作

1. 配置文件实现CRUD

在电商网站中,包含了品牌数据的 查询按条件查询添加删除批量删除修改 等功能,而这些功能其实就是对数据库表中的数据进行CRUD操作。接下来我们将演示使用Mybatis完成品牌数据的增删改查操作。

  • 查询

    • 查询所有数据

    • 查询详情

    • 条件查询

  • 添加

  • 修改

    • 修改全部字段

    • 修改动态字段

  • 删除

    • 删除一个

    • 批量删除

1.1 环境准备

  • 数据库表(tb_brand)及数据准备

    -- 删除tb_brand表
    drop table if exists tb_brand;
    -- 创建tb_brand表
    create table tb_brand
    (
        -- id 主键
        id           int primary key auto_increment,
        -- 品牌名称
        brand_name   varchar(20),
        -- 企业名称
        company_name varchar(20),
        -- 排序字段
        ordered      int,
        -- 描述信息
        description  varchar(100),
        -- 状态:0:禁用  1:启用
        status       int
    );
    -- 添加数据
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
           ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1);
  • 实体类 Brand

    com.itheima.pojo 包下创建 Brand 实体类。

    public class Brand {
        // id 主键
        private Integer id;
        // 品牌名称
        private String brandName;
        // 企业名称
        private String companyName;
        // 排序字段
        private Integer ordered;
        // 描述信息
        private String description;
        // 状态:0:禁用  1:启用
        private Integer status;
        
        //省略 setter and getter。自己写时要补全这部分代码
    }
  • 编写测试用例

    测试代码需要在 test/java 目录下创建包及测试用例。

  • 安装 MyBatisX 插件

    • MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

    • 主要功能

      • XML映射配置文件 和 接口方法 间相互跳转

      • 根据接口方法生成 statement

    • 安装方式

      点击 file ,选择 settings

      注意:安装完毕后需要重启IDEA

    • 插件效果

      红色头绳的表示映射配置文件,蓝色头绳的表示mapper接口。在mapper接口点击红色头绳的小鸟图标会自动跳转到对应的映射配置文件,在映射配置文件中点击蓝色头绳的小鸟图标会自动跳转到对应的mapper接口。也可以在mapper接口中定义方法,自动生成映射配置文件中的 statement ,如图所示

1.2 查询所有数据

1.2.1 编写接口方法

com.itheima.mapper 包写创建名为 BrandMapper 的接口。并在该接口中定义

List<Brand> selectAll()

方法。

  • 参数:无

    查询所有数据功能是不需要根据任何条件进行查询的,所以此方法不需要参数。

  • 结果:List<Brand>

    我们会将查询出来的每一条数据封装成一个 Brand 对象,而多条数据封装多个 Brand 对象,需要将这些对象封装到List集合中返回。

1.2.2 编写SQL语句

resources 下创建 com/itheima/mapper 目录结构,并在该目录下创建名为 BrandMapper.xml 的映射配置文件

  • 实体类中属性名 brandNamecompanyName ,与表中的字段名brand_namecompany_name不一致,所以使用resultMap解决上述问题

<?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.itheima.mapper.BrandMapper">
    <resultMap id="brandResultMap" type="brand">
    <!--
            id:完成主键字段的映射
                column:表的列名
                property:实体类的属性名
            result:完成一般字段的映射
                column:表的列名
                property:实体类的属性名
        -->
    <result column="brand_name" property="brandName"/>
    <result column="company_name" property="companyName"/>
</resultMap>
    <select id="selectAll" resultMap="brandResultMap">
    select *
    from tb_brand;
    </select>
</mapper>

1.2.3 编写测试方法

MybatisTest 类中编写测试查询所有的方法

@Test
public void testSelectAll() throws IOException {
    //1. 获取SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
​
    //2. 获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
​
    //3. 获取Mapper接口的代理对象
    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
​
    //4. 执行方法
    List<Brand> brands = brandMapper.selectAll();
    System.out.println(brands);
​
    //5. 释放资源
    sqlSession.close();
​
}

1.3 根据id查询详情

1.3.1 编写接口方法

Mapper接口

  • 参数:id

    查看详情就是查询某一行数据,所以需要根据id进行查询。而id以后是由页面传递过来。

  • 结果:Brand

    根据id查询出来的数据只要一条,而将一条数据封装成一个Brand对象即可

1.3.2 编写SQL语句

  • BrandMapper.xml 映射配置文件中编写 statement,使用 resultMap 而不是使用 resultType

<select id="selectById"  resultMap="brandResultMap">
    select *
    from tb_brand where id = #{id};
</select>

1.3.3 编写测试方法

  • test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法

     //4. 执行方法
        Brand brand = brandMapper.selectById(id);
        System.out.println(brand);

1.3.4 注意

1.4 多条件查询

1.4.1 编写接口方法

BrandMapper 接口中定义多条件查询的方法。

而该功能有三个参数,我们就需要考虑定义接口时,参数应该如何定义。Mybatis针对多参数有多种实现

  • 使用 @Param("参数名称") 标记每一个参数,在映射配置文件中就需要使用 #{参数名称} 进行占位

    List<Brand> selectByCondition(@Param("status") int status,
     @Param("companyName") String companyName,
    @Param("brandName") String brandName);
  • 将多个参数封装成一个 实体对象 ,将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容} 时,里面的内容必须和实体类属性名保持一致。

    List<Brand> selectByCondition(Brand brand);
  • 将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容} 时,里面的内容必须和map集合中键的名称一致。

    List<Brand> selectByCondition(Map map);

1.4.2 编写SQL语句

BrandMapper.xml 映射配置文件中编写 statement,使用 resultMap 而不是使用 resultType

<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    where status = #{status}
    and company_name like #{companyName}
    and brand_name like #{brandName}
</select>

1.4.3 编写测试方法

MybatisTest类中 定义测试方法

@Test
public void testSelectByCondition() throws IOException {
    //接收参数
    int status = 1;
    String companyName = "华为";
    String brandName = "华为";
​
    // 处理参数
    companyName = "%" + companyName + "%";
    brandName = "%" + brandName + "%";
   ........
 //4. 执行方法
    //方式一 :接口方法参数使用 @Param 方式调用的方法
    //List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
    //方式二 :接口方法参数是 实体类对象 方式调用的方法
     //封装对象
    /* Brand brand = new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);*/
    
    //List<Brand> brands = brandMapper.selectByCondition(brand);
    
    //方式三 :接口方法参数是 map集合对象 方式调用的方法
    Map map = new HashMap();
    map.put("status" , status);
    map.put("companyName", companyName);
    map.put("brandName" , brandName);
    List<Brand> brands = brandMapper.selectByCondition(map);
    System.out.println(brands);    

1.4.4 动态SQL

用户在输入查询条件时,不一定会输入所有信息,就需要把SQL语句改成动态SQL语句

  • Mybatis提供了各种标签使用

    • if

    • choose (when, otherwise)

    • trim (where, set)

    • foreach

  • 该例中需要使用if和where标签

  • 注意:需要给每个条件前都加上 and 关键字

//if 标签:条件判断
    // test 属性:逻辑表达式
//where 标签
//  * 作用:
//      *替换where关键字
//      *会动态的去掉第一个条件前的 and 
//      *如果所有的参数没有值则不加where关键字
<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    <where>
        <if test="status != null">
            and status = #{status}
        </if>
        <if test="companyName != null and companyName != '' ">
            and company_name like #{companyName}
        </if>
        <if test="brandName != null and brandName != '' ">
            and brand_name like #{brandName}
        </if>
    </where>
</select>

1.5 单条件动态查询

1.5.1 编写接口方法

List<Brand> selectByConditionSingle(Brand brand);

1.5.2 编写SQL语句

<select id="selectByConditionSingle" resultMap="brandResultMap">
    select *
    from tb_brand
    <where>
        <choose><!--相当于switch-->
            <when test="status != null"><!--相当于case-->
                status = #{status}
            </when>
            <when test="companyName != null and companyName != '' "><!--相当于case-->
                company_name like #{companyName}
            </when>
            <when test="brandName != null and brandName != ''"><!--相当于case-->
                brand_name like #{brandName}
            </when>
        </choose>
    </where>
</select>

1.5.3 编写测试方法

@Test
public void testSelectByConditionSingle() throws IOException {
    //接收参数
    int status = 1;
    String companyName = "华为";
    String brandName = "华为";
​
    // 处理参数
    companyName = "%" + companyName + "%";
    brandName = "%" + brandName + "%";
    
     //封装对象
    Brand brand = new Brand();
    //brand.setStatus(status);
    brand.setCompanyName(companyName);
    //brand.setBrandName(brandName);
    .........
    //4. 执行方法
    List<Brand> brands = brandMapper.selectByConditionSingle(brand);
    System.out.println(brands);

1.6 添加数据

1.6.1 编写接口方法

void add(Brand brand);

1.6.2 编写SQL语句

<insert id="add">
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
</insert>

1.6.3 编写测试方法

@Test
public void testAdd() throws IOException {
    //接收参数
    int status = 1;
    String companyName = "波导手机";
    String brandName = "波导";
    String description = "手机中的战斗机";
    int ordered = 100;
​
    //封装对象
    Brand brand = new Brand();
    brand.setStatus(status);
    brand.setCompanyName(companyName);
    brand.setBrandName(brandName);
    brand.setDescription(description);
    brand.setOrdered(ordered);
    
    //1. 获取SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //2. 获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //SqlSession sqlSession = sqlSessionFactory.openSession(true); //设置自动提交事务,这种情况不需要手动提交事务了
    //3. 获取Mapper接口的代理对象
    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    //4. 执行方法
    brandMapper.add(brand);
    //提交事务
    sqlSession.commit();
    //5. 释放资源
    sqlSession.close();

1.6.4 添加—主键返回

  • 在数据添加成功后,有时候需要获取插入数据库数据的主键(主键是自增长),这时候SQL语句需要改写

在 insert 标签上添加如下属性:

  • useGeneratedKeys:是够获取自动增长的主键值。true表示获取

  • keyProperty :指定将获取到的主键值封装到哪个属性里

<insert id="add" useGeneratedKeys="true" keyProperty="id">
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
</insert>

1.7 修改

1.7.1 编写接口方法

void update(Brand brand);

1.7.2 编写SQL语句

set标签

<update id="update">
    update tb_brand
    <set>
        <if test="brandName != null and brandName != ''">
            brand_name = #{brandName},
        </if>
        <if test="companyName != null and companyName != ''">
            company_name = #{companyName},
        </if>
        <if test="ordered != null">
            ordered = #{ordered},
        </if>
        <if test="description != null and description != ''">
            description = #{description},
        </if>
        <if test="status != null">
            status = #{status}
        </if>
    </set>
    where id = #{id};
</update>

set 标签可以用于动态包含需要更新的列,忽略其它不更新的列。

1.7.3 编写测试方法

@Test
public void testUpdate() throws IOException {
    //接收参数
    int status = 0;
    String companyName = "波导手机";
    String brandName = "波导";
    String description = "波导手机,手机中的战斗机";
    int ordered = 200;
    int id = 6;
​
    //封装对象
    Brand brand = new Brand();
    brand.setStatus(status);
    //        brand.setCompanyName(companyName);
    //        brand.setBrandName(brandName);
    //        brand.setDescription(description);
    //        brand.setOrdered(ordered);
    brand.setId(id);
    ..........
    //4. 执行方法
    int count = brandMapper.update(brand);
    System.out.println(count);
     //提交事务
    sqlSession.commit();

1.8 删除一行数据

1.8.1 编写接口方法

void deleteById(int id);

1.8.2 编写SQL语句

<delete id="deleteById">
    delete from tb_brand where id = #{id};
</delete>

1.8.3 编写测试方法

 @Test
public void testDeleteById() throws IOException {
    //接收参数
    int id = 6;
    .....
     //4. 执行方法
    brandMapper.deleteById(id);
    //提交事务
    sqlSession.commit();

1.9 批量删除

1.9.1 编写接口方法

  • 参数是一个数组,数组中存储的是多条数据的id

void deleteByIds(@Param("ids")int[] ids);

编写SQL时需要遍历数组来拼接SQL语句。Mybatis 提供了 foreach 标签供我们使用

foreach 标签

用来迭代任何可迭代的对象(如数组,集合)。

  • collection 属性:

    • mybatis会将数组参数,封装为一个Map集合。

      • 默认:array = 数组

      • 使用@Param注解改变map集合的默认key的名称

  • item 属性:本次迭代获取到的元素。

  • separator 属性:集合项迭代之间的分隔符。foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。

  • open 属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一次

  • close 属性:该属性值是在拼接SQL语句拼接后拼接的语句,只会拼接一次

<delete id="deleteByIds">
    delete from tb_brand where id
    in
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
    ;
</delete>

假如数组中的id数据是{1,2,3},那么拼接后的sql语句就是:

delete from tb_brand where id in (1,2,3);

1.9.3 编写测试方法

@Test
public void testDeleteByIds() throws IOException {
    //接收参数
    int[] ids = {5,7,8};
    ........
      //4. 执行方法
    brandMapper.deleteByIds(ids);
    //提交事务
    sqlSession.commit();

1.10 Mybatis参数传递

Mybatis 接口方法中可以接收各种各样的参数,如下:

  • 多个参数,需要使用 @Param 注解

  • 单个参数:单个参数又可以是如下类型

    • POJO 类型

      直接使用。要求 属性名参数占位符名称 一致

    • Map 集合类型

      直接使用。要求 map集合的键名参数占位符名称 一致

    • Collection 集合类型

      Mybatis 会将集合封装到 map 集合中,如下:

      map.put("arg0",collection集合);

      map.put("collection",collection集合;

      可以使用 @Param 注解替换map集合中默认的 arg 键名。

    • List 集合类型

      Mybatis 会将集合封装到 map 集合中,如下:

      map.put("arg0",list集合);

      map.put("collection",list集合);

      map.put("list",list集合);

      可以使用 @Param 注解替换map集合中默认的 arg 键名。

    • Array 类型

      Mybatis 会将集合封装到 map 集合中,如下:

      map.put("arg0",数组);

      map.put("array",数组);

      可以使用 @Param 注解替换map集合中默认的 arg 键名。

    • 其他类型

      比如int类型,参数占位符名称 叫什么都可以。

2. 注解实现CRUD

注解完成简单功能,配置文件完成复杂功能。

  • 注解使用案例

    @Select(value = "select * from tb_user where id = #{id}")
    public User select(int id);
    • 注意:

      • 注解是用来替换映射配置文件方式配置的,所以使用了注解,就不需要再映射配置文件中书写对应的 statement

Mybatis 针对 CURD 操作都提供了对应的注解如下:

  • 查询 :@Select

  • 添加 :@Insert

  • 修改 :@Update

  • 删除 :@Delete

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值