zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Java MyBatis的使用

JAVAmybatis 使用
2023-09-11 14:22:56 时间

⭐写在前面⭐

🧭MyBatis学习
🎉 内容回顾
Java MyBatis的介绍及其执行原理
Java MyBatis配置详解
Java Mybatis中使用Junit进行测试_程序员必备
📢今天我们进行 MyBatis的使用 的学习,感谢你的阅读,内容若有不当之处,希望大家多多指正,一起进步!!!
♨️如果觉得博主文章还不错,可以👍三连支持⭐一下哦😀

Java MyBatis的使用

接口绑定

MyBaits中接口绑定主要有两种实现方式:

通过注解绑定,就是在接口方法上加上@Select @Update 等注解,里面包含SQL语句进行绑定。

通过xml文件里写SQL进行绑定、需要指定xml映射文件里的namespace必须是接口的全路径。

当语句比较简单的时候,使用注解绑定,当SQL语句比较复杂时,可以用xml绑定,一般使用xml比较多。

xml方式的用法

使用步骤

1. 创建Mapper.java接口文件

public interface StudentMapper {
    //通过ID查找学生的信息
    Student selectStudentById(Integer id);
}

2. 创建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">
<!--根标签 namespace命令空间:给定接口文件的全路径-->
<mapper namespace="com.wyscoder.mybatis.mapper.StudentMapper">
    <!--
    select 标签为查询操作标签
    id属性:Statement的id,必填的,和接口文件的方法名保持一致
    parameterType:表示输入参数的类型
    resultType:表示输出参数的类型
    #{XXX}:表示占位符,XXX:接口方法中的参数名称
    -->
    <select id="selectStudentById" parameterType="int" resultType="com.wyscoder.mybatis.pojo.Student">
        select * from student where SID = #{id}
    </select>
</mapper>

3. 在全局配置文件里面配置映射路径

<!--映射文件-->
    <mappers>
        <!--单个文件映射:resource属性一次加载一个文件,指定mapper.xml文件位置,mapper.xml文件通过namespace来查找mapper.java接口文件-->
        <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>

xml开发规范

在mapper.xml文件中 namespace 命名空间指定接口文件的全路径
在这里插入图片描述

mapper.java接口中的方法名要和mapper.xml中的statement中id保持一致
在这里插入图片描述

mapper.java接口方法中的参数类型要和mpper.xml中的parameterType指定的类型保持一致
在这里插入图片描述

mapper.java接口方法中方法的返回值类型和mapper.xml中的resultType指定的类型保持一致
在这里插入图片描述

查询标签

select

   <!--
    select 标签为查询操作标签
    id属性:Statement的id,必填的,和接口文件的方法名保持一致
    parameterType:表示输入参数的类型
    resultType:表示输出参数的类型
    #{XXX}:表示占位符,XXX:接口方法中的参数名称
    -->
    <select id="selectStudentById" parameterType="int" resultType="com.wyscoder.mybatis.pojo.Student">
        select * from student where SID = #{id}
    </select>

resultType和resultMap的区别,我们知道一张表对应一个pojo类,把表中的数据映射成一个个Java对象。其中表中的字段名和pojo类中的字段名完全保持一致的。

在这里插入图片描述
其中表中的字段名和pojo类中的字段名没有完全保持一致。这样某些字段就不能完成自动映射 比如pojo类中的Sname 改为 name ,那么查询出来结果中name为null。
在这里插入图片描述
当表中的字段名和pojo类中的字段名没有完全保持一致时,该如何解决查询结果的问题呢? 这时候我们可以用 resultMap 来解决这种映射问题。
请添加图片描述

resultMap

resultMap 标签主要用来显性指定返回值映射关系。
id 属性:取名称,可以随便给定 (必填)
type 属性:指定显性映射的Java类全限定名 (必填)

id 标签:指定主键映射关系 id标签一般使用一次指定主键即可。
result 标签:指定非主属性映射关系,可以多次使用。
property 属性:指定Java类中属性名称 (必填)
cloumn 属性:指定数据库中属性名称 (必填)
jdbcType 属性:指定数据库中当前属性类型 (选填)
javaType 属性:指定Java类中属性类型 (选填)
typeHandler 属性:类型Handler,如果是有自定义类型处理器需要在这里指定自定义类型处理器的全限定名 (选填)

<resultMap id="sudent" type="student">
	<id property="" column="" javaType="" jdbcType="" typeHandler=""/>
	<result property="" column="" javaType="" jdbcType="" typeHandler=""/>
</resultMap>

示例解决字段name不能完成映射的问题
在这里插入图片描述

同时select标签resultType属性改为resultMap属性,并指明resultMap名
在这里插入图片描述

查询结果: name完成映射。
在这里插入图片描述
🚀resultType和resultMap区别

resultTyperesultMap都是指定返回参数类型,类型可以是pojo类全限定名或者别名
resultType可以完成自动映射过程,但当字段不一致时是无法完成字段映射的,如果字段完全一致优先选取resultType
resultMap是可以显示完成映射过程,当字段不一致时可以完成映射,字段不一致要选取resultMap进行映射

🚀补充

如果数据库属性名和Java的字段名全不一样,不能创建出来映射对象
如果数据库属性名和Java的字段名只存在一个或多个相同的,都能创建出对象

插入标签

insert

insert标签表示插入数据
id属性:Statement的id,必填的,和接口文件的方法名保持一致
parameterType parameterMap属性:指定入参的类型,可以类的全限定或者别名
flushCache属性:参数是true或者false,默认是true,用来清除一级缓存和二级缓存
keyProperty属性:指定pojo类中的主键属性名
useGeneratedKeys属性:参数是true或者false,默认为false,如果是true,会采用数据自增主键
keyColumn属性:表示数据库表中主键的属性名,在update和insert中有效
没有返回类型的指定,如果接口方法中返回int会自动给定值。

  <insert id="insertStudent" parameterType="Student" flushCache="false" keyColumn="" keyProperty="" useGeneratedKeys="false">
    </insert>

示例

mapper.java接口文件中添加插入方法

int insertStudent(Student student);

mapper.xml添加insert标签

<insert id="insertStudent" parameterType="Student">
        insert into student(SID,Sname,Sage,Ssex)
        values
        (#{SID},#{name},#{Sage},#{Ssex})
    </insert>

测试类中添加测试方法

 @Test
    public void insertStudent() {
        sqlSession = sqlSessionFactory.openSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = new Student();
        student.setName("小玉");
        student.setSID(6);
        student.setSage(18);
        student.setSsex("女");
        int i = mapper.insertStudent(student);
        System.out.println("影响行数:" + i);
        sqlSession.commit();
    }

执行结果:
在这里插入图片描述

mysql> select * from student;
+-----+-------+------+------+
| SID | Sname | Sage | Ssex |
+-----+-------+------+------+
|   1 | 赵雷  |   20 ||
|   2 | 钱电  |   20 ||
|   3 | 孙风  |   21 ||
|   4 | 吴兰  |   18 ||
|   5 | 孙兰  |   17 ||
|   6 | 小玉  |   18 ||
+-----+-------+------+------+
6 rows in set (0.00 sec)

多个参数

当接口方法中有多个参数该如何解决呢?案例,通过id修改学生的姓名。

接口方法

int updateStudentById(int id,String name);

mapper.xml文件添加update标签完成映射

<update id="updateStudentById">
        update student set Sname = #{name} where SID = #{id}
    </update>

测试类添加测试方法

@Test
public void updateStudentById() {
    sqlSession = sqlSessionFactory.openSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    int i = mapper.updateStudentById(1, "小赵");
    System.out.println("影响行数:" + i);
    sqlSession.commit();
}

执行程序,出现错误。

在这里插入图片描述

🚀解读

上面控制台输出的错误表示,xml可用的参数只有 0 1 param1 param2,没有id和name。0和1,param1和param2都是mybatis根据参数位置自定义名字。如果将参数中#{name}参数改为#{1}或者#{param2},将#{id}参数改为#{0}或者#{param2},问题就解决了。

在这里插入图片描述

问题解决

<update id="updateStudentById">
        update student set Sname = #{1} where SID = #{0}
</update>

或者

<update id="updateStudentById">
        update student set Sname = #{param2} where SID = #{param1}
</update>

上述问题解决方案有一定的局限性,只能解决两个参数的问题,还有一种可以通过注解的方式来解决参数问题的方案。下图中,@Param()中参数相当于key,后面的参数相当于value,在xml文件中会根据key值找到对应的value。

在这里插入图片描述

注解方式的用法

以course表为例

+-----+-------+------+
| CID | Cname | TID  |
+-----+-------+------+
|   1 | 语文  |    2 |
|   2 | 数学  |    1 |
|   3 | 英语  |    3 |
+-----+-------+------+
3 rows in set (0.01 sec)

创建pojo类

public class Course {
    private int CID;
    private String Cname;
    private int TID;
    //省略getter 和 setter 方法
}

以@Select注解为例

创建mapper.java文件,通过注解的方式,语法: @select(“查询语句”)

public interface CourseMapper {
    @Select("select * from course where CID = #{id}")
    Course selectCnameByCid(int id);
}

因为没有mapper.xml文件,在全局配置文件中用class的方式完成映射
class中填写mapper.java的全路径

<mapper class="com.wyscoder.mybatis.mapper.CourseMapper"/>

创建测试方法,测试

在这里插入图片描述

当pojo类中的字段名没有与数据库表中的字段名保持一致时,可以用@Results注解方式解决。类似于mapper.xml文件中的resultMap

比如将上述pojo类中的Cname属性改为name,此时name没有与数据库course表中的Cname保持一致。
在这里插入图片描述

@Results注解

@Results中的属性信息与mapper.xml配置文件中的resultMap属性信息类似。

public interface CourseMapper {
    @Results(id = "courseMap", value = {
            @Result(property = "CID", column = "CID",id = true),
            @Result(property = "name",column = "Cname"),
            @Result(property = "TID",column = "TID")
    })

    @Select("select * from course where CID = #{id}")
    Course selectCnameByCid(int id);
}