MyBatis教程3【映射文件和动态sql】

桃扇骨 2022-02-13 10:34 305阅读 0赞

1.logj

在程序的运行的过程中为了便于查询sql的输出,需要引入logj添加依赖

  1. <dependency>
  2. <groupId>org.slf4j</groupId>
  3. <artifactId>slf4j-api</artifactId>
  4. <version>1.7.25</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.slf4j</groupId>
  8. <artifactId>slf4j-log4j12</artifactId>
  9. <version>1.7.25</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>log4j</groupId>
  13. <artifactId>log4j</artifactId>
  14. <version>1.2.17</version>
  15. </dependency>

添加log4j.properties文件

  1. log4j.rootCategory=DEBUG, stdout , R
  2. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  3. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  4. log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
  5. log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
  6. log4j.appender.R.File=C:\\tools\\logs\\dpb.log
  7. log4j.appender.R.layout=org.apache.log4j.PatternLayout
  8. log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n

效果
在这里插入图片描述

2.传入参数【$和#】

由于MyBatis底层还是Jdbc,而Jdbc在操作数据库传递参数时,有两种方式,一种是使用Statement,还有一种是使用PreparedStatement: 使用statement时,存在SQL注入问题,PreparedStatement则通过预编译解决了SQL注入问题。
  在MyBatis中,引入参数有两种方式,一种是使用#,还有一种是使用KaTeX parse error: Expected ‘EOF’, got ‘#‘ at position 7: ,其中,使用#̲对应了Jdbc种的Prepar…则对应了Jdbc种的Statement,因此在MyBatis种,推荐使用#。

#的使用

在这里插入图片描述
在这里插入图片描述

$的使用

加入可以使用KaTeX parse error: Expected ‘EOF’, got ‘#‘ at position 3: 替换#̲,注意,如果使用,需要在Mapper种指定参数名字
在这里插入图片描述
在这里插入图片描述

包装对象

javabean

  1. public class UserWrapper {
  2. private User user;
  3. public User getUser() {
  4. return user;
  5. }
  6. public void setUser(User user) {
  7. this.user = user;
  8. }
  9. }

映射文件

  1. <!-- 从包装对象中获取信息 包装对象的别名. 取信息 -->
  2. <insert id="addUser4" parameterType="UserWrapper">
  3. insert into t_user(name,age,favorites)values(#{user.name},#{user.age}
  4. ,#{user.favorites})
  5. </insert>

测试

在这里插入图片描述
在这里插入图片描述

3.返回数据

ResultType

对于简单数据类型,例如查询总记录数、查询某一个用户名这一类返回值是一个基本数据类型的,直接写Java中的基本数据类型即可。
  如果返回的是一个对象或者集合,并且对象中的属性和查询的字段名是一一对应的,那么resultType也可以直接写一个对象。

ResultMap

resultMap主要用来解决属性名和字段名不一致以及一对多、一对一查询等问题 字段名不一致时,首先可以通过取别名解决,例如Bean的定义如下:

User对象

  1. private int id;
  2. // 该类型和字段不一致
  3. private String username;
  4. private int age;

映射文件

在这里插入图片描述
在这里插入图片描述

解决方式一:给字段取别名,这里讲解解决方式二:

  1. <resultMap type="com.sxt.bean.User" id="baseMap">
  2. <id column="id" property="id"/>
  3. <result property="username" column="name"/>
  4. <result property="age" column="age"/>
  5. </resultMap>
  6. <select id="getUserById" resultMap="baseMap"
  7. resultType="com.sxt.bean.User">
  8. select id ,name ,age from t_user where id=${id}
  9. </select>

在这里插入图片描述

主键回写

一般情况下,主键有两种生成方式:

  1. 主键自增长
  2. 自定义主键(一般可以使用UUID

如果是第二种,主键一般是在Java代码中生成,然后传入数据库执行,如果是第一个主键自增长,此时,Java可能需要知道数据添加成功后的主键。 在MyBatis中,可以通过主键回填来解决这个问题(推荐)。

主键回填

  1. <insert id="add" parameterType="user" useGeneratedKeys="true" keyProperty="id">
  2. insert into t_user(username,password) values (#{name},#{password})
  3. </insert>

在这里插入图片描述
在这里插入图片描述

selectKey

另外,可以利用MySQL自带的==last_insert_id()==函数查询刚刚插入的id

  1. <insert id="add1" parameterType="user">
  2. <selectKey keyProperty="id" resultType="int" >
  3. select LAST_INSERT_ID()
  4. </selectKey>
  5. insert into t_user(username,password) values (#{name},#{password})
  6. </insert>

在这里插入图片描述

动态sql语句

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
  虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
  动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。

if语句

动态 SQL 通常要做的事情是根据条件包含 where 子句的一部分。比如

  1. <select id="queryUser" resultMap="baseMap"
  2. resultType="com.sxt.bean.User" parameterType="user">
  3. select id ,name ,age from t_user
  4. where 1 =1
  5. <if test="username!=null">
  6. and name = #{username}
  7. </if>
  8. </select>
  9. // 接口
  10. public List<User> queryUser(User user);

测试
在这里插入图片描述

where语句

在使用if语句做动态条件处理的时候如果所有条件都不满足,那么得到的SQL语句如下:

  1. select * from t_user where

在这种情况下,我们一般会加一个1=1来匹配语法规则

  1. <select id="queryUser" resultMap="baseMap"
  2. resultType="com.sxt.bean.User" parameterType="user">
  3. select id ,name ,age from t_user
  4. where 1 =1
  5. <if test="username!=null">
  6. and name = #{username}
  7. </if>
  8. </select>

此时可以使用标签来处理这种情况

  1. <select id="queryUser" resultMap="baseMap"
  2. resultType="com.sxt.bean.User" parameterType="user">
  3. select id ,name ,age from t_user
  4. <where>
  5. <if test="username!=null">
  6. and name = #{username}
  7. </if>
  8. </where>
  9. </select>

在这里插入图片描述
在这里插入图片描述

set语句

set主要也是用来解决更新问题的。

  1. <update id="updateBookById">
  2. update t_book
  3. <set>
  4. <if test="author!=null"> author=#{author},</if>
  5. <if test="name!=null"> b_name=#{name},</if>
  6. <if test="price!=null"> price=#{price},</if>
  7. </set>
  8. where id=#{id};
  9. </update>

foreach语句

foreach用来遍历,遍历的对象可以是数组,也可以是集合

dao层接口

在这里插入图片描述

mapper映射文件

  1. <select id="query1" resultType="User" resultMap="basemap">
  2. select * from t_user
  3. where id in
  4. <foreach collection="ids" open="(" close=")" separator="," item="id">
  5. #{id}
  6. </foreach>
  7. </select>
  8. <insert id="add2" parameterType="user" useGeneratedKeys="true" keyProperty="id">
  9. insert into t_user(username,password) values
  10. <foreach collection="users" separator="," item="user">
  11. (#{user.name},#{user.password})
  12. </foreach>
  13. </insert>

在这里插入图片描述

bind元素

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。

  1. <select id="getUserById" resultMap="baseMap" resultType="com.sxt.bean.User">
  2. <!-- 声明了一个参数aaa 在后面就可以使用了 -->
  3. <bind name="aaa" value="12"/>
  4. select
  5. id ,name ,age from t_user where id=${aaa}
  6. </select>

在这里插入图片描述

sql块

sql片段一般用来定义sql中的列
在这里插入图片描述

关联关系

在关系型数据库中,表与表之间很少是独立与其他表没关系的。所以在实际开发过程中我们会碰到很多复杂的关联关系。在此我们来分析下载mybatis中怎么处理这些关系

1对1

我们有一张员工表(T_EMP),一张部门表(T_DEPT)。员工表中的一条记录对应于部门表中有且仅有一条记录。这就是一对一的关联关系。

查询每个员工的信息及对应的部门信息

部门对象

  1. package com.sxt.bean;
  2. public class Dept {
  3. private Integer deptid;
  4. private String deptname;
  5. private String deptdesc;
  6. public Integer getDeptid() {
  7. return deptid;
  8. }
  9. public void setDeptid(Integer deptid) {
  10. this.deptid = deptid;
  11. }
  12. public String getDeptname() {
  13. return deptname;
  14. }
  15. public void setDeptname(String deptname) {
  16. this.deptname = deptname;
  17. }
  18. public String getDeptdesc() {
  19. return deptdesc;
  20. }
  21. public void setDeptdesc(String deptdesc) {
  22. this.deptdesc = deptdesc;
  23. }
  24. @Override
  25. public String toString() {
  26. return "Dept [deptid=" + deptid + ", deptname=" + deptname + ", deptdesc=" + deptdesc + "]";
  27. }
  28. }

员工对象

  1. package com.sxt.bean;
  2. public class Emp {
  3. private Integer id;
  4. private String name;
  5. private Dept dept;
  6. public Integer getId() {
  7. return id;
  8. }
  9. public void setId(Integer id) {
  10. this.id = id;
  11. }
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public Dept getDept() {
  19. return dept;
  20. }
  21. public void setDept(Dept dept) {
  22. this.dept = dept;
  23. }
  24. @Override
  25. public String toString() {
  26. return "Emp [id=" + id + ", name=" + name + ", dept=" + dept + "]";
  27. }
  28. }

映射文件处理

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.sxt.dao.EmpDao">
  6. <resultMap type="Emp" id="basemap">
  7. <id property="id" column="id"/>
  8. <result property="name" column="name"/>
  9. <association property="dept" javaType="Dept">
  10. <id property="deptid" column="deptid"/>
  11. <result property="deptname" column="deptname"/>
  12. <result property="deptdesc" column="deptdesc"/>
  13. </association>
  14. </resultMap>
  15. <select id="query" resultMap="basemap">
  16. SELECT t.*,t1.*
  17. FROM t_emp t LEFT JOIN t_dept t1
  18. on t.deptid=t1.deptid
  19. </select>
  20. </mapper>

在这里插入图片描述

1对多关系

查询出所有的部门信息及该部门下所有员工的信息
在这里插入图片描述

映射文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.sxt.dao.DeptDao">
  6. <resultMap type="Dept" id="basemap">
  7. <id property="deptid" column="deptid"/>
  8. <result property="deptname" column="deptname"/>
  9. <result property="deptdesc" column="deptdesc"/>
  10. <collection property="emps" ofType="Emp">
  11. <id property="id" column="id"/>
  12. <result property="name" column="name"/>
  13. <result property="deptid" column="deptid"/>
  14. </collection>
  15. </resultMap>
  16. <select id="query" resultMap="basemap">
  17. SELECT t.*,t1.*
  18. FROM t_dept t LEFT JOIN t_emp t1
  19. on t.deptid=t1.deptid
  20. </select>
  21. </mapper>

在这里插入图片描述

多对多,即使双向的1对多既是多对多关系

发表评论

表情:
评论列表 (有 0 条评论,305人围观)

还没有评论,来说两句吧...

相关阅读

    相关 MyBatis3SQL映射

    前言 前面学习了config.xml,下面就要进入MyBatis的核心SQL映射了,第一篇文章的时候,student.xml里面是这么写的: ![复制代码][copycod