【博学谷学习记录】超强总结,用心分享|Java使用Mybatis进行增删改查

115 阅读6分钟

简介

什么是MyBatis?

  • MyBatis是一款优秀的持久层框架,用于简化JDBC开发
  • 持久层:
    • 负责将数据到保存到数据库的那一层代码
    • JavaEE三层架构:表现层、业务层、持久层
  • 框架
    • 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
    • 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展

MyBatis快速入门

mybatis.org/mybatis-3/z…

  1. 创建user表,添加数据(Mysql)
  2. 创建模块,导入坐标(Maven依赖)
  3. 编写MyBatis核心配置文件(服务器连接信息,SQL映射文件)
  4. 编写SQL映射文件(SQL语句)
  5. 编码
    1. 定义POJO类
    2. 加载核心配置文件
    3. 获取sqlSession对象,执行SQL语句
    4. 释放资源

Mapper代理开发

使用Mapper代理方式步骤:

  1. 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同意目录下
  2. 设置SQL映射文件的namespace属性为Mapper接口全限定名
  3. 在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
  4. 编码
    1. 通过sqlSession的getMapper方法获取Mapper接口的代理对象
    2. 调用对应方法完成sql的执行

细节:如果Mapper接口名称和sql映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载

<mappers>
        <!--包扫描-->
        <package name="com.itheima.Mapper"/>
</mappers>

Mybatis核心配置文件

配置标签的顺序顺序必须按照这个顺序来配置

<environments default="development">

可以配置多个environment通过default来切换

类型别名:包搜索方式,减少全限定类名书写,可以直接写类名且不区分大小写

    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>

Mybatis实现增删改查

查询

查询-查询所有数据

  1. 编写接口方法:Mapper接口
  2. 参数:无
  3. 结果:List
  4. 编写SQL语句:sql映射文件
    select * from tb_brand
  5. 执行方法,测试

Mybatis无法自动封装数据

原因:数据库表的字段名称和实体类的属性名称不一样,则不能自动封装数据

解决办法:

1.起别名
company_name as companyName

2.sql片段

<sql id="brandcol">
  id,brand_name as brandName,company_name,ordered
</sql>
...
select <include refid="brandcol"></include> from tb_brand

3.resultMap

3.1 定义标签

3.2 在select标签中使用resultMap替换resultType

<resultMap id="brandResultMap" type="brand">
        
<!--        id :完成主键字段的映射
            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>

查询-查询详情

  1. 编写接口方法:Mapper接口
    • 参数:id
    • 结果:Brand
  2. 编写SQL语句:SQL映射文件
    select * from tb_brand where id = #{id}
  3. 执行方法,测试

一个参数-参数占位符

  1. 参数占位符
    1. #{}:执行SQL时,会将#{}占位符替换为?,将来自动设置参数值
    2. ${}:拼SQL,会存在SQL注入问题
    3. 使用时机:
      • 传递参数,都使用#{}
      • 如果要对表名、列名进行动态设置,只能使用${}进行sql拼接
  2. parameterType:
    • 用于设置参数类型
  3. SQL语句中特殊字符处理:
    • 转义字符 例如:&lt;
    • CDATA区

查询-多条件查询

  1. 编写接口方法:Mapper接口
    1. 参数:所有查询条件
    2. 结果:List<brand>
List<Brand> selectByCondition(@Param("status") int status,@Param("brandName") String brandName,@Param("companyName") String companyName);

List<Brand> selectByCondition(Brand brand);

List<Brand> selectByCondition(Map map);
  1. 编写SQL语句:SQL映射文件
<select id="selectByCondition" resultMap="brandResultMap">
    select * from tb_brand 
        where 
            status = #{status} 
            and brand_name like #{brandName} 
            and company_name like #{companyName}
</select>
  1. 执行方法,测试

SQL语句设置多个参数

  1. 散装参数:需要使用@param("SQL中的参数占位符名称" 参数类型 参数名称)
  2. 实体类封装参数:只需要保证SQL中的参数名和实体类属性名对应上,即可设置成功
  3. Map集合:只需要保证SQL中参数名和map集合到的键的名称对应上,即可设置成功

查询-多条件-动态条件查询

SQL会随着用户的输入或外部条件的变化而变化,我们称为动态SQL

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

动态SQL

if:用于判断参数是否有值,使用test属性进行条件判断

存在的问题:第一个条件不需要逻辑运算符

解决方案:

  1. 使用恒等式让所有条件格式都一样
  2. 标签替换where关键字

查询-单条件-动态查询

从多个条件中选择一个

choose(when, otherwise):选择,类似于Java中的switch语句

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

添加

添加步骤

  1. 编写接口方法:Mapper接口void add(Brand brand)
    1. 参数:除了id之外的所有数据
    2. 结果:void
  2. 编写SQL语句:SQL映射文件
<insert id="add">
        insert into tb_brand(brand_name, company_name, ordered, description, status)
        VALUES (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status})
</insert>
  1. 执行方法,测试

Mybatis事务

  • openSession():默认开启事务,进行增删改操作后需要使用sqlSession.commit();手动提交事务
  • openSession(true):可以设置为自动提交事务(关闭事务)

主键返回

在数据添加成功后,需要获取插入数据库数据的主键的值

比如:添加订单和订单项

  1. 添加订单
  2. 添加订单项,订单项中需要设置所属订单的id 返回添加数据的主键 <insert useGeneratedKays = "true" keyProperty = "id">

修改

修改步骤

  1. 编写接口方法:Mapper接口
    1. 参数:所有数据
    2. 结果:void 或 int
    int update(Brand brand)
  2. 编写SQL语句:SQL映射文件
<update id="update">
    update tb_brand
    set brand_name = #{brandName},
        company_name = #{companyName},
        ordered = #{ordered},
        description = #{description},
        status = #{status}
    where id = #{id};
</update>
  1. 执行方法,测试

修改-修改动态字段

使用set标签和if标签

<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>

删除

删除一个

  1. 编写接口方法:Mapper接口
    1. 参数:id
    2. 结果:void void deleteById(int id)
  2. 编写SQL语句:SQL映射文件
 <delete id="deleteById">
        delete
        from tb_brand
        where id = #{id};
 </delete>
  1. 执行方法,测试

批量删除

  1. 编写接口方法:Mapper接口
    1. 参数:id数组
    2. 结果 void
    void deleteById(@param("ids")int[] ids);
  2. 编写SQL语句:SQL映射文件
<delete id="deleteByIds">
        delete
        from tb_brand
        where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
        ;
</delete>
  1. 执行方法,测试

Mybatis完成操作需要几步?

三步:

  1. 编写接口方法
  2. 编写SQL
  3. 执行方法

参数传递

MyBatis提供了 ParamNameResolver 类来进行参数封装

单个参数

  1. POJO类型:直接使用,实体类属性名和参数占位符名称一致
  2. Map集合:直接使用,键名和参数占位符名称一致
  3. Collection:封装为Map集合
map.put("collection",collection集合)
map.put("arg0",collection集合)
  1. List:封装为Map集合
map.put("collection",List集合)
map.put("list",List集合)
map.put("arg0",List集合)
  1. Array:封装为Map集合
map.put("array",数组)
map.put("arg0",数组)
  1. 其他类型:直接使用

多个参数:封装为Map集合

map.put("arg0",参数值1)
map.put("param1",参数值1)
map.put("arg1",参数值2)
map.put("param2",参数值2)

建议:将来都使用@Param注解来修改Map集合中默认的键名,并使用修改后的名称来获取值,这样可读性更高!

修改的是arg0

注解完成增删改查

使用注解开发会比配置文件开发更加方便

@Select("select * from tb_brand;")
List<Brand> selectAll();

查询:@Select

添加:@Insert

修改:@Update

删除:@Delete

提示:

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