MyBatis--XxxxMapper.xml-SQL 映射文件和MyBatis--动态SQL 语句-更复杂的查询业务需求

news2024/10/6 2:31:25

目录

MyBatis--XxxxMapper.xml-SQL 映射文件

XxxMapper.xml-基本介绍

MyBatis 的真正强大

2、SQL 映射文件

XxxMapper.xml-详细说明

因为这是一个宁外开了一个项目所以做一下前期准备

Monster.java

 MonsterMapper接口

MonsterMapper .xml

 MonsterMapperTest.java

jdbc.properties

 mybatis-config.xml

parameterType(输入参数类型)

parameterType-应用案例

修改 MonsterMapper.java, 增加方法接口

修改 MonsterMapper.xml

修改 MonsterMapperTest.java ,完成测试

 传入HashMap

 修改 MonsterMapper.java, 增加方法接口

 修改 MonsterMapper.xml

修改 MonsterMapperTest.java 进行测试

传入和返回 HashMap- 应用实例

修改 MonsterMapper.java 

修改 MonsterMapper.xml 

 修改 MonsterMapperTest.java

 resultMap(结果集映射)

基本介绍

创建表 user

创建User.java

 创建UserMapper.java接口

mybatis-co nfig.xml, 改变别名的写法

 创建UserMapper.xml接口

完成测试 创建UserMapperTest 类

注意事项和细节

MyBatis--动态SQL 语句-更复杂的查询业务需求 

 动态SQL-官方文档

 为什么需要动态SQL

 动态SQL-基本介绍

 动态SQL 必要性

解决方案分析

动态SQL 常用标签

动态SQL-案例演示

 if 标签应用实例

修改 MonsterMapper.java 

 修改 MonsterMapper.xml

 修改 MonsterMapperTest.java 并完成测试

where 标签应用实例

修改MonsterMapper.java 

修改MonsterMapper.xml

 修改MonsterMapperTest.java 并完成测试

choose/when/otherwise 应用实例

 修改MonsterMapper.java 

 修改MonsterMapper.xml

  修改MonsterMapperTest.java 并完成测试

forEach 标签应用实例

修改MonsterMapper.java 

修改MonsterMapper.xml

修改MonsterMapperTest.java 并完成测试

 trim 标签应用实例【使用较少】

 修改MonsterMapper.java 

修改MonsterMapper.xml

修改MonsterMapperTest.java 并完成测试

 set 标签应用实例[重点]

修改MonsterMapper.java 

修改MonsterMapper.xml

修改MonsterMapperTest.java 并完成测试


MyBatis--XxxxMapper.xml-SQL 映射文件

官方文档

文档地址: https://mybatis.org/mybatis-3/zh/sqlmap-xml.html

XxxMapper.xml-基本介绍

MyBatis 的真正强大

在于它的语句映射(在XxxMapper.xml 配置), 由于它的异常强大, 如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。 MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

2、SQL 映射文件

常用的几个顶级元素(按照应被定义的顺序列出):

cache – 该命名空间的缓存配置。

cache-ref – 引用其它命名空间的缓存配置。

resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。

parameterType - 将会传入这条语句的参数的类全限定名或别名

sql – 可被其它语句引用的可重用语句块。

insert – 映射插入语句。

update – 映射更新语句。

delete – 映射删除语句。

select – 映射查询语句。

XxxMapper.xml-详细说明

1.    insert、delete、update、select 这个我们在前面讲解过,分别对应增删改查的方法和SQL语句的映射.
2.    如何获取到刚刚添加的 Monster 对象的 id 主键 [前面使用过了]

因为这是一个宁外开了一个项目所以做一下前期准备

将需要的文件/资源拷贝过来(这里我们拷贝Monster.java、resources和jdbc.properties 和 mybatis-config.xml)

创建 MonsterMapper.java MonsterMapper.xml 和 MonsterMapperTest.java , 做一个比较干净的讲解环境

Monster.java

package com.wyxedu.entity;

import java.util.Date;

/**
 * Monster 和 monster表有对应关系
 * 体现OOP
 */
//解读
//1. 一个普通的Pojo类
//2. 使用原生态的sql语句查询结果还是要封装成对象
//3. 要求大家这里的实体类属性名和表名字段保持一致。
public class Monster {
    //属性-和表字段有对应关系
    private Integer id;
    private Integer age;
    private String name;
    private String email;
    private Date birthday;
    private double salary;
    private Integer gender;

    public Monster() {
    }

    public Monster(Integer id, Integer age, String name, String email, Date birthday, double salary, Integer gender) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.email = email;
        this.birthday = birthday;
        this.salary = salary;
        this.gender = gender;
    }

}

 MonsterMapper接口

MonsterMapper .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">

<!--解读
1. 这是一个mapper xml 文件
2. 该文件可以去实现对应的接口的方法
3. namespace 指定该xml文件和哪个接口对应!!!
-->
<mapper namespace="com.wyxedu.mapper.MonsterMapper">

</mapper>

 MonsterMapperTest.java

注意这里的get set 和tostring大家自己生成一下或者使用注解@set @get 和快捷键生成tostring


public class MonsterMapperTest {

    //属性
    private SqlSession sqlSession;
    private MonsterMapper monsterMapper;

    //初始化
    @Before
    public void init() {

        sqlSession = MyBatisUtils.getSqlSession();
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        System.out.println("monsterMapper=" + monsterMapper.getClass());

    }

}

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8//注意这里填自己的
jdbc.user=root
jdbc.pwd=123456//注意这里填自己的

 mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!--引入外部的jdbc.properties-->
    <properties resource="jdbc.properties"/>

    <!--配置MyBatis自带的日志输出-查看原生的sql-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <!--配置别名-->
    <typeAliases>
        <!--<typeAlias type="com.wyxedu.entity.Monster" alias="Monster"/>-->

        <!--
            如果一个包下有很多的类,我们可以直接引入包,这样
            该包下面的所有类名,可以直接使用
        -->
        <package name="com.wyxedu.entity"/>
    </typeAliases>
    
    <environments default="development">
        <environment id="development">
            <!--配置事务管理器-->
            <transactionManager type="JDBC"/>
            <!--配置数据源
            解读
            1. 我们使用外部的properties文件来设置相关的值
            2. 这个属性文件,需要统一的放在 resources目录/类加载路径
            3. 关于属性文件,在讲解java基础-集合
            -->
            <dataSource type="POOLED">
                <!--配置驱动-->
                <!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
                <property name="driver" value="${jdbc.driver}"/>
                <!--配置连接mysql-url
                解读:
                1. jdbc:mysql 协议
                2. 127.0.0.1:3306 : 指定连接mysql的ip+port
                3. mybatis: 连接的DB
                4. useSSL=true 表示使用安全连接
                5. &amp; 表示 & 防止解析错误
                6. useUnicode=true : 使用unicode 作用是防止编码错误
                7. characterEncoding=UTF-8 指定使用utf-8, 防止中文乱码
                8. 温馨提示:不要背,直接使用即可
                -->
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.pwd}"/>
            </dataSource>
        </environment>
    </environments>
    <!--说明
    1. 这里我们配置需要关联的Mapper.xml
    2. 这里我们可以通过菜单 Path from source root
    -->
    <mappers>
        <!--<mapper resource="com/wyxedu/mapper/MonsterMapper.xml"/>-->

        <!--解读
           1. 如果是通过注解的方式,可不再使用 MonsterMapper.xml
           2. 但是需要在mybatis-config.xml注册/引入含注解的类
           3. 如果没有引入,不能使用
        -->
        <!--<mapper class="com.wyxedu.mapper.MonsterAnnotation"/>-->

        <!--
            解读
            1. 当一个包下有很多的Mapper.xml文件和基于注解实现的接口时,
               为了方便,我们可以以包方式进行注册
           2. 将下面的所有xml文件和注解接口 都进行注册
        -->
        <package name="com.wyxedu.mapper"/>
    </mappers>
</configuration>

parameterType(输入参数类型)

1.    传入简单类型,比如按照id 查Monster(前讲过)
2.    传入POJO 类型,查询时需要有多个筛选条件
3.    当有多个条件时,传入的参数就是Pojo 类型的Java 对象,比如这里的Monster 对象
4.    当传入的参数类是String 时,也可以使用 ${} 来接收参数

parameterType-应用案例

 案例1:请查询 id = 1 或者 name = '白骨精' 的妖怪

案例2:请查询 name 中 包含 "牛魔王" 的妖怪1

修改 MonsterMapper.java, 增加方法接口

public interface MonsterMapper {

    //通过id 或者名字查询
    public List<Monster> findMonsterByNameORId(Monster monster);

    //查询名字中含义'精'妖怪
    public List<Monster> findMonsterByName(String name);
}

修改 MonsterMapper.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">

<!--解读
1. 这是一个mapper xml 文件
2. 该文件可以去实现对应的接口的方法
3. namespace 指定该xml文件和哪个接口对应!!!
-->
<mapper namespace="com.wyxedu.mapper.MonsterMapper">
 <!--
    1. 配置/实现public List<Monster> findMonsterByNameORId(Monster monster);
    2. 通过id 或者名字查询
    3. `id` = #{id} `id`表示表的字段名 #{id} 中的id表示你传入的Monster对象的属性名
    -->
    <select id="findMonsterByNameORId" parameterType="Monster" resultType="Monster">
        SELECT * FROM `monster` WHERE `id` = #{id} OR `name` = #{name}
    </select>

    <!--
    1. 配置/实现 public List<Monster> findMonsterByName(String name);
    2. 请查询 name 中 包含 "牛魔王" 的妖怪 - 是模糊查询
    3. 模糊查询的使用 取值 需要 ${value} 取值
    -->
    <select id="findMonsterByName" parameterType="String" resultType="Monster">
        SELECT * FROM `monster` WHERE `name` LIKE '%${name}%'
    </select>
</mapper>

修改 MonsterMapperTest.java ,完成测试

package com.wyxedu.mapper;

import com.wyxedu.entity.Monster;
import com.wyxedu.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class MonsterMapperTest {

    //属性
    private SqlSession sqlSession;
    private MonsterMapper monsterMapper;

    //初始化
    @Before
    public void init() {

        sqlSession = MyBatisUtils.getSqlSession();
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        System.out.println("monsterMapper=" + monsterMapper.getClass());

    }

    @Test
    public void findMonsterByNameORId() {
        Monster monster = new Monster();
        monster.setId(1);
        monster.setName("狐狸精-100");
        List<Monster> monsters =
                monsterMapper.findMonsterByNameORId(monster);

        for (Monster m : monsters) {
            System.out.println("m-" + m);
        }

        if (sqlSession != null) {
            sqlSession.close();
        }

        System.out.println("操作成功~");
    }

    @Test
    public void findMonsterByName() {

        List<Monster> monsters = monsterMapper.findMonsterByName("精");
        for (Monster monster : monsters) {
            System.out.println("monster--" + monster);
        }

        if (sqlSession != null) {
            sqlSession.close();
        }

        System.out.println("操作成功~");
    }
}

 传入HashMap

1.    HashMap 传入参数更加灵活,比如可以灵活的增加查询的属性,而不受限于 Monster 这个 Pojo 属性本身

2.    演示如何遍历一个 List<Map<String,Object>> 的数据类型 

要求:声明一个方法,按传入参数是 HashMap 的方式,查询 id > 10 并且 salary 大于 40的所有妖怪 

 修改 MonsterMapper.java, 增加方法接口

//查询 id > 10 并且 salary 大于 40, 要求传入的参数是HashMap
    public List<Monster> findMonsterByIdAndSalary_PrameterHashMap(Map<String, Object> map);

 修改 MonsterMapper.xml

    <!--
    1. 配置/实现public List<Monster> findMonsterByIdAndSalary_PrameterHashMap(Map<String, Object> map);
    2. id > 10 并且 salary 大于 40, 要求传入的参数是HashMap
    3. 如果是以map形式传入参数,当你这样写条件 `id` > #{id} 表示你的map 中有一个k-v 中 key是id

    -->
    <select id="findMonsterByIdAndSalary_PrameterHashMap" parameterType="map" resultType="Monster">
        SELECT * FROM `monster`  WHERE `id` > #{id} AND `salary` > #{salary}
    </select>

修改 MonsterMapperTest.java 进行测试

 @Test
    public void findMonsterByIdAndSalary_PrameterHashMap() {
        //Diamond types are not supported at language level '5'
        //如何解决.=> 在pom.xml文件中指定编译器版本
        /*
             <!--指定Maven编译器 和 jdk版本-->
            <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
                <java.version>1.8</java.version>
            </properties>
         */

        Map<String, Object> map = new HashMap<>();
        map.put("id", 10);
        map.put("salary", 40);
        List<Monster> monsters =
                monsterMapper.findMonsterByIdAndSalary_PrameterHashMap(map);

        for (Monster monster : monsters) {
            System.out.println("monster--" + monster);
        }

        if (sqlSession != null) {
            sqlSession.close();
        }

        System.out.println("操作成功~");

    }

传入和返回 HashMap- 应用实例

要求:将上面的方法的改成返回参数也以 HashMap 的类型 

修改 MonsterMapper.java 

    //查询 id > 10 并且 salary 大于 40, 要求传入的参数是HashMap
    public List<Map<String, Object>>
    findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap(Map<String, Object> map);

修改 MonsterMapper.xml 

    <!--
    1. 配置/实现 public List<Map<String, Object>>
       findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap(Map<String, Object> map);
    2. id > 10 并且 salary 大于 40, 要求传入的参数和返回的是HashMap
    -->
    <select id="findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap" parameterType="map" resultType="map">
        SELECT * FROM `monster`  WHERE `id` > #{id} AND `salary` > #{salary}
    </select>

 修改 MonsterMapperTest.java

 @Test
    public void findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap() {

        Map<String, Object> map = new HashMap<>();
        map.put("id", 10);
        map.put("salary", 40);
        List<Map<String, Object>> monsterList =
                monsterMapper.findMonsterByIdAndSalary_PrameterHashMap_ReturnHashMap(map);

        //取出返回的结果-以map取出
        //回顾java基础,map遍历
        for (Map<String, Object> monsterMap : monsterList) {
            //System.out.println("monsterMap-" + monsterMap);

            //遍历monsterMap(方式1) ,取出属性和对应值
            //Set<String> keys = monsterMap.keySet();
            //for (String key : keys) {
            //    System.out.println(key + "=>" + monsterMap.get(key));
            //}

            //遍历monsterMap(方式2) ,取出属性和对应值
            for (Map.Entry<String, Object> entry : monsterMap.entrySet()) {
                System.out.println(entry.getKey() + "==>" + entry.getValue());
            }
            System.out.println("------------------------");
        }

        if (sqlSession != null) {
            sqlSession.close();
        }

        System.out.println("操作成功~");

    }

 resultMap(结果集映射)

基本介绍

当实体类的属性和表的字段名字不一致时,我们可以通过 resultMap 进行映射,从而屏蔽实体类属性名和表的字段名的不同

创建表 user

CREATE TABLE `user`(
`user_id` INT NOT NULL AUTO_INCREMENT, 
`user_email` VARCHAR(255) DEFAULT '', 
`user_name` VARCHAR(255) DEFAULT '', 
PRIMARY KEY (`user_id`)
)CHARSET=utf8

创建User.java

package com.wyxedu.entity;


public class User {
    private Integer user_id;
    private String username;
    private String useremail;

    public Integer getUser_id() {
        return user_id;
    }

    public void setUser_id(Integer user_id) {
        this.user_id = user_id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUseremail() {
        return useremail;
    }

    public void setUseremail(String useremail) {
        this.useremail = useremail;
    }

    @Override
    public String toString() {
        return "User{" +
                "user_id=" + user_id +
                ", username='" + username + '\'' +
                ", useremail='" + useremail + '\'' +
                '}';
    }
}

 创建UserMapper.java接口

public interface UserMapper {

    //添加方法
    public void addUser(User user);

    //查询所有的User
    public List<User> findAllUser();
}

mybatis-co nfig.xml, 改变别名的写法

        <typeAliases>
<!-- 为某个 mapper指定一个别名, 下面可以在 XxxxxMapper.xml 做相应简化处理 --> 
<!-- <typeAlias type="com.hspedu.entity.Monster" alias="Monster"/> --> 
            <!--<typeAlias type="com.wyxedu.entity.Monster" alias="Monster"/>-->

            <!--
                如果一个包下有很多的类,我们可以直接引入包,这样
                该包下面的所有类名,可以直接使用
            -->
            <package name="com.wyxedu.entity"/>
        </typeAliases>

 创建UserMapper.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">

<!--解读
1. 这是一个mapper xml 文件
2. 该文件可以去实现对应的接口的方法
3. namespace 指定该xml文件和哪个接口对应!!!
-->
<mapper namespace="com.wyxedu.mapper.UserMapper">

    <!--
    1、配置方法public void addUser(User user);
    2、完成添加用户的任务, 注意这里user属性和表的字段名不一致
    -->
    <insert id="addUser" parameterType="User">
        INSERT INTO `user` (`user_email`,`user_name`)
        VALUE (#{useremail}, #{username})
    </insert>

    <!--
    1. 配置方法public List<User> findAllUser();
    2. 返回所有的user信息
    3. 按照传统的方式完成,会出现什么问题?=> 如果对象属性名和表字段相同时,就会设置值, 如果不同, 就会是默认值
    4. 我们可以使用resultMap来解决
    5. resultMap : 表示我们要定义一个resultMap
    6. id="findAllUserMap"  => id 就是程序员指定的resultMap id ,后面通过id可以使用他
    7. type="User" , 就是你需要返回的对象类型
    8. result column="user_email" property="useremail":  column="user_email" 表的字段名, property="useremail" 对象属性名
    9. resultMap="findAllUserMap" 表示使用我们定义的 resultMap , 通过id关联
    -->
    <resultMap id="findAllUserMap" type="User">
        <result column="user_email" property="useremail"/>
        <result column="user_name" property="username"/>
    </resultMap>
    <select id="findAllUser" resultMap="findAllUserMap">
        SELECT * FROM `user`
    </select>


    <!--使用表字段别名,来解决表的字段名和对象属性名,不一致问题, 可以用,但是我们仍然推荐使用resultmap-->
    <!--<select id="findAllUser" resultType="User">-->
    <!--    SELECT user_id ,user_name AS username,user_email AS useremail FROM `user`-->
    <!--</select>-->
</mapper>

完成测试 创建UserMapperTest 类

package com.wyxedu.mapper;

import com.wyxedu.entity.User;
import com.wyxedu.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class UserMapperTest {

    //属性
    private SqlSession sqlSession;
    private UserMapper userMapper;

    //初始化
    @Before
    public void init() {

        sqlSession = MyBatisUtils.getSqlSession();
        userMapper = sqlSession.getMapper(UserMapper.class);

    }

    @Test
    public void addUser() {
        User user = new User();
        user.setUsername("jack");
        user.setUseremail("jack@qq.com");

        userMapper.addUser(user);

        //如果是增删改, 需要commit()
        if(sqlSession != null) {
            sqlSession.commit();
            sqlSession.close();
        }

        System.out.println("操作OK~");
    }

    @Test
    public void findAllUser() {
        List<User> users = userMapper.findAllUser();
        for (User user : users) {
            System.out.println("user--" + user);
        }

        if(sqlSession != null) {
            sqlSession.close();
        }

        System.out.println("操作OK~");
    }

}

注意事项和细节

1、解决表字段和对象属性名不一致, 也支持使用字段别名

实现 findAllUser【使用别名 屏蔽属性名和字段名不一致 1.可以用,但是复用性不 ok】 

<!-- <select id="findAllUser" resultType="User">
SELECT user_id,user_name AS username, user_email AS useremail FROM user

</select> -->

 如果是 MyBatis-Plus 处理就比较简单, 可以使用 注解@TableField 来解决实体字段名和表字段名不一致的问题,还可以使用@TableName 来解决 实体类名和表名不一致的问题

 


 

MyBatis--动态SQL 语句-更复杂的查询业务需求 

 动态SQL-官方文档

 文档地址: https://mybatis.org/mybatis-3/zh/dynamic-sql.html

 为什么需要动态SQL

1、动态 SQL 是 MyBatis 的强大特性之一

2、使用 JDBC 或其它类似的框架,根据不同条件拼接 SQL 语句非常麻烦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号等

3、 SQL 映射语句中的强大的动态 SQL 语言, 可以很好的解决这个问题.

 动态SQL-基本介绍

1.    在一个实际的项目中,sql 语句往往是比较复杂的
2.    为了满足更加复杂的业务需求,MyBatis 的设计者,提供了动态生成SQL 的功能。

 动态SQL 必要性

1.    比如我们查询Monster 时,如果程序员输入的age 不大于0, 我们的sql语句就不带age 。
2.    更新Monster 对象时,没有设置的新的属性值,就保持原来的值,设置了新的值,才更新.

解决方案分析

1.    从上面的需求我们可以看出,有时我们在生成 sql 语句时,在同一个方法中,还要根据不同的情况生成不同的sql 语句.

2.    解决方案: MyBatis 提供的动态SQL 机制.

动态SQL 常用标签

似我们Java 的控制语句: 

1.    if [判断]
2.    where [拼接 where 子句]
3.    choose/when/otherwise [类似java 的 switch 语句, 注意是单分支]
4.    foreach [类似 in ]
5.    trim [替换关键字/定制元素的功能]
6.    set [在update 的 set 中,可以保证进入 set 标签的属性被修改,而没有进入set 的,保持原来的值]

动态SQL-案例演示

 新建Module dynamic-sql

1、在原来的项目中,新建 dynamic-sql 项目演示动态SQL 的使用

2、新建 Module 后,先创建需要的包,再将需要的文件/资源拷贝过来(这里我们拷贝Monster.java、resources/jdbc.properties 和 mybatis-config.xml)

3、创建 MonsterMapper.java MonsterMapper.xml 和 MonsterMapperTest.java , 做一个比
较干净的讲解环境, 

 if 标签应用实例

需求:请查询age 大于 10 的所有妖怪,如果程序员输入的age 不大于 0, 则输出所有的妖怪! 

修改 MonsterMapper.java 

/**
 * 1. 这是一个接口
 * 2. 该接口用于声明操作monster表的方法
 * 3. 这些方法可以通过注解或者xml文件来实现
 */
public interface MonsterMapper {
   
    //根据age查询结果
    public List<Monster> findMonsterByAge(@Param(value = "age") Integer age);
}

 修改 MonsterMapper.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">

<!--解读
1. 这是一个mapper xml 文件
2. 该文件可以去实现对应的接口的方法
3. namespace 指定该xml文件和哪个接口对应!!!
-->
<mapper namespace="com.wyxedu.mapper.MonsterMapper">

    <!--
    1. 配置方法public List<Monster> findMonsterByAge(@Param(value="age") Integer age);
    2. 请查询age 大于 10 的所有妖怪,如果程序员输入的age 不大于 0, 则输出所有的妖怪
    3. 按照以前方式来配置->问题? 如果使用原来的#{age} 在test表达式是取不出入参值
    4. 解决方案是使用@Param
    -->
    <select id="findMonsterByAge" resultType="Monster" parameterType="Integer">
        SELECT * FROM `monster` WHERE 1 = 1
        <if test="age >= 0">
            AND age > #{age}
        </if>
    </select>
</mapper>

 修改 MonsterMapperTest.java 并完成测试

public class MonsterMapperTest {

    //属性
    private SqlSession sqlSession;
    private MonsterMapper monsterMapper;

    //初始化
    @Before
    public void init() {

        sqlSession = MyBatisUtils.getSqlSession();
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        System.out.println("monsterMapper=" + monsterMapper.getClass());
    }

    @Test
    public void findMonsterByAge() {
        List<Monster> monsters =
                monsterMapper.findMonsterByAge(-1);
        for (Monster monster : monsters) {
            System.out.println("monster--" + monster);
        }
        if (sqlSession != null) {
            sqlSession.close();
        }
        System.out.println("操作成功~");
    }
}

where 标签应用实例

需求:查询id 大于 20 的,并且名字是 "牛魔王" 的所有妖怪, 注意,如果名字为空,或者输入的 id 小于 0, 则不拼接 sql 语句(梳理:如果名字为空 , 就不带名字条件,如果输入的id 小于 0, 就不带id的条件)

修改MonsterMapper.java 

    //根据id和名字来查询结果
    public List<Monster> findMonsterByIdAndName(Monster monster);

修改MonsterMapper.xml

<!--
    1、配置public List<Monster> findMonsterByIdAndName(Monster monster);
    2、查询id 大于 20的,并且名字是 "牛魔王" 的所有妖怪, 注意,如果名字为空,
        或者输入的id 小于 0, 则不拼接 sql语句(老师梳理:如果名字为空 , 就不带名字条件,
        如果输入的id 小于 0, 就不带id的条件)
    3、where + if : WHERE `id` > #{id} AND `name` = #{name}
    4. 如果我们入参是对象,test表达式中, 直接使用对象的属性名即可
    5. where标签,会在组织动态sql时,加上where
    6. mybatis底层自动的去掉多余的AND
    -->
    <select id="findMonsterByIdAndName" parameterType="Monster" resultType="Monster">
        SELECT * FROM `monster`
        <where>
            <if test="id >= 0">
                AND `id` > #{id}
            </if>
            <if test="name != null and name != ''">
                AND `name` = #{name}
            </if>
        </where>
    </select>

 修改MonsterMapperTest.java 并完成测试

@Test
    public void findMonsterByIdAndName() {
        Monster monster = new Monster();
        monster.setId(1);
        monster.setName("牛魔王-100");

        List<Monster> monsters = monsterMapper.findMonsterByIdAndName(monster);
        for (Monster m : monsters) {
            System.out.println("m--" + m);
        }

        if (sqlSession != null) {
            sqlSession.close();
        }
        System.out.println("操作成功~");
    }

choose/when/otherwise 应用实例

 需求:如果给的name 不为空,就按名字查询妖怪,如果指定的id>0,就按id 来查询妖怪, 要求使用 choose/when/otherwise 标签实现, 传入参数要求使用Map

 修改MonsterMapper.java 

    //测试choose标签的使用
    public List<Monster> findMonsterByIdOrName_choose(Map<String, Object> map);

 修改MonsterMapper.xml

    <!--
    1、配置/实现public List<Monster> findMonsterByIdOrName_choose(Map<String, Object> map)
    2、  1) 如果给的name不为空,就按名字查询妖怪,
        2) 如果指定的id>0,就按id来查询妖怪
        3) 如果前面两个条件都不满足, 就默认查询 salary > 100的
        4) 使用mybatis 提供choose-when-otherwise
    -->
    <select id="findMonsterByIdOrName_choose" parameterType="map" resultType="Monster">
        SELECT * FROM `monster`
        <choose>
            <when test="name != null and name != ''">
                WHERE `name` = #{name}
            </when>
            <when test="id > 0">
                WHERE `id` > #{id}
            </when>
            <otherwise>
                WHERE `salary` > 100
            </otherwise>
        </choose>
    </select>

  修改MonsterMapperTest.java 并完成测试

    @Test
    public void findMonsterByIdOrName_choose() {

        Map<String, Object> map = new HashMap<>();
        //map.put("name", "牛魔王-100");
        map.put("id", -1);

        List<Monster> monsters = monsterMapper.findMonsterByIdOrName_choose(map);
        for (Monster monster : monsters) {
            System.out.println("monster--" + monster);
        }

        if (sqlSession != null) {
            sqlSession.close();
        }
        System.out.println("操作成功~");
    }

forEach 标签应用实例

需求:查询monster_id 为 20, 22, 34 的妖怪

修改MonsterMapper.java 

    //测试foreach的标签使用
    public List<Monster> findMonsterById_forEach(Map<String, Object> map);

修改MonsterMapper.xml

<!--
        1、配置/实现public List<Monster> findMonsterById_forEach(Map<String, Object> map);
        2、查询id 为 10, 12, 14 的妖怪
        3、是foreach标签
        4. 入参map 中 会如何传入id值 k-v ids - [集合,比如List 10,12,14], 即
           map 入参中应当有 ids-[10,12,14]
    -->
    <select id="findMonsterById_forEach" parameterType="map" resultType="Monster">
        SELECT * FROM `monster`
        <!--解读
        1、 where标签
        2.  再写入相应的处理代码,比如判断ids 是否为空.. if
        3. 如果ids不为空,则使用foreach标签进行遍历
        4. collection="ids" 对应你的入参map的 key - ids
        5. item="id" 在遍历ids集合时,每次取出的值,对应的变量id
        6. open="(" 对应的就是sql  (10,12,14) 的第一 (
        7. separator="," 遍历出来的多个值的 分隔符号
        8. close=")" 对应的就是sql  (10,12,14) 的最后 )
        9. #{id} 对应的就是 item="id"
        -->
        <if test="ids != null and ids !=''">
            <where>
                id IN
                <foreach collection="ids" item="id" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </where>
        </if>
    </select>

修改MonsterMapperTest.java 并完成测试

 @Test
    public void findMonsterById_forEach() {

        Map<String, Object> map = new HashMap<>();
        map.put("ids", Arrays.asList(10, 12, 14));

        List<Monster> monsters =
                monsterMapper.findMonsterById_forEach(map);

        for (Monster monster : monsters) {
            System.out.println("monster--" + monster);
        }


        if (sqlSession != null) {
            sqlSession.close();
        }
        System.out.println("操作成功~");

    }

 trim 标签应用实例【使用较少】

 trim 可以替换一些关键字.要求:按名字查询妖怪,如果 sql 语句有 and | or 就替换成where

 修改MonsterMapper.java 

 //trim标签的使用
    public List<Monster> findMonsterByName_Trim(Map<String, Object> map);

修改MonsterMapper.xml

    <!--
    1. 配置/实现 public List<Monster> findMonsterByName_Trim(Map<String, Object> map);
    2. 按名字和年龄 查询妖怪,如果sql语句开头有 and | or  就替换成 where
    3. 分析,如果要实现这个功能,其实使用where标签 [加入where 同时会去掉多余的and]
    4. trim prefix="WHERE" prefixOverrides="and|or|hsp" 若子句的开头为 “AND” 或 “OR  或"wyx"
    , 就去除
    -->
    <select id="findMonsterByName_Trim" parameterType="map" resultType="Monster">
        SELECT * FROM `monster`

        <trim prefix="WHERE" prefixOverrides="and|or|wyx">
            <if test="name != null and name != ''">
                AND `name` = #{name}
            </if>
            <if test="age != null and age != ''">
                AND `age` > #{age}
            </if>
        </trim>
    </select>

修改MonsterMapperTest.java 并完成测试

 @Test
    public void findMonsterByName_Trim() {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "牛魔王-100");
        map.put("age", 10);

        List<Monster> monsters =
                monsterMapper.findMonsterByName_Trim(map);

        for (Monster monster : monsters) {
            System.out.println("monster--" + monster);
        }

        if (sqlSession != null) {
            sqlSession.close();
        }
        System.out.println("操作成功~");

    }

 set 标签应用实例[重点]

 需求: 请对指定id 的妖怪进行 修改,如果没有设置新的属性,则保持原来的值

修改MonsterMapper.java 

    //测试Set标签
    public void updateMonster_set(Map<String, Object> map);

 

修改MonsterMapper.xml

   <!--
    1. 配置/实现 public void updateMonster_set(Map<String, Object> map);
    2. 请对指定id 的妖怪进行 修改,如果没有设置新的属性,则保持原来的值
    3. 入参要根据sql语句来配合 map [age-10, email-'xx@sohu.com'...]
    4. set标签会处理多余的 ,
    -->
    <update id="updateMonster_set" parameterType="map">
        UPDATE `monster`
        <set>
            <if test="age != null and age != ''">
                `age` = #{age} ,
            </if>
            <if test="email != null and email != ''">
                `email` = #{email} ,
            </if>
            <if test="name != null and name != ''">
                `name` = #{name} ,
            </if>
            <if test="birthday != null and birthday != ''">
                `birthday` = #{birthday} ,
            </if>
            <if test="salary != null and salary != ''">
                `salary` = #{salary} ,
            </if>
            <if test="gender != null and gender != ''">
                `gender` = #{gender} ,
            </if>
        </set>
        WHERE id = #{id}
    </update>

修改MonsterMapperTest.java 并完成测试

    @Test
    public void updateMonster_set() {
        Map<String, Object> map = new HashMap<>();
        map.put("id", 3);
        map.put("name", "牛魔王5-100");
        map.put("age", 76);
        map.put("email", "hsp@qq.com");

        monsterMapper.updateMonster_set(map);

        //修改需要有commit
        if (sqlSession != null) {
            sqlSession.commit();
            sqlSession.close();
        }
        System.out.println("操作成功~");
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/513077.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【sop】基于灵敏度分析的有源配电网智能软开关优化配置[升级1](Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【AI大模型】教你用百度《文心一言》5分钟写一篇博客

文章目录 前言文心一言是什么文心一言可以做什么文心一言写博客申请体验写在最后 前言 当今社会&#xff0c;博客已成为了许多人分享观点、知识和经验的重要平台。用文心一言写博客是将自己的思考、想法和经验以文字的形式呈现出来&#xff0c;让更多人了解自己。通过写博客&a…

量化因子在 DolphinDB 中的流式实现攻略

DolphinDB 是一款高性能分布式时序数据库。与传统的关系数据库和常见的时序数据库不同&#xff0c;DolphinDB 不仅提供了高速存取时序数据的基本功能&#xff0c;而且内置了向量化的多范式编程语言与强大的计算引擎。DolphinDB 的计算引擎不仅可以用于量化金融的回测和研发&…

Aztec 征集 Rollup Sequencer去中心化提案

1. 引言 前序博客&#xff1a; Rollup去中心化Rollup Decentralization Aztec Rollup中Sequencer角色的主要职责为&#xff1a; 1&#xff09;从mempool中选取pending交易2&#xff09;将选中的pending交易排序打包到L2区块中3&#xff09;验证所有private交易proof以检查其…

数据结构(C语言):递归算法删除链表中所有值为x的结点

一、一个递归算法的诞生过程 这个标题为什么要叫“一个递归算法的诞生过程”呢&#xff1f;因为我在写这个算法的时候可谓一波三折&#xff0c;冲破重重Bug最终才得到了正确的算法。 所以在这里我和大家分享一下我写这段代码的整个过程。其中提到的一些问题大家可能写代…

网络信息安全攻防学习平台CTF练习-基础篇

网络信息安全攻防学习平台 &#xff1a;http://hackinglab.cn/main.php 1、key在哪里&#xff1f; 进入环境之后&#xff0c;右击查看源代码&#xff0c;看到key再网页备注里面&#xff1a; 2、再加密一次你就得到key啦~ 根据提示信息&#xff0c;在加密一次就能得到key&#…

shell脚本----基础命令sort-tr-uniq-cut-split-paste-eval

文章目录 一、sort命令二、uniq命令三、 tr命令四、cut命令五、split命令六、paste命令七、eval命令 一、sort命令 sort命令以行为单位对文件内容进行排序&#xff0c;也可以根据不同的数据类型来排序&#xff0c;比较的原则是从首字符向后&#xff0c;一次按ASCII码的值进行比…

Mail.Ru邮箱注册教程

Mail.Ru 简介 Mail.Ru来自俄罗斯一家网络公司。该初始建立于1998年作为电子邮件服务&#xff08;因此而得名&#xff09;&#xff0c;并继续成为网络的俄语圈主要参与者&#xff0c;每月活跃用户达到俄罗斯网络用户的86&#xff05;&#xff0c;是俄罗斯最大的两家互联网企业之…

Java框架学习03(Spring中设计模式详解)

1、控制反转(IoC)和依赖注入(DI) IoC(Inversion of Control,控制反转) 是 Spring 中一个非常非常重要的概念&#xff0c;它不是什么技术&#xff0c;而是一种解耦的设计思想。 IoC 的主要目的是借助于“第三方”(Spring 中的 IoC 容器) 实现具有依赖关系的对象之间的解耦(IOC…

802. 找到最终的安全状态

class Solution { public:bool vis[40005];//vis[i]表示从节点i开始的所有可能路径是否可以到达终端节点vector<int>regraph[40005];map<int,int>mp;bool id_num[40005];bool dfs(vector<vector<int>>& graph,int st){if(mp[st] || vis[st])//如果…

内网渗透—域环境之信息收集

内网渗透—域环境之信息收集 1. 前言2. 关于域2.1. 域搭建2.2. 域渗透思路 3. 域信息收集3.1. 判断是否存在域3.1.1. 查询网络信息3.1.2. 查询当前登录域与域环境3.1.3. 判断主域 3.2. 查找域控制器3.2.1. 查询DNS地址3.2.2. 查看域控制器的机器名3.2.3. 查看域控制器 3.3. 获取…

媒体邀约之发布会彩排哪些内容和注意那些细节?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 相信发布会前小伙伴都会进行彩排&#xff0c;对发布会的细节&#xff0c;流程&#xff0c;各个工种如何配合进行提前的演练&#xff0c;那么发布会彩排哪些内容&#xff0c;要注意哪些细节…

Linux shell编程常用命令(sort排序 uniq重复行 set +-x调试脚本 tr压缩替换字符 cut切片 split拆分 paste合并文件列 eval扫描变量)

sort命令 排序 以行为单位对文件内容进行排序&#xff0c;也可以根据不同的数据类型来排序 比较原则是从首字符向后&#xff0c;依次按ASCII码值进行比较&#xff0c;最后将他们按升序输出。 sort [选项] 参数 cat file | sort 选项-n 按照数字进行排序 -r 反向排序 -u 等同于u…

[学习笔记]python的web开发全家桶(ing)

源学习视频 目的&#xff1a;开发一个平台(网站) 前端开发&#xff1a;HTML、CSS、JavaScriptWeb框架&#xff1a;接收请求并处理MySQL数据库&#xff1a;存储数据地方 快速上手&#xff1a; 基于Flask Web框架让你快速搭建一个网站出来。 深入学习&#xff1a; 基于Django…

Google Chrome谷歌浏览器崩溃,错误代码: STATUS_STACK_BUFFER_OVERRUN

前两天Edge浏览器崩溃&#xff0c;一通测试&#xff0c;最终解决。谷歌一直没更新&#xff0c;今天更新了下&#xff0c;也崩溃了。 错误代码: STATUS_STACK_BUFFER_OVERRUN 解决办法&#xff1a; 1、开始菜单搜索&#xff1a;ExploitProtection&#xff0c;打开进入。 2、切…

前端CSS学习(二)

1、选择器进阶 1.1 后代选择器&#xff1a;空格 作用&#xff1a;根据HTML标签的嵌套关系,选择父元素后代中满足条件的元素 选择器语法&#xff1a;选择器1 选择器2 { css } 结果&#xff1a;在选择器1所找到标签的后代(儿子、孙子、重孙...)中&#xff0c;找到满足选择器2的…

Ubuntu高效工具——autojump、terminator(快捷键失灵问题)

Ubuntu高效工具——autojump、terminator(快捷键失灵问题) Ubuntu高效工具——autojump、、terminator(快捷键失灵问题) 自动快速跳转工具 autojump终端高效工具 erminator 自动快速跳转工具 autojump 安装指令&#xff1a; sudo apt -y install autojump 安装完成后是不会…

【游戏分析】《某某明月刀》之御风神行

御风神行是《某某明月刀》里很常用的一个技能&#xff0c;可以用来在各大地图的传送点之间相互传送而不需要经过车夫&#xff0c;虽然冷却时间很长&#xff0c;但是非常实用。但是想去到某个传送点必须要先点亮这个传送点&#xff0c;也就是说要跑到传送点附近才可以。但是通过…

频率与周期的精密控制——用SPI输出PWM脉冲

什么是PWM? PWM(Pulse Width Modulation)控制——脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。PWM在如今的应用十分广泛,电机系统,灯光系统,电源系统,还有一些比较精密的控制系统,都无不存在着PWM的控制方式。 常用的单…

5.100ASK_V853-PRO开发板支持按键输入

0.前言 ​ 100ASK_V853-PRO开发板上共有5个功能按键&#xff0c;本章节跟大家讨论如何使能这五个按键。 1.V853功能按键原理 ​ 100ASK_V853-PRO开发板上提供的5个按键是通过GPADC高精度数模转换模块模拟出5个功能按键。GPADC 是 12bit 分辨率&#xff0c;8 位采集精度的模数…