2020年7月8日星期三

Mybatis的sql映射

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.

 	<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@ToStringpublic class Student { private String sname; private String age;}

Teacher.class

@Data@NoArgsConstructor@AllArgsConstructor@ToStringpublic class Teacher { private int tid; private String tname; private ArrayList<Student> list;}

创建TeacherDao接口

public interface TeacherDao { ArrayList<Teacher> getTeacher(@Param("tid") int tid);}

然后创建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@Setterpublic class Teacher { private int tid; private String tname; }

student.class

@Data@NoArgsConstructor@AllArgsConstructor@ToString@Getter@Setterpublic class Student { private int sid; private String sname; private String sage; private Teacher teacher;}

创建StudentDao接口

public interface StudentDao { public ArrayList<Student> getAllStudent();}

创建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 来保证行为与期望的相一致。
jdbcTypeJDBC 类型,只需要在可能执行插入、更新和删除的且允许空值的列上指定 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语句先在数据库中测试,确诊正确了再搬过来
Mybatis的sql映射writerindiegogo飞书互动international shopping feature好消息!跨境物流即将恢复正常!预计明年推出:eBay版FBA已完成β阶段测试!珠海长隆旅游报价珠海长隆旅游报价珠海长隆旅游报团价格