当前位置: 首页 > 图灵资讯 > 技术篇> mybatis小技巧

mybatis小技巧

来源:图灵教育
时间:2023-06-05 09:30:48

1.#677}与${}的区别

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

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

2.初步了解#{}与${}的区别672.1需求:根据car_type查询汽车⻋CarMaperper67接口

package com.powernode.mybatis.mapper;import com.powernode.mybatis.pojo.Car;import java.util.List;//这是一个接口   演示 #{ }和${ }的区别   67public 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降序。然后通过asc升序,desc降序。     * @param ascOrDesc     * @return     */    List selectAllByAscOrDesc(String ascOrDesc);    /**     * 根据汽车类型获取汽车信息。     * @param carType     * @return     */    List selectByCarType(String carType);}

test中com.powernode.mybatis.testcarmapertest类testelectbycartypester

@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]DEBUGc.p.mybatis.mapper.CarMapper.selectByCarType-==>Preparing:selectid,car_numascarNum,brand,guide_priceasguidePrice,produce_timeasproduceTime,car_typeascarTypefromt_carwherecar_type=?

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

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

2.1.2${}执行结果:677

[main]DEBUGc.p.mybatis.mapper.CarMapper.selectByCarType-==>Preparing:selectid,car_numascarNum,brand,guide_priceasguidePrice,produce_timeasproduceTime,car_typeascarTypefromt_carwherecar_type=新能源

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

org.apache.ibatis.exceptions.PersistenceException:

###Errorqueryingdatabase.Cause:java.sql.SQLSyntaxErrorException:Unknowncolumn'新能源'in'whereclause'

###TheerrormayexistinCarMapper.xml

###TheerrormayinvolvedefaultParameterMap

###Theerroroccurredwhilesettingparameters

###SQL:selectid,car_numascarNum,brand,guide_priceasguidePrice,produce_timeasproduceTime,car_typeascarTypefromt_carwherecar_type=新能源

###Cause:java.sql.SQLSyntaxErrorException:Unknowncolumn'新能源'in'whereclause'

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_numascarNum,brand,guide_priceasguidePrice,produce_timeasproduceTime,car_typeascarType

fromt_carorderbyproduce_time?

Parameters:asc(String)

select

id,car_numascarNum,brand,guide_priceasguidePrice,produce_timeasproduceTime,car_typeascarType

fromt_carorderbyproduce_time'asc'

3.2${}执行结果:68

Preparing:

selectid,car_numascarNum,brand,guide_priceasguidePrice,produce_timeasproduceTime,car_typeascarType

fromt_carorderbyproduce_timeasc

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.testLogMapperTest

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:deletefromt_carwhereid=1orid=2orid=3;

第二种int:deletefromt_carwhereidin(1,2,3);

${}应采用的方式:

deletefromt_carwhereidin(${ids});

test中com.powernode.mybatis.testcarmapertest类teletebatch

///批量删除  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.模糊查询:like711

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

select*fromt_carwherebrandlike%奔驰%;

select*fromt_carwherebrandlike%比亚迪%;

第一种方案:

'%${brand}%'

第二种方案:concat函数,这是mysql数据库中的函数,专门用于字符串拼接

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

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

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

第四种方案:

"%"#{brand}"%"

test中com.powernode.mybatis.testcarmapertest类telectBrandlike

///模糊查询  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 '%${brand}%'-->            <!--brand like concat('%',#{brand},'%')-->            <!--brand like concat('''',''',''${brand}","%"-->            brand like "%"#{brand}"%"    </select>