【JavaWeb学习记录09】MyBatis(1)

四、MyBatis练习

4.1 配置文件实现 CRUD

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Id1Fc4nG-1663774584852)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829072356478.png)]

4.1.1 环境准备
1. 数据库表 tb_brand

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Esx8jLcD-1663774584853)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829073024601.png)]

2. 实体类 Brand
package pojo;

/**
 * @Author 晨默
 * @Date 2022/8/28 20:06
 */
public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用 1:启用
    private Integer status;

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public Integer getOrdered() {
        return ordered;
    }

    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }
}
4.1.2 查询所有数据
1. 编写接口方法 BrandMapper
public interface BrandMapper {
    /*
    * 查询所有
    * */
    List<Brand> selectAll();
}
2. SQL 语句

创建名为 BrandMapper.xml 的映射配置文件

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="mapper.BrandMapper">
    <!-- 查询所有数据 -->
    <select id="selectAll" resultType="brand">
        select *
        from tb_brand;
    </select>
</mapper>
3. 测试方法

MybatisTest 类中编写

@Test
public void testSelectById() 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();
}

测试结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OcfDWAzd-1663774584853)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829074405578.png)]

==出现问题:==有的数据没有封装成功

解决方式:

  • 给字段起别名
  • 使用 resultMap 定义字段和属性的映射关系。推荐使用
4. 使用 resultMap 解决问题

映射配置文件中使用 resultMap 定义字段和属性的映射关系

注意:只需定义字段名和属性名不一样的映射,而一样的则不需要

    <resultMap id="brandResultMap" type="brand">
        <!--
             id:完成主键字段的映射 
                 column:表的列名 
                 property:实体类的属性名 
             result:完成一般字段的映射 
                 column:表的列名 
                 property:实体类的属性名
         -->
        <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>

SQL语句则变为如下:

<!-- 查询所有数据 -->
    <select id="selectAll" resultMap="brandResultMap">
        select *
        from tb_brand;
    </select>
4.1.3 查询详情

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dRP8733r-1663774584854)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829081243811.png)]

查询某一行的数据,需要根据id进行查询

1. 接口方法——BrandMapper接口
/*                        
* 查看详情:根据id查询             
* */                      
Brand selectById(int id); 
2. SQL语句
<!-- 查询详情 -->                                       
<select id="selectById" resultMap="brandResultMap"> 
    select *                                        
    from tb_brand where id = #{id};                 
</select>                                           
3. 测试方法
/*
* 查看详情:根据Id查询
* */
@Test
public void testSelectById() throws IOException {
    // 接受参数,该id以后需要传递过来
    int id = 1;
    // 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. 执行方法
    Brand brand = brandMapper.selectById(id);
    System.out.println(brand);

    // 5. 释放资源
    sqlSession.close();
}

测试结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uGbMhLH2-1663774584854)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829081919536.png)]

4. 参数占位符
  • #{} : 执行SQL时,会将 #{} 占位符替换为 ?。之后自动设置参数值。底层使用 PreparedStatement一般使用#{}

  • ${} : 拼接SQL时,底层使用 Statement,会存在SQL注入问题

5. paramterType 使用

对于有参数的mapper接口方法,映射配置文件中应该配置 ParamterType 来制定参数类型。不过改属性都可以省略。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VXo9aGRL-1663774584854)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829082701308.png)]

6. SQL特殊字段处理

<>等字符在xml文件中有特殊含义,需要进行转义

  • 转义字符:&lt; 代表 < 字符
  • <![CDATA[内容]]>
4.1.4 多条件查询

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PmNFEnRU-1663774584855)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829083253457.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-snLT3E1W-1663774584855)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829083313578.png)]

1. 接口方法
  • 使用 @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);
2. SQL语句
<!-- 多条件查询 -->                                            
<select id="selectByCondition" resultMap="brandResultMap">
    select *                                              
    from tb_brand                                         
    where status = #{status}                              
    and company_name like #{companyName}                  
    and brand_name like #{brandName};                     
</select>                                                 
3. 测试方法
   /*
    * 多条件查询
    * */
    @Test
    public void testSelectByCondition() throws IOException {
        // 接收参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";

        // 处理参数
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";

        //
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        // 执行方法
        // 1. 接口方法参数使用 @Param 方式调用
        /*List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);*/
        // 2. 接口方法参数是 实体类对象 方式调用的方法
        /*Brand brand = new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(companyName);
        List<Brand> brands = brandMapper.selectByCondition(brand);*/
        // 3. 接口方法参数是 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);

        //
        sqlSession.close();
    }                                         

测试结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZDiYBNb2-1663774584856)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829090104534.png)]

4. 动态SQL

当用户在输入条件时没有填写全部,则此时的SQL也会有所不同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PKKwE0tI-1663774584857)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829130157249.png)]

Mybatis对动态SQL有以下标签可用

  • if
  • choose(when, otherwise)
  • trim(where, set)
  • foreach
  • if 标签 : 条件判断

    • test 属性 : 逻辑表达式
    <!-- 多条件查询 -->           
    <select id="selectByCondition" resultMap="brandResultMap">    
        select *                                                  
        from tb_brand                                             
        where                                                     
            <if test="status != null">                            
                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>                                                   
    </select>                                                     
    

    SQL语句会根据传递的参数值进行动态拼接。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GboUTkfh-1663774584858)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829131942496.png)]

  • where 标签

    • 作用:
      • 替换 where 关键字
      • 回动态的去掉第一个条件前的 and
      • 若所有参数没有则不加 where 关键字
    <!-- 多条件查询 -->                                      
    <select id="selectByCondition" resultMap="brandResultMap">    
        select *                                                  
        from tb_brand                                             
        <where>                                                   
            <if test="status != null">                            
                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>                                                     
    
4.1.5 单个条件(动态SQL)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p4jRtJ5P-1663774584858)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829132625284.png)]

使用 **choose(when, otherwise)**标签实现。choose 标签类似于 Java 中的 switch 语句

1. 接口方法
/**                                              
 * 单条件动态查询                                       
 * @param brand                                  
 * @return List<Brand>                           
 * */                                            
List<Brand> selectByConditionSingle(Brand brand);
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 != '' ">
                and company_name like #{companyName}               
            </when>                                               
            <when test="brandName != null and brandName != '' ">  
                and brand_name like #{brandName}                   
            </when>                                              
        </choose>                                                 
    </where>                                                      
</select>                                                         
3. 测试方法
/*                                                                                          
 * 单条件查询                                                                                    
 * */                                                                                       
@Test                                                                                       
public void testSelectByConditionSingle() throws IOException {                              
    // 接收参数            
    int status = 1;
    String companyName = "华为";  
    String brandName = "华为";                                                 
    // 处理参数            
    companyName = "%" + companyName + "%";
    brandName = "%" + brandName + "%";                                               
    //            
    String resource = "mybatis-config.xml";      
    InputStream inputStream = Resources.getResourceAsStream(resource);                      
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //             
    SqlSession sqlSession = sqlSessionFactory.openSession(); 
    //       
    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);                                                             
    // 执行方法           
    Brand brand = new Brand();     
    // brand.setStatus(status);           
    brand.setCompanyName(companyName);     
    // brand.setBrandName(companyName);                  
    List<Brand> brands = brandMapper.selectByConditionSingle(brand);                       
    System.out.println(brands);                                  
    // 
    sqlSession.close();                                 
}   

测试结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g9oXVLMW-1663774584860)(C:\Users\18517\AppData\Roaming\Typora\typora-user-images\image-20220829151356029.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mathison晨默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值