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可以不使用配置文件 使用注解配置 注解不适合复杂配置

相关推荐
zhuyixiangyyds7 小时前
day21和day22学习Pandas库
笔记·学习·pandas
jingjingjing11118 小时前
笔记:docker安装(ubuntu 20.04)
笔记·docker·容器
DreamBoy@9 小时前
【408--考研复习笔记】操作系统----知识点速览
笔记
UpUpUp……9 小时前
特殊类的设计/单例模式
开发语言·c++·笔记·单例模式
电星托马斯10 小时前
C++中顺序容器vector、list和deque的使用方法
linux·c语言·c++·windows·笔记·学习·程序人生
jingjingjing111110 小时前
笔记:代码随想录算法训练营day64:拓扑排序精讲、dijkstra(朴素版)精讲
笔记
jimmyleeee10 小时前
人工智能基础知识笔记七:随机变量的几种分布
人工智能·笔记·概率论
熬夜造bug11 小时前
LeetCode Hot100 刷题笔记(6)—— 栈、堆
笔记
对方正在长头发丿12 小时前
LETTERS(DFS)
c++·笔记·算法·深度优先·图论
能来帮帮蒟蒻吗12 小时前
GO语言学习(16)Gin后端框架
开发语言·笔记·学习·golang·gin