0
点赞
收藏
分享

微信扫一扫

mybatis小技巧

1. #{ }和${ }的区别   67

#{}:先编译sql语句,再给占位符传值,底层是PreparedStatement实现。可以防⽌sql注⼊,⽐较常⽤。

${}:先进⾏sql语句拼接,然后再编译sql语句,底层是Statement实现。存在sql注⼊现象。只有在需要进⾏sql语句关键字拼接的情况下才会⽤到。

2 初步认识#{ }和${ }的区别 67

2.1 需求:根据car_type查询汽⻋  67

接口CarMapper

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;

import java.util.List;

//这是一个接口   演示 #{ }和${ }的区别   67
public interface CarMapper {
    /**
     * 插入Car信息,并且使用生成的主键值。
     * @param car
     * @return
     */
    int insertCarUseGeneratedKeys(Car car);

    /**
     * 根据汽车品牌进行模糊查询
     * @param brand
     * @return
     */
    List selectByBrandLike(String brand);

    /**
     * 批量删除,根据id
     * @param ids
     * @return
     */
    int deleteBatch(String ids);

    /**
     * 查询所有的汽车信息。然后通过asc升序,desc降序。
     * @param ascOrDesc
     * @return
     */
    List selectAllByAscOrDesc(String ascOrDesc);

    /**
     * 根据汽车类型获取汽车信息。
     * @param carType
     * @return
     */
    List selectByCarType(String carType);
}

test中com.powernode.mybatis.test

CarMapperTest类中的testSelectByCarType

@Test
    public void testSelectByCarType(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List cars = mapper.selectByCarType("新能源");
        //遍历
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }

CarMapper.xml

<select id="selectByCarType" resultType="com.powernode.mybatis.pojo.Car">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
        where
            car_type = #{carType}

    </select>

2.1.1 #{}的执行结果:  67

[main] DEBUG c.p.mybatis.mapper.CarMapper.selectByCarType - ==>  Preparing: select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car where car_type = ?

[main] DEBUG c.p.mybatis.mapper.CarMapper.selectByCarType - ==> Parameters: 新能源(String)

[main] DEBUG c.p.mybatis.mapper.CarMapper.selectByCarType - <==      Total: 2

2.1.2 ${}的执行结果:  67

[main] DEBUG c.p.mybatis.mapper.CarMapper.selectByCarType - ==>  Preparing: select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car where car_type = 新能源

[main] DEBUG c.p.mybatis.mapper.CarMapper.selectByCarType - ==> Parameters:

org.apache.ibatis.exceptions.PersistenceException:

### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: Unknown column '新能源' in 'where clause'

### The error may exist in CarMapper.xml

### The error may involve defaultParameterMap

### The error occurred while setting parameters

### SQL: select             id,             car_num as carNum,             brand,             guide_price as guidePrice,             produce_time as produceTime,             car_type as carType         from             t_car         where             car_type = 新能源

### Cause: java.sql.SQLSyntaxErrorException: Unknown column '新能源' in 'where clause'

2.1.3 #{}和${}的区别:  67

    #{}: 底层使用PreparedStatement。特点:先进行SQL语句的编译,然后给SQL语句的占位符问号?传值。可以避免SQL注入的风险。

    ${}:底层使用Statement。特点:先进行SQL语句的拼接,然后再对SQL语句进行编译。存在SQL注入的风险。

优先使用#{},这是原则。避免SQL注入的风险。

3. 使用sql排序看看#{}和${}的区别  68

//查询所有  排序  68
    @Test
    public void testSelectAllByAscOrDesc(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectAllByAscOrDesc("asc");//升序
        //List<Car> cars = mapper.selectAllByAscOrDesc("desc");//降序
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }

CarMapper.xml

<select id="selectAllByAscOrDesc" resultType="com.powernode.mybatis.pojo.Car">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
        order by
            produce_time ${ascOrDesc}
    </select>

3.1 #{}的执行结果:  68

Preparing: select

                id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType

           from t_car order by produce_time ?

Parameters: asc(String)

select

    id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType

from t_car order by produce_time 'asc'

3.2 ${}的执行结果:  68

Preparing:

    select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType

    from t_car order by produce_time asc

Parameters:

如果需要SQL语句的关键字放到SQL语句中,只能使用${},因为#{}是以值的形式放到SQL语句当中的。

4. 向SQL语句当中拼接表名,就需要使用${}  69

现实业务当中,可能会存在分表存储数据的情况。因为一张表存的话,数据量太大。查询效率比较低。可以将这些数据有规律的分表存储,这样在查询的时候效率就比较高。因为扫描的数据量变少了。

日志表:专门存储日志信息的。如果t_log只有一张表,这张表中每一天都会产生很多log,慢慢的,这个表中数据会很多。

怎么解决问题?

        可以每天生成一个新表。每张表以当天日期作为名称,例如:

            t_log_20220901

            t_log_20220902

            ....

4.1 你想知道某一天的日志信息怎么办?  69

        假设今天是20220901,那么直接查:t_log_20220901的表即可。

test中com.powernode.mybatis.test

LogMapperTest

package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.LogMapper;
import com.powernode.mybatis.pojo.Log;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

//向SQL语句当中拼接表名,就需要使用${}  69
//想知道某一天的日志信息
public class LogMapperTest {

    @Test
    public void testSelectAllByTable(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        LogMapper mapper = sqlSession.getMapper(LogMapper.class);
        List<Log> logs = mapper.selectAllByTable("20220901");
        logs.forEach(log -> System.out.println(log));
    }
}

main中com.powernode.mybatis.mapper

接口LogMapper

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Log;

import java.util.List;

public interface LogMapper {
    List<Log> selectAllByTable(String date);
}

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

<!--namespace不能使用别名机制。必须写全限定接口名称。带有包名的。-->
<mapper namespace="com.powernode.mybatis.mapper.LogMapper">

    <select id="selectAllByTable" resultType="com.powernode.mybatis.pojo.Log">
            <!--select * from t_log_#{date}-->
            select * from t_log_${date}
    </select>

</mapper>

原理很简单,如果你需要先进行sql拼接在进行编译的就用${ }

  如果你就只需要进行传值用#{ }

5. 批量删除  70

批量删除:一次删除多条记录。

    批量删除的SQL语句有两种写法:

        第一种or:delete from t_car where id=1 or id=2 or id=3;

        第二种int:delete from t_car where id in(1,2,3);

    应该采用${}的方式:

        delete from t_car where id in(${ids});

test中com.powernode.mybatis.test

CarMapperTest类中的testDeleteBatch

//批量删除  70
    @Test
    public void testDeleteBatch(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        int count = mapper.deleteBatch("11,12,13");
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

CarMapper.xml

<delete id="deleteBatch">
        <!--delete from t_car where id in(#{ids})-->
        delete from t_car where id in(${ids})
    </delete>

6. 模糊查询:like   71

    需求:根据汽车品牌进行模糊查询

        select * from t_car where brand like '%奔驰%';

        select * from t_car where brand like '%比亚迪%';

    第一种方案:

        '%${brand}%'

    第二种方案:concat函数,这个是mysql数据库当中的一个函数,专门进行字符串拼接

        concat('%',#{brand},'%')

    第三种方案:比较鸡肋了。可以不算。

        concat('%','${brand}','%')

    第四种方案:

        "%"#{brand}"%"

test中com.powernode.mybatis.test

CarMapperTest类中的testSelectByBrandLike

//模糊查询  71
    @Test
    public void testSelectByBrandLike(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectByBrandLike("奔驰");
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }

CarMapper.xml

<select id="selectByBrandLike" resultType="com.powernode.mybatis.pojo.Car">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
        where
            <!--brand like '%${brand}%'-->
            <!--brand like concat('%',#{brand},'%')-->
            <!--brand like concat('%','${brand}','%')-->
            brand like "%"#{brand}"%"
    </select>

举报

相关推荐

0 条评论