MyBatis映射文件中 常用标签

在MyBatis映射文件中,如果你想根据传入的有值条件进行查询,可以使用多种动态SQL标签来实现这一需求。以下是一些常用的动态SQL标签及其用法:

insert返回自增主键

不用接收,它自己更改你传过来的admin中的id值

void addAdmin(Admin admin);
<insert id="addAdmin">
        insert into `admin` value (null,#{userName},#{password},#{ecSalt},#{lastLogin,jdbcType=BIGINT},#{isAll},#{lastIp})
        <selectKey keyProperty="adminId" resultType="int" order="AFTER">
            select LAST_INSERT_ID()
        </selectKey>
    </insert>

1. if标签:用于条件判断,只有当指定的条件为真时,才会包含该标签内的SQL片段。例如:

<select id="selectByCondition" resultType="YourModel">
     SELECT * FROM your_table
     WHERE
     <if test="condition1 != null">
       column1 = #{condition1}
     </if>
     <if test="condition2 != null">
       AND column2 = #{condition2}
     </if>
   </select>

2. **where标签**:用于自动插入"WHERE"关键字,并且会移除多余的"AND"或"OR"。例如:

<select id="selectByCondition" resultType="YourModel">
     SELECT * FROM your_table
     <where>
       <if test="condition1 != null">
         column1 = #{condition1}
       </if>
       <if test="condition2 != null">
         AND column2 = #{condition2}
       </if>
     </where>
   </select>

3. **choose、when、otherwise标签**:用于在多个条件中选择一个执行,类似于Java中的switch语句。例如:
 

<select id="selectByCondition" resultType="YourModel">
     SELECT * FROM your_table
     WHERE
     <choose>
       <when test="condition1 != null">
         column1 = #{condition1}
       </when>
       <otherwise>
         column2 = #{condition2}
       </otherwise>
     </choose>
   </select>

4. **set标签**:用于动态更新语句,它会在有值的条件后添加"SET"关键字,并移除多余的逗号。例如:

<update id="updateByCondition" parameterType="YourModel">
     UPDATE your_table
     <set>
       <if test="condition1 != null">
         column1 = #{condition1},
       </if>
       <if test="condition2 != null">
         column2 = #{condition2}
       </if>
     </set>
     WHERE id = #{id}
   </update>

5. **foreach标签**:用于遍历集合,常用于构建IN条件。例如:
 

<select id="selectByIdList" resultType="YourModel">
     SELECT * FROM your_table
     WHERE id IN
     <foreach item="idItem" collection="idList" open="(" separator="," close=")">
       #{idItem}
     </foreach>
   </select>

6. **trim标签**:提供了更灵活的文本处理能力,可以处理SQL语句的前缀和后缀。例如:
   

<update id="updateByCondition" parameterType="YourModel">
     UPDATE your_table
     <trim prefix="SET" suffixOverrides=",">
       <if test="condition1 != null">
         column1 = #{condition1},
       </if>
       <if test="condition2 != null">
         column2 = #{condition2}
       </if>
     </trim>
     WHERE id = #{id}
   </update>

7. **sql标签**:用于定义可重用的SQL片段,类似于Java中的方法。例如:
 

<sql id="Base_Column_List">
     column1, column2, column3
   </sql>
   <select id="selectAll" resultType="YourModel">
     SELECT
     <include refid="Base_Column_List"/>
     FROM your_table
   </select>

8. **include标签**:用于引用其他SQL语句中定义的SQL片段。例如:

<select id="selectAll" resultType="YourModel">
     SELECT
     <include refid="Base_Column_List"/>
     FROM your_table
   </select>

9. **bind标签**:用于在Mapper映射文件上下文中声明一个变量,该变量可以使用OGNL表达式进行赋值。

<bind name="variableName" value="expression"/>
  • name:变量的名称,这个名称在 SQL 映射文件中是唯一的。
  • value:一个 OGNL 表达式,用于计算变量的值。
<update id="updateUser" parameterType="User">
  <bind name="status" value="(user.status == 1) ? 'Active' : 'Inactive'"/>
  UPDATE users SET status = #{status} WHERE id = #{id}
</update>
<select id="selectUsersByName" resultType="User">
  <bind name="pattern" value="'%' + name + '%'"/>
  SELECT * FROM users WHERE name LIKE #{pattern}
</select>

 10,一对一查询:

<select id="selectUserWithProfile" resultMap="UserWithProfileResultMap">
  SELECT
    u.id,
    u.username,
    p.profile_info
  FROM
    User u
  LEFT JOIN Profile p ON u.profile_id = p.id
  WHERE u.id = #{id}
</select>
<resultMap id="UserWithProfileResultMap" type="User">
  <id property="id" column="id" />
  <result property="username" column="username" />
  <association property="profile" javaType="Profile">
    <id property="id" column="profile_id" />
    <result property="profileInfo" column="profile_info" />
  </association>
</resultMap>
  • type="User"指定了结果映射的类型,即查询结果将被映射到User类的实例。
  • <association>标签用于指定一对一的关系。property属性表示User类中的profile属性,javaType指定了关联对象的类型。
  • <id><result>标签在<association>内部定义了如何从查询结果中映射Profile对象的属性。

11,一对多

<select id="selectUserWithPosts" resultMap="UserWithPostsResultMap">
  SELECT
    u.id,
    u.username,
    p.id as "post.id",
    p.title,
    p.content
  FROM
    User u
  LEFT JOIN Post p ON u.id = p.user_id
  WHERE u.id = #{id}
</select>
<resultMap id="UserWithPostsResultMap" type="User">
  <id property="id" column="id" />
  <result property="username" column="username" />
  <collection property="posts" ofType="Post">
    <id property="id" column="post.id" />
    <result property="title" column="title" />
    <result property="content" column="content" />
  </collection>
</resultMap>
  • type="User" 指定了结果映射的类型,即查询结果将被映射到 User 类的实例。
  • <collection> 标签用于指定一对多的关系。property 属性表示 User 类中的 posts 属性,ofType 指定了集合中元素的类型。
  • <id> 和 <result> 标签在 <collection> 内部定义了如何从查询结果中映射 Post 对象的属性。

 12,多对多

在MyBatis中处理多对多关系时,通常会使用`<collection>`标签来实现。这个标签允许你指定一个属性,该属性是一个集合,包含了与主对象相关联的多个对象。`<collection>`标签可以与`<resultMap>`结合使用,以实现复杂的映射关系。

对于多对多关系,通常需要三个表:两个主表通过一个关联表进行连接。在MyBatis的映射文件中,你会在其中一个主表的结果映射中使用`<collection>`标签来指定如何加载关联表中的数据。

例如,如果你有两个实体`User`和`Group`,它们之间通过一个中间表`user_group`建立多对多关系,你的MyBatis映射文件可能会像这样:

<resultMap id="userResultMap" type="User">
    <id property="id" column="user_id"/>
    <result property="username" column="username"/>
    <collection property="groups" ofType="Group">
        <id property="id" column="group_id"/>
        <result property="name" column="group_name"/>
    </collection>
</resultMap>

<select id="selectUserWithGroups" resultMap="userResultMap">
    SELECT u.*, g.*
    FROM users u
    LEFT JOIN user_group ug ON u.id = ug.user_id
    LEFT JOIN groups g ON ug.group_id = g.id
    WHERE u.id = #{id}
</select>

在这个例子中,`User`实体有一个`groups`属性,它是一个包含多个`Group`对象的集合。`<collection>`标签中的`property`属性指向这个集合,`ofType`指定了集合中元素的类型。`<id>`和`<result>`标签用于映射`Group`对象的属性。

请注意,实际的SQL查询和结果映射可能会根据你的数据库结构和业务需求有所不同。上述代码只是一个示例,用于说明如何在MyBatis中处理多对多关系。在实际应用中,你可能需要根据实际情况调整SQL语句和映射配置。
关于多对多的扩展

多对多关系,必须有个中间表吗

是的,多对多关系在数据库中通常需要一个中间表(也称为关联表或链接表)来实现。这是因为关系型数据库的设计是基于实体和它们之间的关系,而多对多关系意味着两个实体之间存在复杂的双向关系,这种关系不能直接通过两个表的直接关联来表示。

在多对多关系中,中间表通常包含两个外键,这两个外键分别指向参与关系的两个表的主键。中间表可能还会包含其他信息,比如关联的额外属性或者关联的创建时间等。

例如,考虑一个学校环境中的教师和课程的关系:

- 一个教师可以教授多个课程。
- 一个课程可以由多个教师教授。

为了在数据库中表示这种关系,你可以创建三个表:

1. `teachers` 表,包含教师的信息。
2. `courses` 表,包含课程的信息。
3. `teacher_course` 中间表,包含教师和课程之间的关联信息。

`teacher_course` 表的结构可能如下:

CREATE TABLE teacher_course (
    teacher_id INT,
    course_id INT,
    PRIMARY KEY (teacher_id, course_id),
    FOREIGN KEY (teacher_id) REFERENCES teachers(id),
    FOREIGN KEY (course_id) REFERENCES courses(id)
);

在这个例子中,`teacher_course` 表通过 `teacher_id` 和 `course_id` 外键与 `teachers` 表和 `courses` 表关联。这样,你就可以在中间表中插入记录来表示哪个教师教授了哪些课程。

在应用程序中,你可以使用像MyBatis这样的ORM框架来抽象和简化这种多对多关系的查询和数据映射。通过使用MyBatis的`<collection>`标签,你可以方便地加载和处理这种复杂的关系数据。
entity怎么写

在多对多关系中,实体类(entity)的设计通常涉及到三个实体类,每个实体类代表数据库中的一个表。以教师和课程的多对多关系为例,我们可能有三个实体类:`Teacher`、`Course` 和 `TeacherCourse`。下面是每个实体类的示例代码:

1. `Teacher` 实体类(代表教师表):

public class Teacher {
    private Integer id;
    private String name;
    private String department;
    // 省略其他属性

    // 教师与课程的多对多关系
    private List<Course> courses;

    // Getter和Setter方法
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public List<Course> getCourses() {
        return courses;
    }

    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }

    // 省略其他Getter和Setter方法
}

2. `Course` 实体类(代表课程表):

public class Course {
    private Integer id;
    private String name;
    private String description;
    // 省略其他属性

    // 课程与教师的多对多关系
    private List<Teacher> teachers;

    // Getter和Setter方法
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<Teacher> getTeachers() {
        return teachers;
    }

    public void setTeachers(List<Teacher> teachers) {
        this.teachers = teachers;
    }

    // 省略其他Getter和Setter方法
}

3. `TeacherCourse` 实体类(代表中间表):

public class TeacherCourse {
    private Teacher teacher;
    private Course course;
    // 如果中间表包含额外的字段,如上课时间、教室等,可以在这里添加

    // Getter和Setter方法
    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course = course;
    }

    // 省略其他Getter和Setter方法
}

在实际应用中,`TeacherCourse` 实体类可能不需要包含 `Teacher` 和 `Course` 属性,因为这些关系已经通过 `Teacher` 和 `Course` 实体类的 `courses` 和 `teachers` 属性来表示。但是,如果中间表包含额外的信息,那么 `TeacherCourse` 实体类就会包含这些信息,并且可能会包含指向 `Teacher` 和 `Course` 的外键属性。

请注意,这些代码示例是基于Java语言的,如果你使用的是其他编程语言,实体类的语法会有所不同。此外,实体类的设计还应该考虑到你所使用的ORM框架(如Hibernate、MyBatis、JPA等)的特定要求。
 


这些标签可以帮助你构建灵活且高效的SQL查询,根据实际的业务需求动态地生成SQL语句。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值