24.11.27 Mybatis3

Mybatis3

1.模糊查询的用法

mysql中常用条件连接符

复制代码
-- 查询条件  
-- 条件连接符  and   or   in
--             <  >  <= >=   !=  <>
--             BETWEEN  '2024-11-01 00:00:00' and  '2024-11-02 00:00:00'
--             like  模糊匹配符  _  %

模糊查询在业务场景中非常常用

复制代码
select * from user 
where username like CONCAT('%','老','%')

mybatis映射文件

复制代码
    <select id="listUser" resultMap="UserBaseMap">
        select * from user
        where username like CONCAT('%',#{username},'%')
    </select>

2.排序用法

排序时 需要拼语法结构 不能用#{} 需要用${} 做语法拼接

复制代码
    @Test
    public void listUserBySortTest(){
        SqlSession sqlSession = MyBatisHealper.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        //List<User> users = mapper.listUserBySort("desc");
        List<User> users = mapper.listUserBySort("asc");
        System.out.println(JSON.toJSONString(users));
        MyBatisHealper.backAndSaveSqlSession(sqlSession);
    }

    <select id="listUserBySort" resultMap="UserBaseMap">
        select * from user
        order by balance ${sort}
    </select>

#{} 传参使用

${} 拼语法使用 没有使用占位符(不要让用户自己输入,可能会SQL注入)

3.sql标签公用字段标签

查询数据时 不要*(做全表扫描 查询较慢) 可读性比较差 会把需要的字段标记出来

标记公共字段

复制代码
<!-- sql标签 公用sql语句部分 一般用来放查询的字段   -->
    <sql id="UserFileds">
        id,username,age,`password`,image,balance,create_time,update_time,rid,deptno
    </sql>

查询时引用公共字段

复制代码
    <select id="listUser" resultMap="UserBaseMap">
        select
        <include refid="UserFileds"></include>

        from user
        where username like CONCAT('%',#{username},'%')
    </select>

4.动态sql

通过java代码根据不同的查询情况 拼接出不同的sql语句

mybats提供了动态sql标签 通过标签配置 生成对应动态sql语句

1.查询场景
1.1动态查询条件 根据用户选填条件不同 生成不同的条件语句
复制代码
    <select id="listUserByCondition" resultMap="UserBaseMap">
        select
        <include refid="UserFileds"></include>

        from user
        <where>

            <if test="username!=null and username!=''">
               and username like CONCAT('%',#{username},'%')
            </if>

            <if test="deptno!=null">
                and deptno = #{deptno}
            </if>

            <if test ="age!=null">
            and age=#{age}
            </if>

               
        </where>

    </select>

注意:

复制代码
test条件中 通过java实体类属性判断
           字符串    null ""
           其他类型  null

测试代码

复制代码
    @Test
    public void listUserByConditionTest(){
        SqlSession sqlSession = MyBatisHealper.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        //List<User> users = mapper.listUserBySort("desc");
        User user = new User();
//        user.setAge(30);
//        user.setDeptno(10l);
        user.setUsername("老");
        List<User> users = mapper.listUserByCondition(user);
        System.out.println(JSON.toJSONString(users));
        MyBatisHealper.backAndSaveSqlSession(sqlSession);
    }
1.2动态查询多条数据

接口文件

复制代码
//List<Long> listId;   标准做法
//String    listIdStr  简化做法 需要使用${}拼接语法 不能防注入
//                     所以参数:1,2,3,4,5 不是从页面传的时候 才可以使用
//通过@Param封装map 指定list的key 方便映射文件使用
    List<User> listUserByListId(@Param("listId") List<Long> listId);

映射文件

复制代码
    <select id="listUserByListId" resultMap="UserBaseMap">
        select
        <include refid="UserFileds"></include>

        from user
        where id in
                                 集合的key 每次遍历到的元素 分割符
            <foreach collection="listId" item="userid" separator="," 
                                 open="(" close=")">
                #{userid} //对应item
            </foreach>


    </select>

测试代码:

复制代码
    @Test
    public void listUserByListIdTest(){
        SqlSession sqlSession = MyBatisHealper.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<Long> listId = new ArrayList<>();
        listId.add(1l);
        //listId 需要有数据 没数据会报错 执行前需要检测是否有数据
        List<User> users = mapper.listUserByListId(listId);
        System.out.println(JSON.toJSONString(users));
        MyBatisHealper.backAndSaveSqlSession(sqlSession);
    }
2.删除场景

多条删除

配合in语句 通过forEach遍历集合数据 多条删除

接口文件

复制代码
//List<Long> listId;
//String    listIdStr  1,2,3,4,5 不是从页面传的
    int deleteUserByListId(@Param("listId") List<Long> listId);

映射文件

复制代码
    <delete id="deleteUserByListId">
        delete from user
        where id in
            <foreach collection="listId" item="id" separator="," //最后一个,会自动删除
                        open="(" close=")">
                #{id}
            </foreach>

    </delete>

测试案例

复制代码
    @Test
    public void deleteUserByListIdTest(){
        SqlSession sqlSession = MyBatisHealper.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<Long> listId = new ArrayList<>();
        listId.add(29l);
        listId.add(30l);
        listId.add(31l);
        //listId 需要有数据 没数据会报错 执行前需要检测是否有数据
        int resNum = mapper.deleteUserByListId(listId);
        System.out.println(resNum);
        MyBatisHealper.backAndSaveSqlSession(sqlSession);
    }
3.添加场景 多条添加

批量从文件导入数据时使用

接口文件

复制代码
//List<User> addUserList; 传入对象集合  
int addUserByUserList(@Param("addUserList")List<User> addUserList);

映射文件

复制代码
    <insert id="addUserByUserList">
        insert into user(username,`password`,age) VALUES
                <foreach collection="addUserList" item="user" separator=",">
                   
                    (#{user.username},#{user.password},#{user.age})
                </foreach>

<!--        通过对象找到实际属性
         ('444','333',15) ,('555','333',15),('666','333',15)-->

    </insert>

测试案例

复制代码
    @Test
    public void addUserByUserListTest(){
        SqlSession sqlSession = MyBatisHealper.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> addUserList = new ArrayList<>();
        addUserList.add(new User("aaa1", 13, "aaa"));
        addUserList.add(new User("aaa2", 13, "aaa"));
        addUserList.add(new User("aaa3", 13, "aaa"));
        //listId 需要有数据 没数据会报错 执行前需要检测是否有数据
        int resNum = mapper.addUserByUserList(addUserList);
        System.out.println(resNum);
        MyBatisHealper.backAndSaveSqlSession(sqlSession);
    }
4.动态修改 根据条件不同执行的修改不同

给多模块公共修改语句时使用

接口文件

复制代码
int UpdateUserByCondition(User inputUser);

映射文件

复制代码
    <update id="UpdateUserByCondition">
        update user

        <set>
            <if test="username!=null and username!=''">
                username = #{username} ,  //set标签会自动去除多余的,
            </if>

            <if test="age!=null ">
                age = #{age} ,
            </if>

        </set>

        where id = 38

<!--     set username = '888888' ,age = 15    -->

    </update>

测试案例

复制代码
    @Test
    public void updateUserByConditionTest(){
        SqlSession sqlSession = MyBatisHealper.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
       // User user = new User("aaa2", 13, "aaa");
        User user = new User();
        user.setAge(99);
        user.setId(38l);
        //listId 需要有数据 没数据会报错 执行前需要检测是否有数据
        int resNum = mapper.UpdateUserByCondition(user);
        System.out.println(resNum);
        MyBatisHealper.backAndSaveSqlSession(sqlSession);
    }

5mybatis缓存

复制代码
* mybatis缓存
*   一级缓存(sqlSession级别)  查询数据时 如果是相同的数据 会自动存入缓存(不多次查询数据库)
*                           在一次sqlSession中生效
*
*   二级缓存(SqlSessionFactory) 可以跨sqlSession共享数据
*
* 
*   redis (类似 内存数据库) 可以替代java中的自带缓存

    @Test
    public void listUserCacheTest(){
        /*
        * mybatis缓存
        *   一级缓存(sqlSession级别)  查询数据时 如果是相同的数据 会自动存入缓存(不多次查询数据库)
        *                           在一次sqlSession中生效
        *
        *   二级缓存(SqlSessionFactory) 可以跨sqlSession共享数据
        *
        *
        *   redis (类似 内存数据库) 可以替代java中的自带缓存
        *
        *
        * */


        SqlSession sqlSession = MyBatisHealper.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        //在一次事务控制中  如果使用了相同的数据 直接从缓存加载
        List<User> users = mapper.listUser("老");
        System.out.println("第一次查询的数据"+JSON.toJSONString(users));
        MyBatisHealper.backAndSaveSqlSession(sqlSession);


        SqlSession sqlSession2 = MyBatisHealper.getSqlSession();
        UserDao mapper2 = sqlSession2.getMapper(UserDao.class);
        //在一次事务控制中  如果使用了相同的数据 直接从缓存加载
        List<User> users2 = mapper2.listUser("老");
        System.out.println("第二次查询的数据"+JSON.toJSONString(users2));
        MyBatisHealper.backAndSaveSqlSession(sqlSession2);
    }

6.mybatis注解配置

mybatis可以不使用配置文件 使用注解配置 注解不适合复杂配置

相关推荐
HuashuiMu花水木1 小时前
PyTorch笔记1----------Tensor(张量):基本概念、创建、属性、算数运算
人工智能·pytorch·笔记
一勺菠萝丶2 小时前
Spring Boot + MyBatis/MyBatis Plus:XML中循环处理List参数的终极指南
xml·spring boot·mybatis
笑衬人心。4 小时前
Ubuntu 22.04 修改默认 Python 版本为 Python3 笔记
笔记·python·ubuntu
金色光环4 小时前
【Modbus学习笔记】stm32实现Modbus
笔记·stm32·学习
zyxzyx6665 小时前
Flyway 介绍以及与 Spring Boot 集成指南
spring boot·笔记
coding and coffee6 小时前
狂神说 - Mybatis 学习笔记 --下
java·后端·mybatis
西岭千秋雪_7 小时前
Redis性能优化
数据库·redis·笔记·学习·缓存·性能优化
HuashuiMu花水木7 小时前
Matplotlib笔记4----------图像处理
图像处理·笔记·matplotlib
DES 仿真实践家8 小时前
【Day 11-N22】Python类(3)——Python的继承性、多继承、方法重写
开发语言·笔记·python
IMPYLH14 小时前
Python 的内置函数 reversed
笔记·python