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

相关推荐
万物复苏10126 分钟前
c++-用c++解决简单数学问题
开发语言·c++·笔记·青少年编程
宇寒风暖42 分钟前
软件工程之动态建模
笔记·学习·软件工程
宇寒风暖42 分钟前
软件工程之静态建模
笔记·学习·软件工程
baijin_cha2 小时前
PyTorch基础学习03_数学运算&自动微分
人工智能·pytorch·笔记·机器学习
Eshin_Ye2 小时前
transformer学习笔记-神经网络原理
笔记·神经网络·学习
kfepiza3 小时前
Docker的save和export命令的区别,load和import的区别 笔记241124
笔记·docker
一棵开花的树,枝芽无限靠近你4 小时前
【element-tiptap】导出word
前端·笔记·学习·编辑器·word·element-tiptap
亦枫Leonlew4 小时前
微积分复习笔记 Calculus Volume 1 - 6.8 Exponential Growth and Decay
笔记·数学·微积分
想要打 Acm 的小周同学呀4 小时前
TCP/IP学习笔记
笔记·学习·tcp/ip·计算机网络