MyBatis小技巧

一、MyBatis中接口代理机制及使用

我们不难发现,以前编写dao/mapper实现类中的方法代码很固定,基本上就是一行代码,通过SqlSession对象调用insert、delete、update、select等方法,这个类中的方法没有任何业务逻辑,既然是这样,这个类我们能不能动态的生成,以后可以不写这个类吗?答案:可以,mybatis内部已经实现了自动生成dao/mapper的代理实现类,我们直接调用以下代码即可获取dao接口的代理类。

// 这里以StudentMapper举例
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
// 获取到代理实现类mapper后,我们可以直接利用mapper去调用代理方法

使用以上代码的前提是:StudentMapper.xml文件中的namespace必须和dao接口的全限定名称一致,id必须和dao接口中方法名一致。

二、SqlSessionUtil工具类

每一次获取SqlSession对象代码太繁琐,封装一个工具类

package com.liming.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SqlSessionUtil {
    private static SqlSessionFactory sqlSessionFactory;

    /**
     * 类加载时初始化sqlSessionFactory对象
     */
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static ThreadLocal<SqlSession> local = new ThreadLocal<>();

    /**
     * 每调用一次openSession()可获取一个新的会话,该会话支持自动提交。
     *
     * @return 新的会话对象
     */
    public static SqlSession openSession() {
        SqlSession sqlSession = local.get();
        if (sqlSession == null) {
            sqlSession = sqlSessionFactory.openSession(true);
            local.set(sqlSession);
        }
        return sqlSession;
    }

    /**
     * 关闭SqlSession对象
     * @param sqlSession
     */
    public static void close(SqlSession sqlSession){
        if (sqlSession != null) {
            sqlSession.close();
        }
        local.remove();
    }
}

三、#{}和${}

1、#{}:先编译sql语句,再给占位符传值,底层是PreparedStatement实现。可以防止sql注入,比较常用。
2、${}:先进行sql语句拼接,然后再编译sql语句,底层是Statement实现。存在sql注入现象。只有在需要进行sql语句关键字拼接的情况下才会用到。
3、如果需要SQL语句的关键字放到SQL语句中,只能使用${},因为#{}是以的形式(字符串)放到SQL语句中的。
4、优先使用#{}这是原则,避免SQL注入的风险

模糊查询

  1. 使用${}
select * from 表名 where 字段名 like '%${形参}%'
  1. 使用#{}
// 第一种:concat函数
select * from 表名 where 字段名 like concat('%',#{形参},'%')

// 第二种:双引号方式
select * from 表名 where 字段名 like "%"#{形参}"%"

四、idea配置文件模板

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

MyBatis小技巧_第1张图片

mybatis-config.xml


DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
    <properties resource=""/>
    <settings>
        
        <setting name="lazyLoadingEnabled" value="true"/>
        
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    settings>
    
    <typeAliases>
        <package name=""/>
    typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            dataSource>
        environment>
    environments>
    <mappers>
        
       <package name=""/>
    mappers>
configuration>

SqlMapper.xml


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">
mapper>

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

前提是:主键是自动生成的。
业务背景:一个用户有多个角色。
MyBatis小技巧_第2张图片

插入一条新的记录之后,自动生成了主键,而这个主键需要在其他表中使用时。
插入一个用户数据的同时需要给该用户分配角色:需要将生成的用户的id插入到角色表的user_id字段上。

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>

CarMapperTest.testInsertUseGeneratedKeys

@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());
}

你可能感兴趣的:(Mybatis,mybatis,java,数据库)