本文已参与新人创作礼活动,一起开启掘金创造之路。
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>
产生报错: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字段👇
栗子⑤
班级实体类,一个班级里有多个学生,故其属性有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 的区别
-
collection 是将结果集封装成⼀个集合对象(多个⽬标对象)
-
association 是将结果集封装成⼀个实体类的对象(⼀个⽬标对象)
-
collection 是通过 ofType 设置数据类型, association 是通过 javaType 设置数据类型。
假如存在POJO List的对象中,也存在POJO,可以在collection中嵌套使用association