Mybatis 基础
简介
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。
MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。
MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的POJOs(普通的 Java对象)映射成数据库中的记录。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但其实可以使用任何Reader实例,包括用文件路径或 file:// 开头的 url 创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
优点
- MyBatis封装了JBDC底层访问数据库的细节,使我们程序猿不需要与JDBC API打交道,就可以访问数据库
- MyBatis简单易学,程序猿直接编写SQL语句,适合于对SQL语句性能要求比较高的项目
- SQL语句封装在配置文件中,便于统一管理与维护,降低了程序的耦合度
- SQL代码从程序代码中彻底分离出来,可重用
- 提供了动态SQL标签,支持编写动态SQL
- 提供映射标签,支持对象与数据库的ORM字段关系映射
缺点
- 过于依赖数据库SQL语句,导致数据库移植性差,更换数据库,如果SQL语句有差异,SQL语句工作量大
- 由于xml里标签id必须唯一,导致DAO中方法不支持方法重载
SpringBoot 集成 Mybatis
依赖
SpringBoot官方并没有提供Mybatis的启动器,不过Mybatis官网自己实现了
<!-- Mybatis启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!-- mybatis分页插件 PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<!-- jdbc连接启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
默认情况下,插件MyBatis-Spring-Boot-Starter将进行如下配置:
- 自动检查 SpringBoot 的数据源配置并构建 DataSource 对象
- 通过 SqlSessionFactoryBean 使用数据源构建并注册 SqlSessionFactory 对象
- 从 SqlSessionFactory 中创建并注册一个 SqlSessionTemplate 实例,其实就是构建一个 SqlSession 对象
- 自动扫描使用了注解
@Mapper
的接口映射器,并将这些映射器与SqlSessionTemplate实例进行关联,同时将它们注册到Spring容器中
常用yaml配置
mybatis:
# 注册XML映射器,即mapper.xml文件位置。如果没有映射文件,请注释掉
mapper-locations: classpath:mapper/**.xml
# 配置Java类型别名包扫描路径。通过该属性可以给包中的类注册别名,注册后在 Mapper 对应的 XML 文件中可以直接使用类名,而不用使用全限定的类名(即 XML 中调用的时候可以不用包含全限包名)
type-aliases-package: com.test.springbootssm.entity
configuration:
# 指定MyBatis所用日志的具体实现(输出sql语句),未指定时将自动查找。
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 开启自动驼峰命名规则(camel case)映射。即从经典数据库列名 A_COLUMN(下划线命名)到经典 Java 属性名 aColumn(驼峰命名)的类似映射
map-underscore-to-camel-case: true
不太常用的yaml配置
mybatis:
## 不常用的配置
check-config-location: true # 是否检测MyBatis运行参数配置文件
config-location: classpath:mybatis/mybatis-config.xml # mybatis配置文件所在路径
type-handlers-package: test.springboot.handlers # 配置类型处理器包名
executor-type: SIMPLE # 指定执行器类型
configuration:
default-fetch-size: 20
default-statement-timeout: 30
lazy-loading-enabled: true # 开启延时加载开关
aggressive-lazy-loading: false # 将积极加载改为消极加载(即按需加载),默认值就是false
lazy-load-trigger-methods: "" # 指定触发延迟加载的方法
cache-enabled: true # 打开全局缓存开关(二级环境),默认值就是true
#MyBatis使用pageHelper分页
pagehelper:
helper-dialect: mysql # 配置使用哪种数据库语言,不配置的话pageHelper也会自动检测
reasonable: true # 启用查询合理化。如果pageNum<1,则会查询第一页;如果pageNum>pages,则会查询最后一页
# 支持通过Mapper接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。
support-methods-arguments: true
上述配置参数最终是通过mybatis-spring-boot-autoconfigure.jar加载和配置的。
Java方式配置MyBatis运行时参数
MyBatis的运行时参数除了可以在SpringBoot的配置文件中指定,还可以通过Java编码方式设置。实际上就是在Spring容器中注册一个实现了ConfigurationCustomizer接口的Bean。
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisConfig {
@Bean
ConfigurationCustomizer mybatisConfigurationCustomizer() {
return new ConfigurationCustomizer() {
@Override
public void customize(org.apache.ibatis.session.Configuration configuration) {
// 在SpringBoot中以Java编码方式配置MyBatis运行时参数
configuration.setMapUnderscoreToCamelCase(true);
configuration.addMappers("com.test.springboot.mapper");
}
};
}
}
Spring 集成 MyBatis
依赖
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${version.mybatis}</version>
</dependency>
<!-- 通用Mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>${version.mybatis.mapper}</version>
</dependency>
<!-- mybatis分页插件 PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${version.pagehelper}</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${version.mybatis.spring}</version>
</dependency>
<!-- spring事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
通过Java方式注册MyBatis核心组件
通过Java方式在Spring框架中注册MyBatis的核心组件Bean,并且配置声明式事务管理。
(1)在Spring中注册MyBatis的核心组件Bean:SqlSessionFactory,SqlSession,以及Spring的事务管理器。另外,在构建SqlSessionFactory时还可以注册MyBatis的xml映射器。
@Configuration
@EnableTransactionManagement
public class MyBatisSpringConfig implements TransactionManagementConfigurer {
@Autowired
private DataSource dataSource;
// 在Spring中注册SqlSessionFactory,在这里可以设置一下参数:
// 1.设置分页参数
// 2.配置MyBatis运行时参数
// 3.注册xml映射器
@Bean
public SqlSessionFactory sqlSessionFactory() {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
// 设置数据源
sqlSessionFactoryBean.setDataSource(dataSource);
// 设置映射POJO对象包名
// sqlSessionFactoryBean.setTypeAliasesPackage("org.chench.test.springboot.model");
// 分页插件
/*PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);*/
//添加插件
//sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
// 配置mybatis运行时参数
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
// 自动将数据库中的下划线转换为驼峰格式
configuration.setMapUnderscoreToCamelCase(true);
configuration.setDefaultFetchSize(100);
configuration.setDefaultStatementTimeout(30);
sqlSessionFactoryBean.setConfiguration(configuration);
// 在构建SqlSessionFactory时注册xml映射器
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 注入sqlSession对象
* @param sqlSessionFactory
* @return
*/
@Bean(value = "sqlSession")
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
// Spring事务管理器
@Bean(value = "transactionManager")
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
(2)注册MyBatis接口映射器 MyBatis 3支持2种映射器:xml映射器和接口映射器,其中xml映射器可以在构建SqlSessionFactory时进行注册。
@Configuration
@AutoConfigureAfter(MyBatisSpringConfig.class) //注意,由于MapperScannerConfigurer执行的比较早,所以必须有该注解
public class MyBatisMapperScannerConfig {
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
// 设置sqlSessionFactory名
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
// 设置接口映射器基础包名
mapperScannerConfigurer.setBasePackage("org.chench.test.springboot.mapper");
Properties properties = new Properties();
//properties.setProperty("mappers", "org.chench.test.springboot.mapper");
properties.setProperty("notEmpty", "false");
properties.setProperty("IDENTITY", "MYSQL");
mapperScannerConfigurer.setProperties(properties);
return mapperScannerConfigurer;
}
}
MyBatis支持2种类型的映射器:XML映射器和接口映射器,在这里以定义并使用接口映射器为例。
定义接口映射器
@Repository
public interface AccountMapper {
@Select("select * from account where id = #{id}")
public Account getAccountById(@Param("id") long id);
}
注意: 在这里可以使用Spring容器的注解@Repository
声明MyBatis的接口映射器为一个Bean组件,这样在使用接口映射器时可以直接注入这个接口映射器Bean进行使用。
通过xml方式注册MyBatis核心组件
applicationContext-mybaits.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--datasource-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="root"></property>
<property name="password" value="root"></property>
<property name="url" value="jdbc:mysql:///heima23"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
</bean>
<!--1、spring管理mybatis的核心对象-->
<!--sqlSessionfactory-->
<bean id="sqlSessionfactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="cn.test.domain"></property>
</bean>
<!--
spring自动的对执行包下的dao接口创建动态代理对象,存入容器
mapperScannerConfigurer:
1、spring容器启动的时候,加载执行包下的所有接口和映射文件
2、调用session的方法获取dao接口的动态代理对象
3、将对象存入容器
-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--dao接口所在的包-->
<property name="basePackage" value="cn.test.dao"></property>
</bean>
<!--2、配置声明式事务(xml)-->
<!-- i.事务管理器交给容器管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--ii.配置事务通知-->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" read-only="false"/>
<tx:method name="update*"/>
<tx:method name="delete*"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="*"></tx:method>
</tx:attributes>
</tx:advice>
<!--iii.配置事务的AOP-->
<aop:config>
<aop:pointcut id="pt" expression="execution(* cn.test.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"></aop:advisor>
</aop:config>
</beans>
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" >
<mapper namespace="com.test.springbootssm.mapper.UserMapper">
<!--注意包名不要错了-->
<select id="findById" parameterType="long" resultType="user">
select * from tb_user where id=#{id}
</select>
</mapper>
配置 mapper 接口扫描
方式一
给每一个Mapper接口添加@Mapper
注解,由Spring来扫描这些注解,完成Mapper接口的动态代理。
@Mapper
public interface UserMapper {
}
方式二
在启动类上添加扫描包注解(若Mapper接口文件位置统一存放,推荐此种方式)
这种方式的好处是,不用给每一个Mapper都添加注解。
@SpringBootApplication
@MapperScan("com.test.springbootssm.mapper")
public class Application {
public static void main(String[] args) {
// 启动代码
SpringApplication.run(Application.class, args);
}
}
Mybatis 实现 Dao 层
接口开发规范
- 接口全限定名与映射文件的namespace属性一致
- 接口的方法名与statement(子标签)的id属性一致
- 接口方法参数类型与statement(子标签)的parameterType属性一致
- 接口方法返回值类型与statement(子标签)的resultType属性一致
UserMapper接口
public interface UserMapper {
public List<User> findAll();
}
UserMapper.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">
<mapper namespace="com.test.mapper.UserMapper">
<select id="findAll" resultType="user">
select * from user
</select>
</mapper>
Mybatis 高级查询
查询结果封装
resultType
如果实体的属性名与数据库表中字段名(或查询字段别名)一致,将查询结果自动封装到实体类中。- 如果是单条数据,mybatis直接返回封装好数据的对象
- 如果是多条数据,mybatis会将封装好的多个对象放入list集合中
resutlMap
如果实体的属性名与数据库表中字段名不一致,使用ResutlMap实现手动映射封装到实体类中resutlMap的属性说明 :
<resultMap id="userResultMap" type="user"> <!-- id 此标签唯一标识`--> <!-- type 封装后的实体类型`--> <id column="uid" property="id"></id> <!-- 表中主键字段封装`--> <result column="username" property="username"></result> <!-- 表中普通字段封装`--> <!-- column 表中的字段名`--> <!-- property 实体的属性名`-->
xml映射文件:
<resultMap id="userResultMap" type="user"> <id column="uid" property="id"></id> <result column="username" property="username"></result> <result column="bir" property="birthday"></result> <result column="gender" property="sex"></result> <result column="address" property="address"></result> </resultMap> <select id="findAllResultMap" resultMap="userResultMap"> SELECT id AS uid,username AS NAME,birthday AS bir,sex AS gender ,address FROM USER </select>
多条件查询
- 方式1:将多个参数封装到一个 pojo对象中,进行对象的传递【推荐】
- 方式2:使用 @Param 注解声明参数【推荐】
缺点:参数过多时不太方便
- 方式3:xml里sql中使用 #{arg0} #{arg1}... 或 #{param1} #{param2}... 传递参数
缺点:可读性差
mapper接口:
// 方式1
public List<User> findByIdAndUsername3(User user);
// 方式2
public List<User> findByIdAndUsername2(@Param("id") Integer id,@Param("username") String username);
// 方式3
public List<User> findByIdAndUsername1(Integer id,String username);
xml文件:
<!-- 方式1 -->
<select id="findByIdAndUsername3" parameterType="user" resultType="user">
select * from user where id = #{id} and username = #{username}
</select>
<!-- 方式2(如果查询条件有多个参数 parameterType 可以省略) -->
<select id="findByIdAndUsername2" resultType="user">
select * from user where id = #{id} and username = #{username}
</select>
<!-- 方式3(如果查询条件有多个参数 parameterType 可以省略) -->
<select id="findByIdAndUsername1" resultType="user">
<!-- select * from user where id = #{arg0} and username = #{arg1} -->
select * from user where id = #{param1} and username = #{param2}
</select>
模糊查询
- 方式1:sql中使用
concat
函数进行模糊匹配拼接【推荐】 - 方式2:sql中使用
||
(字符串连接符)进行模糊匹配拼接【推荐】 方式3:java中添加模糊匹配
缺点:在java中出现了sql通配符,产生了耦合性问题,不太推荐使用
// java示例 List<User> list = userDao.findLikeUsername("%王%")
- 方式4:sql中拼接模糊匹配(%#{usenme}%)
缺点:只支持mysl5.5以上版本,oracle不支持该写法
- 方式5:sql中拼接模糊匹配(%${value}%)
${}
字符串拼接 ,如果接收简单数据类型 名称只能是:${value} 缺点:这种方式的底层使用的是编译对象statement做的查询,会出现sql注入问题,开发不能使用
xml文件:
<!-- 方式1 -->
<select id="findByUsername4" parameterType="string" resultType="user">
select * from user where username like concat('%', #{username}, '%');
</select>
<!-- 方式2 -->
<select id="findByUsername4" parameterType="string" resultType="user">
select * from user where username like ('%' || #{username} || '%');
</select>
<!-- 方式3 -->
<select id="findByUsername1" parameterType="string" resultType="user">
select * from user where username like #{username}
</select>
<!-- 方式4 -->
<select id="findByUsername1" parameterType="string" resultType="user">
select * from user where username like '%#{username}%'
</select>
<!-- 方式5-->
<select id="findByUsername3" parameterType="string" resultType="user">
select * from user where username like '%${value}%'
</select>
分页查询
需要添加 PageHelper 的依赖
<!-- mybatis分页插件 PageHelper(与SpringBoot集成版) -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
/**
* 分页查询所有数据
* */
@Override
public PageInfo<Brand> findPage(Integer page, Integer size) {
//调用PageHelper的startPage方法,设置当前页、每页条数
PageHelper.startPage(page, size);
//调用dao接口方法,查询所有的数据
// List<Brand> brandList = brandDao.selectAll();
Page<Brand> list = brandDao.selectAll();
//把查到的数据封装到PageInfo中,然后返回,PageInFo中包含了所有的数据,总条数等等
PageInfo<Brand> pageInfo = new PageInfo<>(list);
//返回即可
return pageInfo;
}
动态传递参数方式:#{} 与 ${}
(1)#{}:占位符
\#{} 是预编译处理,MyBatis在处理 #{} 时,它会将sql中的 #{} 替换为 ?,然后调用 PreparedStatement 的set方法来赋值,传入字符串后,会在值两边加上单引号。
(2)${}:拼接符
${} 是字符串替换,在处理是字符串替换,mybaits在处理时,它会将 sql 中的 { } 替换为变量的值,传入的数据不会在两边加上单引号。
注意:使用${ }会导致sql注入,不利于系统的安全性!
SQL注入:就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。常见的有匿名登录(在登录框输入恶意的字符串)、借助异常获取数据库信息等
#{} 与 ${} 的区别:
#{}:底层 PreparedStatement
1.sql与参数分离,不会出现sql注入问题
2.sql只需要编译一次
3.接收普通数据类型,命名:#{随便写}
4.接收引用数据类型,命名:#{属性名}
5.变量替换后,#{} 对应的变量自动加上单引号 ''
${}:底层 Statement
1.将sql与参数拼接在一起,会出现sql注入问题
2.每次执行sql语句都会编译一次
3.接收普通数据类型,命名:'${value}'
4.接收引用数据类型,命名: '${属性名}' ;注意:需要使用单引号‘${xxx}’
5.变量替换后,${} 对应的变量不会加上单引号 ''
必须使用@param注解的四种情况
1、方法有多个参数
原因:当不使用 @Param 注解时,mybatis 是不认识哪个参数叫什么名字的,尽管在接口中定义了参数的名称,mybatis仍然不认识。mybatis默认以接口中参数定义的顺序和SQL语句中的表达式进行映射。
例如:
mapper接口方法:
@Mapper
public interface UserMapper {
Integer insert(@Param("username") String username, @Param("address") String address);
}
对应的xml:
<insert id="insert" parameterType="org.javaboy.helloboot.bean.User">
insert into user (username, address) values (#{username}, #{address});
</insert>
2、方法参数要取别名
mapper接口方法:
@Mapper
public interface UserMapper {
Integer insert(@Param("name") String username, @Param("address") String address);
}
对应的xml:
<insert id="insert" parameterType="org.javaboy.helloboot.bean.User">
insert into user (username, address) values (#{name}, #{address});
</insert>
3、XML 中的 SQL 使用了 $ 拼接sql
$
会有注入的问题,但是有的时候不得不使用 $ 符号,例如要传入列名或者表名的时候,这个时候必须要添加 @Param 注解
mapper接口方法:
@Mapper
public interface UserMapper {
List<User> getAllUsers(@Param("order_by")String order_by);
List<User> findAll(@Param("tb_user")String tb_user);
}
对应xml:
<select id="getAllUsers" resultType="org.javaboy.helloboot.bean.User">
select * from user
<if test=" order_by !=null and order_by != ''">
order by ${order_by} desc <!-- order by 时,必须用 ${} 传入列名 -->
</if>
</select>
<select id="findAll" resultType="org.javaboy.helloboot.bean.User">
select * from ${tb_user}
</select>
4、动态 SQL 中使用了参数作为变量
如果在动态 SQL 中使用参数作为变量,那么也需要 @Param 注解,即使你只有一个参数。
例如:
@Mapper
public interface UserMapper {
List<User> getUserById(@Param("id")Integer id);
}
对应xml:
<select id="getUserById" resultType="org.javaboy.helloboot.bean.User">
select * from user
<if test="id != null">
where id=#{id}
</if>
</select>
通用 mapper
官方网站:https://mybatis.io/
github源码:https://github.com/abel533/Mapper
gitee源码:https://gitee.com/free/Mapper/wikis/Home
简介、依赖及常用配置
通用 Mapper 是简化 mybatis 操作的一个框架,是为了解决单表增删改查,基于 Mybatis 的插件。开发人员不需要建立 xml 映射文件编写 SQL,不需要在 dao 接口中增加方法,只需要写好实体类,用注解跟数据库的表和字段建立映射关系,然后在dao接口继承BaseMapper<T>
并指定泛型,就能支持相应的增删改查方法。在service实现类中,直接调用相关方法,就可以执行简单的单表CRUD。
SpringBoot官方并没有提供通用Mapper的启动器,不过通用Mapper的作者为自己的插件编写了启动器
注意:一旦引入了通用Mapper的启动器,会覆盖Mybatis官方启动器的功能,因此需要移除对官方Mybatis启动器的依赖。
(把mybatis相关的配置文件删除、把引导类上mapperScan注解删除、把mybatis的启动器删除)
<!-- 通用Mapper启动器(与SpringBoot集成版) -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
启动类上若有@MapperScan注解,则需修改为通用Mapper中自带的:
import tk.mybatis.spring.annotation.MapperScan;
修改mapper接口
public interface UserMapper extends BaseMapper<User> {
}
在实体类上添加注解@Table
,主键上添加@Id
@Data
@Table(name = "tb_user") // 指定要映射的数据库中的哪个表
public class User {
/** id */
@Id //表示该成员变量是主键id
private Long id;
/** 用户名 */
private String userName;
/** 密码 */
private String password;
}
常用API
根据主键id查询:selectByPrimaryKey(id);
添加数据:
- insertSelective(brand):添加数据,如果添加的数据中有为null的字段,则不进行更改。推荐,如果有特需,则用下面方式
- insert(brand):添加数据,不管要添加的数据是否为null,都进行更改,如果为null则将数据库中的该字段修改为null
根据id更新数据:
- updateSelective(brand):更新数据,如果添加的数据中有为null的字段,则不进行更改。推荐,如果有特需,则用下面方式
- update(brand):更新数据,不管要添加的数据是否为null,都进行更改,如果为null则将数据库中的该字段修改为null
注意:根据id更新数据,那么传入的 pojo 对象中的 id 字段一定要有值,否则它不知道修改哪条数据
根据id删除数据:deleteByPrimaryKey(id);