9. Mybatis 小技巧

1. #{ } 和 $

#{ } 和 ${ } 的区别

#{ }:先编译sql语句,再给占位符传值,底层是PreparedStatement实现。可以防止sql注入,比较常用。

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

什么情况下必须使用${}

当需要进行sql语句关键字拼接的时候。必须使用${}

  • 拼接表名:代码演示:

    <select id="selectAllByTableName" resultType="car">
      select
      id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType
      from
      ${tableName}
    </select>
    
  • 批量删除 , 代码演示:

    <delete id="deleteBatch">
      delete from t_car where id in(${ids})
    </delete>
    
  • 模糊查询

    • 使用${} 代码演示:

      <select id="selectLikeByBrand" resultType="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>
      
    • 使用#{}代码演示:

      • 第一种:concat函数

        <select id="selectLikeByBrand" resultType="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 concat('%',#{brand},'%')
        </select>
        
      • 第二种:双引号方式 : 这种方法比较常用

        <select id="selectLikeByBrand" resultType="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. typeAliases

2.1 第一种方式:typeAlias

代码演示:

    <typeAliases>
        <typeAlias type="com.north.mybatis.pojo.Car"></typeAlias>
    </typeAliases>
  • 首先要注意typeAliases标签的放置位置,如果不清楚的话,可以看看错误提示信息。

    image

  • typeAliases标签中的typeAlias可以写多个。

  • typeAlias:

    • type属性:指定给哪个类起别名
    • alias属性:别名。
  • alias属性不是必须的,如果缺省的话,type属性指定的类型名的简类名作为别名。

  • alias是大小写不敏感的。也就是说假设alias="Car",再用的时候,可以CAR,也可以car,也可以Car,都行。

2.2 第二种方式:package (比较常用)

代码演示:

    <typeAliases>
        <package name="com.north.mybatis.pojo"/>
    </typeAliases>

如果一个包下的类太多,每个类都要起别名,会导致typeAlias标签配置较多,所以mybatis用提供package的配置方式,只需要指定包名,该包下的所有类都自动起别名,别名就是简类名。并且别名不区分大小写。

3. mappers 设置讲解

SQL映射文件的配置方式包括四种:

  • resource:从类路径中加载
  • url:从指定的全限定资源路径中加载
  • class:使用映射器接口实现类的完全限定类名
  • package:将包内的映射器接口实现全部注册为映射器

3.1 resource 讲解

这种方式是从类路径中加载配置文件,所以这种方式要求SQL映射文件必须放在resources目录下或其子目录下。

<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

3.2 URL 讲解

这种方式显然使用了绝对路径的方式,这种配置对SQL映射文件存放的位置没有要求,随意。

<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>

3.3 class 讲解 (记住这种包命名方式)

如果使用这种方式必须满足以下条件:

  • SQL映射文件和mapper接口放在同一个目录下。
  • SQL映射文件的名字也必须和mapper接口名一致。
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

将CarMapper.xml文件移动到和mapper接口同一个目录下:

  • 在resources目录下新建:com/powernode/mybatis/mapper【这里千万要注意:不能这样新建 com.powernode.mybatis.dao】
  • 将CarMapper.xml文件移动到mapper目录下
  • 修改mybatis-config.xml文件
<mappers>
  <mapper class="com.powernode.mybatis.mapper.CarMapper"/>
</mappers>

3.4 package

如果class较多,可以使用这种package的方式,但前提条件和上一种方式一样。

<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="com.north.mybatis.mapper"/>
</mappers>

4. idea配置文件模板

mybatis-config.xml和SqlMapper.xml文件可以在IDEA中提前创建好模板,以后通过模板创建配置文件。

image

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

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

业务背景:一个用户有多个角色。

插入一条新的记录之后,自动生成了主键,而这个主键需要在其他表中使用时。

插入一个用户数据的同时需要给该用户分配角色:需要将生成的用户的id插入到角色表的user_id字段上。

第一种方式:可以先插入用户数据,再写一条查询语句获取id,然后再插入user_id字段。【比较麻烦】

第二种方式:mybatis提供了一种方式更加便捷。

image

CarMapper 代码

/**
     * 获取自动生成的主键
     * @param car
     */
void insertUseGeneratedKeys(Car car);

CarMapper.xml 代码

<insert id="insertUseGeneratedKeys" useGeneratedKeys="true" keyProperty="id">
  insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
</insert>

测试代码:

@Test
public void testInsertUseGeneratedKeys(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    Car car = new Car();
    car.setCarNum("5262");
    car.setBrand("BYD汉");
    car.setGuidePrice(30.3);
    car.setProduceTime("2020-10-11");
    car.setCarType("新能源");
    mapper.insertUseGeneratedKeys(car);
    SqlSessionUtil.openSession().commit();
    System.out.println(car.getId());
}
posted @ 2024-06-23 12:43  捞月亮的小北  阅读(4)  评论(0编辑  收藏  举报