Mybatis 的 XML 映射

这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战

ParameterType

  1. 一个基本类型的参数,可以通过 #{参数名} 获取

    <?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.UserMapper">
    
        <delete id="deleteUserById" parameterType="int">
            delete
            from user
            where id = #{id}
        </delete>
    
    </mapper>
    复制代码
  2. 多个参数时采用Map,通过 #{Key} 获取

    Map<String, Object> map = new HashMap<>();
    map.put("name", "test");
    map.put("password", "test");
    User user = userMapper.selectUserByNameAndPassword(map);
    复制代码
    <?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.UserMapper">
    
        <select id="selectUserByNameAndPassword" parameterType="map" resultType="pojo.User">
            select *
            from user
            where name = #{name}
              and password = #{password}
        </select>
    
    </mapper>
    复制代码
  3. 对象传递参数,通过 #{属性名} 获取

    <?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.UserMapper">
    
        <insert id="addUser" parameterType="pojo.User">
            insert into user(id, name, password)
            values (#{id}, #{name}, #{password})
        </insert>
    
    </mapper>
    复制代码
  4. 使用注解,在接口方法的参数前加 @Param() 属性,直接取 @Param() 中设置的值即可,不需要单独设置参数类型

    import org.apache.ibatis.annotations.Param;
    
    public interface UserMapper {
    
        int deleteUserById(@Param("id") int id);
        
    }
    复制代码
    <?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.UserMapper">
    
        <delete id="deleteUserById">
            delete
            from user
            where id = #{id}
        </delete>
    
    </mapper>
    复制代码

关于@Param

使用 @Param 注解用于给方法参数起一个名字。使用原则:

  • 在方法只接受一个参数的情况下,可以不使用 @Param。
  • 在方法接受多个参数的情况下,建议一定要使用 @Param 注解给参数命名。
  • 如果参数是 JavaBean , 则不能使用@Param。
  • 不使用 @Param 注解时,参数只能有一个,并且是Javabean。

#与$的区别

  • #{} 的作用主要是替换预编译语句(PrepareStatement)中的占位符? 【推荐使用】

    INSERT INTO user (name) VALUES (#{name});
    INSERT INTO user (name) VALUES (?);
    复制代码
  • ${} 的作用是直接进行字符串替换

    INSERT INTO user (name) VALUES ('${name}');
    INSERT INTO user (name) VALUES ('zhangsan');
    复制代码

ResultType

自动映射

  • resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来。
  • 实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的长达数千行的代码。
  • ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了

简单映射语句示例,不需要显指定 resultMap。比如:

<?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.UserMapper">
    
    <select id="selectUserById" resultType="map">
        select id , name , pwd
        from user
        where id = #{id}
    </select>

</mapper>
复制代码

上述语句只是简单地将所有的列映射到 HashMap 的键上,这由 resultType 属性指定。虽然在大部分情况下都够用,但是 HashMap 不是一个很好的模型。你的程序更可能会使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象)作为模型。

手动映射

返回值类型为 resultMap,编写 resultMap,实现手动映射!

<?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.UserMapper">

    <!-- 编写 resultMap -->
    <resultMap id="UserMaps" type="pojo.User">
        <!-- id为主键 -->
        <id column="id" property="id"/>
        <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
        <result column="name" property="name"/>
        <result column="password" property="password"/>
    </resultMap>

    <!-- 返回值类型为 resultMap ,值为编写的 resultMap 的 id -->
    <select id="selectUser" resultMap="UserMaps">
        select *
        from user
    </select>

</mapper>
复制代码

注解开发

适用于简单的 SQL 语句,利用注解开发就不需要 mapper.xml 映射文件

  1. 在接口中添加注解

    package mapper;
    
    import org.apache.ibatis.annotations.*;
    import pojo.User;
    
    import java.util.List;
    
    public interface UserMapper {
    
        @Insert("insert into user(id, name, password) values (#{id}, #{name}, #{password})")
        int addUser(User user);
    
        @Delete("delete from user where id=#{id}")
        int deleteUserById(@Param("id") int id);
    
        @Update("update user set name=#{name},password=#{password} where id = #{id}")
        int updateUserById(User user);
    
        @Select("select id,name,password from user")
        List<User> selectUser();
    
    }
    复制代码
  2. 在mybatis的核心配置文件中注入

    <!--注册 Mapper-->
    <mappers>
        <mapper class="mapper.UserMapper"/>
    </mappers>
    复制代码
  3. 测试 OK 即可

一对多

多个学生对应一个老师

  1. 创建学生实体类

    @Data
    public class Student {
       private int id;
       private String name;
       //多个学生可以是同一个老师,即多对一
       private Teacher teacher;
    }
    复制代码
  2. 编写 StudentMapper 接口

    public interface StudentMapper {
        
        //获取所有学生及对应老师的信息
        public List<Student> getStudents();
        
    }
    复制代码
  3. 编写 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.StudentMapper">
    
        <!--需求:获取所有学生及对应老师的信息-->
    
        <!--思路1:嵌套查询
           association → 一个复杂类型的关联;使用它来处理关联查询
       -->
        <select id="getStudents" resultMap="StudentTeacher">
            select * from student
        </select>
    
        <resultMap id="StudentTeacher" type="Student">
            <!--association关联属性 property→属性名 javaType→属性类型 column→关联列名 select→子查询-->
            <association property="teacher"  column="tid" javaType="Teacher" select="getTeacher"/>
        </resultMap>
    
        <!-- 传递一个参数的时候,下面可以写任何值 -->
        <select id="getTeacher" resultType="teacher">
            select * from teacher where id = #{id}
        </select>
    
    <!---------------------------------------------------------------------------------------------------->
        
        <!--思路2:结果集的映射-->
        <select id="getStudents2" resultMap="StudentTeacher2" >
            select s.id sid, s.name sname , t.name tname
            from student s,teacher t
            where s.tid = t.id
        </select>
    
        <resultMap id="StudentTeacher2" type="Student">
            <id property="id" column="sid"/>
            <result property="name" column="sname"/>
            <!--association关联属性 property→属性名 javaType→属性类型-->
            <association property="teacher" javaType="Teacher">
                <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
                <result property="name" column="tname"/>
            </association>
        </resultMap>
    
    </mapper>
    复制代码

    注:当子查询需要传多个参数时

    <?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.StudentMapper">  
    
        <select id="getStudents" resultMap="StudentTeacher">
            select * from student
        </select>
    
        <!-- 传递多个参数时
     association 中 column 多参数配置:column="{key=value,key=value}"
       其实就是键值对的形式,key 是传给下个 sql 的取值名称,value 是片段一中 sql 查询的字段名-->
        <resultMap id="StudentTeacher" type="Student">
            <!--association关联属性 property→属性名 javaType→属性类型 column→关联列名 select→子查询-->
            <association property="teacher"  column="{id=tid,name=tname}" javaType="Teacher" select="getTeacher"/>
        </resultMap>
    
        <select id="getTeacher" resultType="teacher">
            select * from teacher where id = #{id} and name = #{name}
        </select>
    
    </mapper>
    复制代码

多对一

一个老师对应多个学生

  1. 创建教师实体类

    @Data
    public class Teacher {
       private int id;
       private String name;
       //一个老师多个学生
       private List<Student> students;
    }
    复制代码
  2. 编写 TeacherMapper 接口

    public interface TeacherMapper {
        
        //获取指定老师,及老师下的所有学生
        public Teacher getTeacher(int id);
    
    }
    复制代码
  3. 编写 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.TeacherMapper"> 
    
        <!--需求:获取指定老师,及老师下的所有学生-->
    
        <!--思路1:嵌套查询-->
        <select id="getTeacher" resultMap="TeacherStudent2">
            select * from teacher where id = #{id}
        </select>
    
        <resultMap id="TeacherStudent2" type="Teacher">
            <!--column是 student 表外键的列名-->
            <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/>
        </resultMap>
    
        <select id="getStudentByTeacherId" resultType="Student">
            select * from student where tid = #{id}
        </select>
        
    <!---------------------------------------------------------------------------------------------------->
    
        <!--思路2:结果集映射
           集合映射使用 collection!
              JavaType 和 ofType都是用来指定对象类型的
              JavaType是用来指定 pojo 中属性的类型
              ofType 指定的是映射到 list集合属性中 pojo的类型。
       -->
        <select id="getTeacher" resultMap="TeacherStudent">
            select s.id sid, s.name sname , t.name tname, t.id tid
            from student s,teacher t
            where s.tid = t.id and t.id=#{id}
        </select>
    
        <resultMap id="TeacherStudent" type="Teacher">
            <result  property="name" column="tname"/>
            <collection property="students" ofType="Student">
                <result property="id" column="sid" />
                <result property="name" column="sname" />
                <result property="tid" column="tid" />
            </collection>
        </resultMap>
    
    </mapper>
    复制代码

猜你喜欢

转载自juejin.im/post/7034875154177982477
今日推荐