Mybatis的sql映射
添加:
boolean addUser(User user);
<insert id="addUser" parameterType="User">
insert into Users(uname,upass) values(#{uname},#{upass})
</insert>
删除:
boolean deleteUserById(Integer uid);
<delete id="deleteUserById" parameterType="int">
delete from Users where id = #{uid}
</delete>
修改:
boolean update(Map<String,String> map);
<update id="update" parameterType="map">
update Users set uname = #{uname}
where uid=#{uid}
</update>
查询:
List<User> selectUserById(Integer uid);
<select id="selectUserById" resultType="User">
select * from Users where uid = #{uid}
</select>
参数详解
映射语句常用属性:
属性 | 描述 |
---|---|
id |
在命名空间中唯一的标识符,可以被用来引用这条语句。 |
parameterType |
将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数。 |
resultType |
期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。 |
resultMap |
对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,resultType 和 resultMap 之间只能同时使用一个。 |
传递参数:使用占位符#{}
- 一个参数:使用
#{value}
接收。 - 同一对象的多个属性:封装成对象传入,使用
#{属性名}
接收。 - 多个参数:封装成
Map
集合传入,使用#{key}
接收。
字符串替换:使用${value}
替换字符串的一部分内容,可用作模糊匹配。
<!--查询名称中含有value值的用户-->
<select id="selectUserByName" resultType="User">
select * from user_table where name like '%${value}%'
</select>
ResultMap
作用:匹配结果映射集,常用来处理复杂结构的查询结果。
使用场景:
- 数据表字段与其对应的 JavaBean 类属性名不相同时,无法自动匹配。
- 查询结果集结构较为复杂,如查询用户信息及其所有订单集合。
例子
使用场景一:数据库表中字段名和pojo类的属性名不一致
//数据库 Users 包含字段 uid、uname、upass
//pojo类的属性为:uid uname password
List<User> selectUserById(Integer uid);
<select id="selectUserById" resultType="User">
select * from Users where uid = #{uid}
</select>
结果为:
Users(uid=1, uname=zhangwuji, password=null)
Users(uid=2, uname=zhaomin, password=null)
Users(uid=3, uname=zhouzhiruo, password=null)
Users(uid=4, uname=xiaozhao, password=null)
将mapper.xml的语句改为
<select id="queryUsers" resultMap="UsersMap">
select * from users
</select>
<resultMap id="UsersMap" type="Users">
<result property="uid" column="uid"/>
<result property="uname" column="uname"/>
<result property="password" column="upass"/>
</resultMap>
结果为:
Users(uid=1, uname=zhangwuji, password=123456)
Users(uid=2, uname=zhaomin, password=123456)
Users(uid=3, uname=zhouzhiruo, password=123456)
Users(uid=4, uname=xiaozhao, password=123456)
使用场景二:一对多
建表并赋值
CREATE TABLE `student`(
`sid` INT NOT NULL AUTO_INCREMENT COMMENT '学生id',
`sname` VARCHAR(30) NOT NULL COMMENT '学生姓名',
`sage` VARCHAR(30) NOT NULL COMMENT '学生年龄',
`tid` INT NOT NULL COMMENT '老师id',
PRIMARY KEY(`sid`)
)ENGINE = INNODB DEFAULT CHARSET = utf8;
CREATE TABLE `teacher`(
`tid` INT NOT NULL AUTO_INCREMENT COMMENT '老师id',
`tname` VARCHAR(30) NOT NULL COMMENT '老师姓名',
PRIMARY KEY(`tid`)
)ENGINE = INNODB DEFAULT CHARSET = utf8;
INSERT INTO teacher (tname) VALUES
("王老师"),
("李老师"),
("刘老师");
INSERT INTO student (sname,sage,tid) VALUES
('诸葛亮','18',1),
('李白','18',1),
('花木兰','18',1),
('妲己','18',2),
('貂蝉','18',2),
('小乔','18',2),
('鲁班','18',3),
('后裔','18',3),
('伽罗','18',3);
创建pojo类
Student.class
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Student {
private String sname;
private String age;
}
Teacher.class
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Teacher {
private int tid;
private String tname;
private ArrayList<Student> list;
}
创建TeacherDao接口
public interface TeacherDao {
ArrayList<Teacher> getTeacher(@Param("tid") int tid);
}
然后创建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.cugb.dao.TeacherDao">
<!--sql语句-->
<select id="getTeacher" resultMap="TeacherStudent">
select teacher.tid tid1,teacher.tname tname,student.sname sname,student.sage
from student,teacher
where
teacher.tid = student.tid
and
teacher.tid = #{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="tid" column="tid1"/>
<result property="tname" column="tname"/>
<collection property="list" ofType="student">
<result property="sname" column="sname"/>
<result property="sage" column="sage"/>
</collection>
</resultMap>
</mapper>
结果:
Teacher(tid=1, tname=王老师, list=[Student(sname=诸葛亮, sage=18),
Student(sname=李白, sage=18),
Student(sname=花木兰, sage=18)])
使用场景三:多对一
创建pojo
teacher.class
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Getter
@Setter
public class Teacher {
private int tid;
private String tname;
}
student.class
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Getter
@Setter
public class Student {
private int sid;
private String sname;
private String sage;
private Teacher teacher;
}
创建StudentDao接口
public interface StudentDao {
public ArrayList<Student> getAllStudent();
}
创建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.cugb.dao.StudentDao">
<!--sql语句-->
<select id="getAllStudent" resultMap="Studenteacher">
select student.sid sid,student.sname sname,student.sage,teacher.tname
from student,teacher
where
teacher.tid = student.tid
</select>
<resultMap id="Studenteacher" type="Student">
<result property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="sage" column="sage"/>
<association property="teacher" javaType="Teacher">
<result property="tname" column="tname"/>
</association>
</resultMap>
</mapper>
结果:
Student(sid=1, sname=诸葛亮, sage=18, teacher=Teacher(tname=王老师))
Student(sid=2, sname=李白, sage=18, teacher=Teacher(tname=王老师))
Student(sid=3, sname=花木兰, sage=18, teacher=Teacher(tname=王老师))
Student(sid=4, sname=妲己, sage=18, teacher=Teacher(tname=李老师))
Student(sid=5, sname=貂蝉, sage=18, teacher=Teacher(tname=李老师))
Student(sid=6, sname=小乔, sage=18, teacher=Teacher(tname=李老师))
Student(sid=7, sname=鲁班, sage=18, teacher=Teacher(tname=刘老师))
Student(sid=8, sname=后裔, sage=18, teacher=Teacher(tname=刘老师))
Student(sid=9, sname=伽罗, sage=18, teacher=Teacher(tname=刘老师))
ResultMap 结构:
constructor
:用于在实例化类时,注入结果到构造方法中。idArg
- ID 参数;标记出作为 ID 的结果可以帮助提高整体性能。arg
- 将被注入到构造方法的一个普通结果。
id
: 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能。result
– 注入到字段或 JavaBean 属性的普通结果。association
:一个复杂类型的关联;许多结果将包装成这种类型。- 嵌套结果映射 – 关联可以是
resultMap
元素,或是对其它结果映射的引用。
- 嵌套结果映射 – 关联可以是
collection
:一个复杂类型的集合。- 嵌套结果映射 – 集合可以是
resultMap
元素,或是对其它结果映射的引用。
- 嵌套结果映射 – 集合可以是
discriminator
:使用结果值来决定使用哪个resultMap
。case
- 基于某些值的结果映射- 嵌套结果映射 –
case
也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射
- 嵌套结果映射 –
ResultMap 属性:
属性 | 描述 |
---|---|
id |
当前命名空间中的一个唯一标识,用于标识一个结果映射。 |
type |
类的完全限定名, 或者一个类型别名。 |
autoMapping |
如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。默认未设置。 |
id & result 属性:
属性 | 描述 |
---|---|
property |
映射到列结果的字段或属性名。如果 JavaBean 有这个名字的属性(property),会先使用该属性。否则 MyBatis 将会寻找给定名称的字段(field)。 |
column |
数据库中的列名,或者是列的别名。 |
javaType |
一个 Java 类的全限定名,或一个类型别名。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。 |
jdbcType |
JDBC 类型,只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。如果你直接面向 JDBC 编程,你需要对可以为空值的列指定这个类型。 |
typeHandler |
使用这个属性,你可以覆盖默认的类型处理器。 这个属性值是一个类型处理器实现类的全限定名,或者是类型别名。 |
总结
-
sql映射主要是记住各标签的用处
属性 描述 id
在命名空间中唯一的标识符,可以被用来引用这条语句。 parameterType
将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数。 resultType
期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。 resultMap
对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,resultType 和 resultMap 之间只能同时使用一个。 -
resultmap处理一对多,多对一是重点难点
- 创建pojo对象尽量根据数据库字段来,避免复杂结果的处理
- 创建pojo的类,相当于一个临时的数据结构,所以创建时,应以实际需要的数据为准,而不是把数据库的所有字段都搬过来
- 如果pojo的属性是一个对象,用asossiation来处理, 对应的是javaType
- 如果pojo的属性是一个对象,用collection来处理, 对应的是ofType
- sql语句先在数据库中测试,确诊正确了再搬过来