Mybatis持久层框架

一、Mybatis的概述

MyBatis 是一个开源、轻量级的数据持久化框架,是 JDBC 和 Hibernate 的替代方案。MyBatis 内部封装了 JDBC,简化了加载驱动、创建连接、创建 statement 等繁杂的过程,开发者只需要关注 SQL 语句本身。

Mybatis中文网网址:https://mybatis.net.cn/index.html

在这里插入图片描述



  • Mybatis的准备步骤
  1. 在IDEA中下载Mybatis插件


    在这里插入图片描述
    在这里插入图片描述



  1. 在pom文件中导入Mybatis的依赖,版本可自选
<!--Mybatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>



  1. 配置XML映射文件【选做】
  • XML映射文件的名称和Mapper接口名称一致,并且将XML文件中的Mapper接口放在相同包下,即一定要同包同名
  • XML映射文件中的<mapper></mapper>标签的namespace属性为Mapper接口全限定名一致,即Mapper接口所在的包名.接口名
  • XML映射文件中SQL语句的属性值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="接口类所在的全限定类名">
    
</mapper>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述



二、Mybatis的增删改查

假设现在有一张学生表

在这里插入图片描述


2.1 添加数据

  • 添加数据我们用@Insert("SQL语句")注解
public interface StudentMapper {
    // 添加数据
    @Insert("insert into student values (null,'翔太',18,'潮汕')")
    public void addStudent();
}

有没有发现,我们在注解里写的SQL语句都是写死的,所以说当我们每一次要添加一条数据的时候就要修改这里的SQL语句,这在开发中是非常麻烦的,所以Mybatis提供了占位符的写法优化SQL语句

  • 当我们从前端那边接收到请求,请求中携带过来的数据往往都会很多,就比如我们添加学生这个需求来说,从前端传递过来的参数有学生姓名、年龄、家庭住址等等一些信息,我们往往会用一个实体类来封装起来,可以让我们的SQL语句更加的灵活

这里我们用#{属性}占位符的方式表示stu对象中的各个属性值,值得注意的是,我们#{属性}里面的属性值一定要和stu对象中的属性名一样,否则拿不到对象中的值,从而会导致SQL语句出错

@Mapper
public interface StudentMapper {
    // 添加数据
    @Insert("insert into student values (#{id},#{name},#{age},#{address})")
    public void addStudent(Student stu);
}

  • 补充【重点】:一般我们在表中设置主键id都是自动增长的,所以我们添加数据的时候,封装的实体类中id不会被前端携带过来的数据赋值,所以添加的id是个null值,由数据库自动生成id,但有时候我们也要在服务层用到这个新生成的id,但实体类中id依然为null,这时候我们就要使用一个注解让数据库把生成的id值赋值给实体类中的id属性
  • @Options(useGeneratedKeys = true,keyProperty = "id")
  • useGeneratedKeys = true为固定格式
  • keyProperty = "id" 的意思是把新生成的主键赋值给对象中的id属性

优化过后的代码如下

@Mapper
public interface StudentMapper {
    // 添加数据
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into student values (#{id},#{name},#{age},#{address})")
    public void addStudent(Student stu);
}

2.2 删除数据

  • 删除数据我们用的是@Delete("SQL语句")注解
@Mapper
public interface StudentMapper {
    // 删除数据
    @Delete("delete from student where id = #{id}")
    void deleteById(Integer id);
}


2.3 修改数据

  • 修改数据我们使用@Update("SQL语句")注解
@Mapper
public interface StudentMapper {
    // 修改数据
   @Update("update student set name = #{name},age = #{age},address = #{address} where id = #{id}")
   void updateById(Student student);
}

2.4 查询数据

现在有一张teacher表为演示下面操作


在这里插入图片描述

  • 现在我们通过id查询老师的信息,并用一个实体类封装数据
@Mapper
public interface StudentMapper {
    // 查询数据
    @Select("select * from teacher where id = #{id}")
    Teacher findById(Integer id);
}

在这里插入图片描述

在查询信息的时候,如果我们使用一个实体类来接收查询到的数据,在这个例子中就是用Teacher实体类来接收,那么Mybatis框架就会按照查询到的字段名与实体类的属性名匹配,如果名字一样就把对应的数据赋值给这个属性,否则就不赋值

那么在这个例子中,我们数据库中有一个字段old_address和对象中的属性oldAddress不一致,就导致查询到的数据不能被赋值给对象,这是因为在数据库的命名规范中,一个字段名遇到第二个单词就用下划线_隔开,与Java中的小驼峰命名法有一些差异,以下提供三种解决方法

  • 手动起别名
@Mapper
public interface StudentMapper {
    // 查询数据
    @Select("select id, name, age, old_address as oldAddress  from teacher where id = #{id}")
    Teacher findById(Integer id);
}
  • 手动映射 @Results(@Result(column = "数据库字段名", property = "对象属性名")...)
@Mapper
public interface StudentMapper {
    // 查询数据
    @Results(
            @Result(column = "old_address", property = "oldAddress")
    )
    @Select("select * from teacher where id = #{id}")
    Teacher findById(Integer id);
}
  • application.properties文件中配置
# 数据库下划线命名自动转换成小驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true



三、Mybatis动态SQL

  • 这里为了方便我们看见XML动态映射SQL语句,我们需要在application文件中配置依赖
# Properties文件格式
# mybatis日志依赖
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# yml文件格式
mybatis.configuration:
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

一般来说,如果是普通的SQL语句,类似通过id查询信息,通过id删除某个成员这一类简单的语句,我们直接在Mapper层接口的方法上定义增删改查的注解处理就好了,但如果涉及到多个不确定条件的SQL语句,就比如通过姓名、地址、年龄这几个条件中存在的条件查询某张表里的信息,我们不能确定前端用户给我们传递了几个条件,这样就可能发生前端传递过来的某个条件为null,这和我们的需求不匹配,所以这时候就要用到Mybatis框架提供XML映射SQL语句动态的来处理数据

  • <if test="判断条件">SQL语句</if> 如果判断条件为假这个SQL语句就不会存在,反之则存在
  • <where>SQL判断条件</where> 通常和if标签一起使用,作用是去掉因为if标签消除SQL语句后多余的 andor,并且当标签内没有SQL语句时,这个标签也会自动消除,不影响剩下的SQL语句执行
 // Mapper接口方法
 // 通过多个条件查询数据
    List<Student> findByAll(Student student);
// 测试类代码
@Test
    void testFindByAll(){
        Student student = new Student(1, null, 19, "广州");
        List<Student> list = studentMapper.findByAll(student);
        for (Student s : list) {
            System.out.println(s);
        }
    }
<?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.mybatis.Mapper.StudentMapper">
    <select id="findByAll" resultType="com.itheima.mybatis.pojo.Student">
        select * from student
        <where>
            <if test="name != null">
                name = #{name} and
            </if>
            <if test="age != null">
                age = #{age} and
            </if>
            <if test="address != null">
                address = #{address}
            </if>
        </where>
    </select>
</mapper>

在这里插入图片描述


  • <set></set>标签主要用于update修改语句,作用是去除里面多余的逗号
    // 测试类代码
    @Test
    void testUpdateById(){
        Student student = new Student(7, null, 29, "桂林");
        studentMapper.updateById(student);
    }
    // Mapper接口方法
    // 修改数据
    void updateById(Student student);
<?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.mybatis.Mapper.StudentMapper">
    <update id="updateById">
        update student
        <set>
            <if test="name != null">
                name = #{name}
            </if>
            <if test="age != null">
                ,age = #{age}
            </if>
            <if test="address != null">
                ,address = #{address}
            </if>
        </set>
        where id = #{id}
    </update>
 </mapper>

在这里插入图片描述


  • <foreach></foreach>标签用来遍历数组或集合
<foreach collection="集合或数组"  item=""  separeator="每一次遍历的分隔符"  open="遍历开始拼接的符号" close="遍历结束拼接的符号">
    #{item}
<foreach>

现在有这样一个需求,根据多个id查询学生信息,怎么样用一条SQL语句查询?

    // 测试类代码
    @Test
    void testFindByIds(){
        Integer ids[] = {1,2,3};
        List<Student> list = studentMapper.findByIds(ids);
        for (Student student : list) {
            System.out.println(student);
        }
    }
    // Mapper接口方法
    // 查询多个id的学生信息
    List<Student> findByIds(Integer ids[]);
<?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.mybatis.Mapper.StudentMapper">
    <select id="findByIds" resultType="com.itheima.mybatis.pojo.Student">
        select * from student
        where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </select>
</mapper>

在这里插入图片描述



  • <sql id="名字"></sql> 定义可重复的SQL片段,对代码进行抽取
  • <include refid="sql片段的id名"></include> 通过属性refid指定包含的SQL片段

在这里插入图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值