MyBatis

98 阅读4分钟

MyBatis

1 MyBatis

1.1 MyBatis作用

​ 持久层框架可以操作数据库,简化JDBC的开发

1.2 MyBatis入门步骤

​ 1) 准备数据

​ 2) 添加依赖,配置数据库连接信息

​ 3) 编写MyBatis相关代码

​ 4) 测试

image-20230910210113062转存失败,建议直接上传图片文件

image-20230910210155591转存失败,建议直接上传图片文件

1.3 JDBC
1.3.1 什么是JDBC

​ JDBC ( 全称为Java DataBase Connectivity) 是Java数据库连接技术, 是sun公司提供的一套链接关系型数据库的规范, 接口(API)

1.3.2 JDBC的作用

​ 通过JDBC可以让Java程序操作数据库

1.3.3 什么是数据库的驱动

​ 数据库厂商实现了JDBC接口的类的集合可以真正操作数据库

2 简单实用 MyBatis

2.1 数据库连接池
2.1.1 连接池的概念

​ 是一个容器,管理数据库的链接

2.1.2 连接池的优点

​ 连接池中的链接可以反复使用,降低资源的消耗

2.1.3 连接池接口

​ DataSource

2.2 lombok
2.2.1 lombok是什么

​ 是一个工具, 简化实体类的编写

2.2.2 常用注解
@Data: 生成get/set/equals/hashCode/toString
@NoArgsConstructor: 生成无参构造器
@AllArgsConstructor: 生成满参构造器

3 MyBatis 基础操作 (增删改查CRUD)

3.1 删除
3.1.1 语句
@Delete("delete from emp where id = #{id};")
int deleteById(int id);
3.1.2 #{参数名}

​ /\ 使用?占位

​ /\ 把参数赋值给?

​ /\ 没有SQL注入,效率高一点

3.1.3 ${参数名}

​ /\ 直接拼接字符串

​ /\ 可能有SQL注入,效率低一点

3.2 新增
3.2.1 代码实现

值传入为数据库中对应的字段 (sql语言)

占位符中的名称 均为来自于实体类中定义的属性字段 (java语言)

    @Insert("insert into day4_mybatis2.emp(username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time) values (null, #{username}, #{password}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime});")
    void add(Emp emp);
3.2.2 方法参数是自定义类

​ #{成员变量名}:

​ 1) 使用?占位

​ 2) 取出成员变量的值赋值给?

3.3 修改
3.3.1 代码实现
@Update("update emp set username = #{username}, password = #{password}, name = #{name}, gender = #{gender}, image = #{image}, job = #{job}, entrydate = #{entrydate}, dept_id = #{deptId}, update_time = #{updateTime} where id=#{id};")

3.4 查询
3.4.1 代码实现
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId, create_time createTime, update_time updateTime from emp where id = #{id};")
    Emp findById(int id);
3.4.2 表中的字段和类中的成员变量名不同时

​ 表中的字段和类中的成员变量名不同, 到时对象中没有数据,我们需要指定表中的字段对应类中哪个成员变量:

​ 1) 查询的SQL中取别名

​ 2) @Results 手动映射结果

​ 3) 开启驼峰命名自动映射 (重要)

3.5 条件查询模糊

错误方法:

		 name like '%${name}%' 

正确方法:

		 name like concat('%', #{name}, '%')

4 XML配置SQL语句

​ 1) xml的文件名要和接口名一样, 并且编译后要在同一个包中

​ 2) namespaces对应包名的接口名

​ 3) id对应方法名, resultType返回值类型配置

image-20230910180111883转存失败,建议直接上传图片文件

Map文件中:

@Mapper
public interface UserMapper {
    // 增 create
    void createUser(Emp emp);

    //  删 delete
    void deleteUser(Integer id);
    // 多选删除 multiDelete
    void multiDelete(List idLists);

    //  改 update
    void updateUser(Emp emp);

    // 查 retrieve
    List retrieveUser();
    //Retrieve by id
    Emp retrieveUserByID(Integer id);
    //模糊搜索 fuzzyRetrieve
    List fuzzyRetrieveByUsername(String name);
    //Multiple search, 找任何类型都可以
    List multipleSearch(Emp emp);
}
<?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" >

//namespace指向map文件
<mapper namespace="com.example.mapper.UserMapper">
//添加用户
    //id指xml文件映射的方法
    <insert id="createUser" parameterType="com.example.pojo.Emp">
        insert into day4_mybatis2.emp(username, password, name, gender, image, job, entrydate, dept_id, create_time,
                                      update_time)
        VALUES (#{username}, #{password}, #{name}, #{gender}, #{image}, #{job}, #{entryDate}, #{deptId}, #{createTime},
                #{updateTime})
    </insert>
</mapper>
4.1 怎么定义传入参数 和 返回值的类型

需要在insert标签里id 后填写parameterType或者resultType字段, 这两个字段为可选项, 如果是Utils存在的类则只需要填类名, 比如List, 如果没有则需要填全类名

4.2 如何进行主键的映射

需要在insert标签下添加keyProperty和useGeneratedKeys字段, 其功能类似于myBatis注解里的@Result. 在数据处理(写入)后, 将会把主键的值映射给实体类中的keyProperty中, 这样方便了多表链接中键的处理

    <insert id="createUser" parameterType="com.example.pojo.Emp" keyProperty="id" useGeneratedKeys="true">
4.3 没有删除原mybatis注解

出现如下报错:

Caused by: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.itheima.mapper.EmpSearchByIDMapper.searchByIDMapper. please check com/itheima/mapper/EmpSearchByIDMapper.xml and com/itheima/mapper/EmpSearchByIDMapper.java (best guess)

5 MyBatis动态SQL

5.1 修改
5.1.1 if 语句判空处理

​ 做判断,满足条件,拼接SQL

<!--    复用sql语句  -->
    <sql id="updateReuse">
        <if test="id!=null">
            id = #{id},
        </if>

        <if test="username!=null">
            username = #{username},
        </if>
        <if test="password!=null">
            password = #{password},
        </if>
    </sql>
5.1.2 用set标签消除语法错误

​ 如果只用if语句进行修改前的判空处理, 会出现语法syntax错误, 错误位置通常出现在句头或者句尾的位置. 原因是因为语句前后的 ' , ' 没有被删除, 可以通过修改sql语句set为标签去除多余的,

<update id="updateUser" parameterType="com.example.pojo.Emp">
    update day4_mybatis2.emp
    
    <set>
    //这里用重复引用进行简写, 原处这里为用if语句判空
    <include refid="updateReuse"></include>
    </set>

    where id = #{id}

</update>
5.2 批量删除

​ 可以用foreach遍历数组或集合

​ // 指定要遍历的数组或集合 collction ​ // 定义变量,保存遍历到的元素 item ​ // 拼接遍历开始前的内容 open ​ // 拼接遍历后的内容 close ​ // 分隔符, 拼接每个元素之间的内容 separator

代码实现:

 <delete id="multiDelete" parameterType="List">
     delete from day4_mybatis2.emp
        where id in
        <foreach collection="idLists" item="id" separator="," open="(" close=")">
            #{id}
         </foreach>
</delete>
5.3 抽取重复的SQL
//id可随意取id的名字, 但是引入时需保持一致
<sql id="updateReuse">
//中间放重复的SQL语句
        <if test="id!=null">
            id = #{id},
        </if>
    </sql>
5.4 引入抽取的SQL
//引入sql语句
<include refid="updateReuse"></include>