八、MyBatis小技巧

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

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

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

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

    1.1什么时候使用${}

    CarMapper.java

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

    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>
    

    CarMapperTest

    @Test
        public void testSelectAllByAscOrDesc(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            List<Car> cars = mapper.selectAllByAscOrDesc("desc");
            cars.forEach( car -> System.out.println(car));
            sqlSession.close();
        }
    
  • #{}的执行结果:
    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'

  • ${}的执行结果:
    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

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

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

    业务当中,可能会存在分表存储数据的情况。因为一张表存的话,数据量太大。查询效率比较低。
    可以将这些数据有规律的分表存储,这样在查询的时候效率就比较高。因为扫描的数据量变少了。
    日志表:专门存储日志信息的。如果t_log只有一张表,这张表中每一天都会产生很多log,慢慢的,这个表中数据会很多。
    怎么解决问题?
    可以每天生成一个新表。每张表以当天日期作为名称,例如:
    t_log_20220901
    t_log_20220902

    <select id="selectAllByTable" resultType="com.powernode.mybatis.pojo.Log">
            select * from t_log_${date}
    select>
    
    1.3.批量删除:一次删除多条记录。

    批量删除的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});

    1.4.模糊查询:like

    需求:根据汽车品牌进行模糊查询
    select * from t_car where brand like ‘%奔驰%’;

    第一种方案:
    '%${brand}%'
    第二种方案:concat函数,这个是mysql数据库当中的一个函数,专门进行字符串拼接
    concat('%',#{brand},'%')
    第三种方案:比较鸡肋了。可以不算。
    concat('%','${brand}','%')
    第四种方案:
    "%"#{brand}"%"

    <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}"%"
        select>
    

2. 关于MyBatis中别名机制:


<typeAliases>
    
    <typeAlias type="com.powernode.mybatis.pojo.CarMapper" alias="car"/>
    
    <package name="com.powernode.mybatis.pojo"/>
typeAliases>

所有别名不区分大小写。
namespace不能使用别名机制。

6. mybatis-config.xml文件中的mappers标签。

要求类的根路径下必须有:CarMapper.xml
要求在d:/下有CarMapper.xml文件

  • mapper标签的属性可以有三个:

    • resource:这种方式是从类的根路径下开始查找资源。采用这种方式的话,配置文件需要放到类路径当中才行。
    • url: 这种方式是一种绝对路径的方式,这种方式不要求配置文件必须放到类路径当中,哪里都行,只要提供一个绝对路径就行。这种方式使用极少,因为移植性太差。
    • class: 这个位置提供的是mapper接口的全限定接口名,必须带有包名的。
    • 思考:mapper标签的作用是指定SqlMapper.xml文件的路径,指定接口名有什么用呢?

      如果你class指定是:com.powernode.mybatis.mapper.CarMapper
      那么mybatis框架会自动去com/powernode/mybatis/mapper目录下查找CarMapper.xml文件。
      注意:也就是说:如果你采用这种方式,那么你必须保证CarMapper.xml文件和CarMapper接口必须在同一个目录下。并且名字一致。
      CarMapper接口-> CarMapper.xml
  • package:将包内的映射器接口实现全部注册为映射器

提醒:
在IDEA的resources目录下新建多重目录的话,必须是这样创建:
com/powernode/mybatis/mapper
不能这样:
com.powernode.mybatis.mapper

<mappers>
    
    <mapper resource="CarMapper.xml"/>
    
    <mapper url="file://c:/CarMapper.xml"/>
    
    
    
    
    <mapper class="com.powernode.mybatis.mapper.CarMapper"/>
    
    
    
    <package name="com.powernode.mybatis.mapper"/>

mappers>

7 插入数据时获取自动生成的主键

前提:主键是自动生成的。


<insert id="insertCarUseGeneratedKeys" useGeneratedKeys="true" keyProperty="id">
    insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
insert>

把自动递增的主键返回给了id

你可能感兴趣的:(MyBatis老杜学习笔记,mybatis,sql,java)