Mybatis 框架基本使用指南

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Mybatis 框架基本使用指南

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 映射文件

1571623550945.png

<?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 层

接口开发规范

  1. 接口全限定名与映射文件的namespace属性一致
  2. 接口的方法名与statement(子标签)的id属性一致
  3. 接口方法参数类型与statement(子标签)的parameterType属性一致
  4. 接口方法返回值类型与statement(子标签)的resultType属性一致

image-20211228223946788.png

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);

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2天前
|
SQL Java 数据库连接
MyBatis 框架入门理论与实践
MyBatis 框架入门理论与实践
31 6
|
2天前
|
SQL XML Java
程序员都要懂的SQL防注入Mybatis框架SQL防注入
程序员都要懂的SQL防注入Mybatis框架SQL防注入
22 0
|
2天前
|
SQL Java 数据库连接
MyBatis 优秀的持久层框架(一)
MyBatis 优秀的持久层框架
76 0
|
2天前
|
SQL 关系型数据库 Java
Mybatis-Flex框架初体验
Mybatis-Flex框架初体验
|
2天前
|
SQL 缓存 Java
持久层框架MyBatis
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的操作。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
26 1
|
2天前
|
SQL 缓存 Java
【框架】MyBatis 框架重点解析
【框架】MyBatis 框架重点解析
7 0
|
2天前
|
SQL Java 数据库连接
【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态SQL(下)
【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态
5 0
|
2天前
|
SQL Java 数据库连接
【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态SQL(上)
【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态SQL
4 0
|
2天前
|
SQL Java 数据库连接
【JavaEE】懒人的福音-MyBatis框架—[单表]增删改查等常规操作(下)
【JavaEE】懒人的福音-MyBatis框架—[单表]增删改查等常规操作
6 0
|
2天前
|
SQL 前端开发 Java
【JavaEE】懒人的福音-MyBatis框架—[单表]增删改查等常规操作(上)
【JavaEE】懒人的福音-MyBatis框架—[单表]增删改查等常规操作
8 0