MyBatis动态sql

本文详细介绍了MyBatis中的动态SQL,包括if、choose、trim和foreach元素的使用,展示了如何根据传入参数动态构建SQL查询语句,避免硬编码和SQL注入问题。同时,讲解了一级缓存和二级缓存的工作原理,以及如何配置和使用,强调了缓存在高并发场景下的重要性。
摘要由CSDN通过智能技术生成

一 、动态sql

if
choose (when, otherwise)
trim (where, set)
foreach

1、动态sql查询

注意 查询的时候数据
常见的 动态 查询

where 可以直接让and添加 不需要在 语句写where 1=1 来调了
根据传进的值不同 调用的sql语句也不同
注意传进去的值 名字对应正确

2、一个使用多个条件

当传入值时就判断这个条件

    <select id="sellectMap" resultType="java.util.Map" parameterType="java.util.Map" >
        select  * from users
<where>
    <if test="userid!=null">
        and userid=#{userid}
    </if>
    <if test="username!=null">
        and username like concat('%',#{username},'%')
    </if>
    <if test="usepwd!=null">
       and usepwd like '%${usepwd}%'
    </if>
</where>
    </select>
     <!-- $取值:直接将内容取出来,拼接字符串的形式进去,只拼内容不带符号。 没有?占
   位,有可能造成sql注入。 优点:由于是字符串拼接,只取内容:出现在表名 列名 关键字上
   -->
    <!-- #{}取值:?占位,可以解决sql注入。相当于自带符号 ?占位不能出现在表名和列名
上关键字 -->
	
    @Test
    public void sellectMap(){
        InputStream is = null;//对一
        try {
            is = Resources.getResourceAsStream("config/mybatis.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//工具类:创建slqSessionFactory
            //SqlSessionFactory factory=builder.build(is,"development");//factory:sqlSession的工厂——基于数据源创建出来SqlSessionFactory
            // default="development"走默认
            SqlSessionFactory factory = builder.build(is);
            SqlSession session = factory.openSession();//执行sql的
            UserMapper mapper = session.getMapper(UserMapper.class);

            Map map=new HashMap();
            map.put("username","张");
            List<Map> maps = mapper.sellectMap(map);
            System.out.println(maps);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
3、多个条件中选择一个使用的·情况下

chose的功能和 switch()的功能类似 when 同 case otherwise同default相同

    </select>
    <select id="selectchoose" parameterType="java.util.Map" resultType="java.util.Map">
        select  * from users
        <where>
        <choose>
             <when test="gender==1"> 
                and gender='女'
            </when>
            <when test="gender==2">
                and gender='男'
            </when>
            <when test="gender==3">
                and (gender='女' or gender is null)
            </when>
                  <otherwise>
                and gender is null 
            </otherwise>
        </choose>
    </where>
    </select>

传入gender = 3 查询 gender= 女的 和gender =null 的 注意 null用 is 来判断

    @Test
    public void selectMapmmmm(){
        InputStream is = null;//对一
        try {
            is = Resources.getResourceAsStream("config/mybatis.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//工具类:创建slqSessionFactory
            //SqlSessionFactory factory=builder.build(is,"development");//factory:sqlSession的工厂——基于数据源创建出来SqlSessionFactory
            // default="development"走默认
            SqlSessionFactory factory = builder.build(is);
            SqlSession session = factory.openSession();//执行sql的
            UserMapper mapper = session.getMapper(UserMapper.class);
            Map map=new HashMap();
            map.put("gender","3");
            List<Map> maps = mapper.selectchoose(map);
            System.out.println(maps);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

《trim替代where》

<!-- prefix 前添加  prefixOverrides 前覆盖  -->
   <select id="sellectMaptrim" resultType="java.util.Map" parameterType="java.util.Map" >
        select  * from users
        <trim    prefix="where"  prefixOverrides="and" >
            <if test="userid!=null">
                and userid=#{userid}
            </if>
            <if test="username!=null">
                and username like concat('%',#{username},'%')
            </if>
            <if test="usepwd!=null">
                and usepwd like '%${usepwd}%'
            </if>
        </trim>
    </select>
4、.forearch in查询

foreach
元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!

 <!-- 动遍历查询 in 条件  /*
        collection:指定要遍历的集合;
        item:将当前遍历出的元素覆给指定的变量
        separator:没个元素的分隔符
        open:遍历出所有结果的拼接一个开始字符
        close: 遍历出所有结果的拼接一个结束字符
        index: 遍历的索引
        */-->
    <select id="selectMapIn" parameterType="java.util.Map" resultType="java.util.Map">
        select * from users where username in
    <foreach collection="array" item="e" index="" separator="," open="(" close=")">
        #{e}
    </foreach>
    </select>

   @Test
    public void selefctIN() {
        InputStream is = null;//对一
        try {
            is = Resources.getResourceAsStream("config/mybatis.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//工具类:创建slqSessionFactory
            //SqlSessionFactory factory=builder.build(is,"development");//factory:sqlSession的工厂——基于数据源创建出来SqlSessionFactory
            // default="development"走默认
            SqlSessionFactory factory = builder.build(is);
            SqlSession session = factory.openSession();//执行sql的
            UserMapper mapper = session.getMapper(UserMapper.class);
            String[] map={"张三","葛优"};//这是一个数组 
            List<Map> maps = mapper.selectMapIn(map);
            session.commit();
            session.close();
            System.out.println(maps);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2、动态新增

1.动态选择新增

注意数据库 的属性是否能够为空

 <insert id="inserttrmi" parameterType="java.util.Map" >
        insert into users
            <trim suffixOverrides="," prefix="(" suffix=")" >

                <if test="userid!=null"> userid,
                </if>
                <if test="username!=null">username,
                </if>
                <if test="usepwd!=null"> usepwd,
                </if>
                <if test="gender!=null"> gender,
                </if>
            </trim>
values
        <trim suffixOverrides="," prefix="(" suffix=")" >

            <if test="userid!=null">
             #{userid},
            </if>
            <if test="username!=null">
             #{username},
            </if>
            <if test="usepwd!=null">
              #{usepwd},
            </if>
            <if test="gender!=null">
                #{gender},
            </if>
        </trim>
    </insert>
   @Test
    public void insertinto(){
        InputStream is = null;//对一
        try {
            is = Resources.getResourceAsStream("config/mybatis.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//工具类:创建slqSessionFactory
            //SqlSessionFactory factory=builder.build(is,"development");//factory:sqlSession的工厂——基于数据源创建出来SqlSessionFactory
            // default="development"走默认
            SqlSessionFactory factory = builder.build(is);
            SqlSession session = factory.openSession();//执行sql的
            UserMapper mapper = session.getMapper(UserMapper.class);
            Map map=new HashMap();
            map.put("username","张");
            map.put("userid","90");
            map.put("usepwd","张");
            map.put("gender","张");
            int  maps = mapper.inserttrmi(map);
            session.commit();
            session.close();
            System.out.println(maps);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

日志

==> Preparing: insert into users ( userid, username, usepwd, gender ) values ( ?, ?, ?, ? )
==> Parameters: 90(String), 张(String), 张(String), 张(String)

2。动态批量新增 (foreach)

你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

    <select id="selectMapList" resultType="java.util.Map">
        select *
        from teacher where education in
        <foreach collection="edus" item="e" separator="," open="(" close=")">
            #{e}
        </foreach>
    </select>
  @Test
    public void insertrPL() {
        InputStream is = null;//对一
        try {
            is = Resources.getResourceAsStream("config/mybatis.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//工具类:创建slqSessionFactory
            //SqlSessionFactory factory=builder.build(is,"development");//factory:sqlSession的工厂——基于数据源创建出来SqlSessionFactory
            // default="development"走默认
            SqlSessionFactory factory = builder.build(is);
            SqlSession session = factory.openSession();//执行sql的
            UserMapper mapper = session.getMapper(UserMapper.class);

            List<Map> list=new ArrayList<>();
            Map map=new HashMap();
            map.put("username","丽丽");
            map.put("gender","女");
            map.put("usepwd","丽丽");
            list.add(map);

            map=new HashMap();
            map.put("username","丽丽");
            map.put("gender","女");
            map.put("usepwd","丽丽");
            list.add(map);

              map=new HashMap();
            map.put("username","丽丽");
            map.put("gender","女");
            map.put("usepwd","丽丽");
            list.add(map);
            map =new HashMap();
            map.put("edus",list);
            mapper.insetttrmiPL(map);
            session.commit();
            session.close();
            System.out.println(map);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

动态修改

通过判断值的插入 来属性动态修改 想修改的内容

  <update id="updateByid"  >
        update users
        <set>
            <if test="username!=null">
                 username=#{username},
            </if>
            <if test="usepwd!=null">
                 usepwd=#{usepwd},
            </if>
            <if test="gender!=null">
                gender=#{gender},
            </if>
        </set>
        where userid=#{userid}
    </update>
    @Test
    public void updateByid() {
        InputStream is = null;//动态修改
        try {
            is = Resources.getResourceAsStream("config/mybatis.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//工具类:创建slqSessionFactory
            //SqlSessionFactory factory=builder.build(is,"development");//factory:sqlSession的工厂——基于数据源创建出来SqlSessionFactory
            // default="development"走默认
            SqlSessionFactory factory = builder.build(is);
            SqlSession session = factory.openSession();//执行sql的
            UserMapper mapper = session.getMapper(UserMapper.class);
            //创建修改的属性值 传什么改什么
            Map map=new HashMap();
            map.put("userid","92");
            map.put("username","罗丽丽");
            map.put("gender","男");
           int maps = mapper.updateByid(map);
            session.commit();
            session.close();
            System.out.println(maps);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

二、缓存

一级缓存(一个MAP)

当上万个人同时访问一个数据时缓存就出现啦

当执行一个程序的语句时 查到的数据会加载到一级缓存里面,如果缓存没有清理再次调用相同方法的时候就会直接调用缓存内的数据 不会再次执行数据库

加载在一次会话的数据 会话结束 会话不同都不相同
SQLsession级别 一级缓存一直打开
执行增删改也会情空缓存
也可以手动清除缓存
sqlsession不同 和 查询条件不同的时候数据都不能使用 一级缓存

二级缓存

mapper里面
<cache eviction="" flushInterval="" readOnly="" size="" type="" blocking=""></cache>
主配置文件打开

 <setting name="cacheEnabled" value="true"/>
        <!-- 开启二级全局缓存-->

什么是二级缓存
基于namespace级别的缓存 : 一个namespace对应一个二级缓存;

1、一个会话,查询一条数据,这个数据就会放在当前会话的一级缓存中,

2、如果会话关闭:一级缓存中的数据会保存到二级缓存中;新的会话查询信息,可以参照二级缓存

3、不同的namespace查出的数据会放在自己的对应的缓存中(MAp)

查出的数据都会先放在一级缓存里面 在提交后会在在关闭后才会转移到二级缓存里面

flushInterval:刷新间隔时间,单位为毫秒,这里配置的是100秒刷新,如果你不配置它,那
么当SQL被执行的时候才会去刷新缓存。

size:引用数目,一个正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会
导致内存溢出。 这里配置的是1024个对象

readOnly:只读,缓存返回相同对象,但这些对象不要修改。否则会影响缓存内容
他的默认值是false,可读写。
读缓存:反序列化(和原来的内容已经没有联系),更改和缓存无关。

eviction
可用的清除策略有:
LRU – 最近最少使用:移除最长时间不被使用的对象。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象

type= 自定义缓存全类名 (mybatis提供啦cacher接口可以实现自动义缓存)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Network porter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值