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.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语句先在数据库中测试,确诊正确了再搬过来

Mybatis的sql映射

上一篇:java MySQL基础


下一篇:MySQL 主从复制错误1837