> 文章列表 > MyBatis小技巧

MyBatis小技巧

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小技巧

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--jdbc.properties--><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

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">
</mapper>

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

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

插入一条新的记录之后,自动生成了主键,而这个主键需要在其他表中使用时。
插入一个用户数据的同时需要给该用户分配角色:需要将生成的用户的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());
}

中华银杏网