【Mybatis专栏】(二)Mapper.xml实战

266 阅读2分钟

本文已参与新人创作礼活动,一起开启掘金创造之路。

Mapper.XML

Header

<?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为xml全限定文件名(包名+文件名)-->
<mapper namespace="xxx.xxx.xxx.XMLFileName">
</mapper>

SQL语句

栗子①

<select id="findById" parameterType="java.lang.Integer" resultType="org.sample.entity.People">
    select * from people where id = #{id}
</select>
package org.sample.repository;
import org.sample.entity.People;
public interface PeopleRepository {
  People findById(Integer id);
	int save(People people);
	People findByIdAndName(Integer id,String name);
}
  • select:执行select MySql语句
  • id:对应实体接口的函数
  • parameterType:实体接口函数的形参
  • resultType:实体接口函数的返回类型

栗子②

<insert id="save" parameterType="org.sample.entity.People">
    insert into people(id,name,money) values(#{id},#{name},#{money})
</insert>

values(#{id},#{name},#{money}) : 形参为POJO时,value是通过反射调用对应的getter方法获取,故命名需要与实体类成员属性一致

栗子③

多入口参数

public interface PeopleRepository {
    People findByIdAndName(Integer id,String name);
}
<select id="findByIdAndName" resultType="com.southwind.entity.People">
	select * from people where id = #{id} and name = #{name}
</select>

image.png

产生报错:org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]

多参数时需要使用arg1, arg0, param1, param2去给value赋值👇

<select id="findByIdAndName" resultType="com.southwind.entity.People">
	select * from people where id = #{arg0} and name = #{arg1}
</select>

栗子④

学生实体类,学生属于某个班级,故存在Classes属性

import lombok.Data;
@Data
public class Student {
    private Integer id;
    private String name;
    private Classes classes;
}

import org.sample.entity.Student;
public interface StudentRepository {
    public Student findById(Integer id);
}
<mapper namespace="org.sample.repository.StudentRepository">
  <resultMap id="studentMap" type="org.sample.entity.Student">
        <!--column数据库表里面的字段,property实体类里面的属性-->
      <id column="sid" property="id"/>
      <result column="sname" property="name"/>
      <association property="classes" javaType="org.sample.entity.Classes">
          <id column="cid" property="id"/>
          <result column="cname" property="name"/>
      </association>
  </resultMap>
  <select id="findById" parameterType="java.lang.Integer" resultMap="studentMap">
      select s.id sid,s.name sname,c.id cid,c.name cname from t_student s,t_classes c where s.id = #{id} and s.cid = c.id
  </select>
</mapper>
  • resultMap : 当返回值的POJO(Student)中存在成员属性也为POJO(Classes)时,需要用resultMap创建映射
  • resultMap→id(result)→column : 对应select返回的数据库字段
  • resultMap→id(result)→property : 对应实体类里面的属性
  • resultMap→association : 映射到POJO的某个类型属性

id 和 result 都将一个列的值映射到一个简单数据类型(字符串,整型,双精度浮点数,日期等)的属性或字段,但是id 表示的结果将是对象的标识属性

假如此处不对数据库字段重命名select s.id sid,s.name sname,c.id cid,c.name cname ,则会导致赋值错误,因为student表和classes表都存在id字段👇

image.png

栗子⑤

班级实体类,一个班级里有多个学生,故其属性有student list

public class Classes {
    private Integer id;
    private String name;
    private List<Student> students;
}

public interface StudentRepository {
    public Student findById(Integer id);
}
<resultMap id="classesMap" type="org.sample.entity.Classes">
    <!--column数据库表里面的字段,property实体类里面的属性-->
    <id column="cid" property="id"/>
    <result column="cname" property="name"/>
    <collection property="students" ofType="org.sample.entity.Student">
        <id column="sid" property="id"/>
        <result column="sname" property="name"/>
    </collection>
</resultMap>
  • resultMap→collection : 映射到POJO List 对象

collection 和 association 的区别

  1. collection 是将结果集封装成⼀个集合对象(多个⽬标对象)

  2. association 是将结果集封装成⼀个实体类的对象(⼀个⽬标对象)

  3. collection 是通过 ofType 设置数据类型, association 是通过 javaType 设置数据类型。

假如存在POJO List的对象中,也存在POJO,可以在collection中嵌套使用association