Java学习 day46_mybatis

Mybatis

1. 介绍

Mybatis是一个ORM框架。

ORM:Object RelationShip Mapping 对象关系映射

其实Mybatis就是把数据库中的记录映射为Java对象,把Java对象映射为数据库中的记录 的这么一个框架。

Mybatis的中文官网

Mybatis英文官网

2. Mybatis入门案例

  • 导包

    <!-- myabtis-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    
    
    <!-- 数据库的驱动包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    
  • 配置

    • 配置一个Mybatis的主配置文件

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-config.dtd">
      <configuration>
          <!-- 环境配置,其实也就是数据库连接的配置-->
          <environments default="development">
              <environment id="development">
                  <transactionManager type="JDBC"/>
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql://localhost:3306/33th?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai&amp;useSSL=false"/>
                      <property name="username" value="root"/>
                      <property name="password" value="123456"/>
                  </dataSource>
              </environment>
          </environments>
          
          <!-- 映射器的配置-->
          <mappers>
          	<!-- 这个mapper配置文件是用来干嘛的呢?其实是用来放SQL语句的 -->    
              
              <!--<mapper resource="org/mybatis/example/BlogMapper.xml"/>-->
              
          </mappers>
          
      </configuration>
      
    • 配置映射器 ( Mapper)

      <?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">
      
      <!--
          我们后续所有的关于SQL语句的配置都需要写在这个mapper标签下
          namespace:命名空间
          select: 表示这里面需要放一个查询语句
          id: 是你这个sql语句的id值,在一个Mapper.xml文件里面,这个id不能重复
          resultType: 结果类型
          parameterType: 参数类型
      
      -->
      <mapper namespace="cskaoyan">
          <select id="selectAccountById" resultType="com.cskaoyan.Account" parameterType="int">
              select * from account where id = #{id}
          </select>
      
      </mapper>
      
  • 使用

    public class MybatisMain {
    
        static SqlSession sqlSession;
    
        static {
    
            // 构建一个SqlSessionFactory
            // 获取主配置文件流
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            } catch (IOException e) {
                e.printStackTrace();
            }
    //        InputStream resource = MybatisMain.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
    
            // 获取SqlSessionFactory 解析我们的 Mybatis-config.xml,进而解析Mapper.xml 获取到SQL语句,放到内存
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
    
            // 获取SqlSession 这个SQLSession可以帮助我们执行SQL语句
            sqlSession  = sqlSessionFactory.openSession();
    
        }
    
        public static void main(String[] args){
    
            // 执行SQL语句
            // 参数一:SQL语句的坐标
            // 参数二:传入的参数
            Account account = sqlSession.selectOne("cskaoyan.selectAccountById", 1);
    
            System.out.println("account:" + account);
    
        }
    
    }
    

类里面为何定义成员变量的时候,不用int, 用integer?
主要是为了和框架适配,避免出错
而且比如在数据库插入过程中自增的可以插入null,但是如果用int类型就不能插入,用Integet就可以


3. Mybatis的动态代理

Mybatis的动态代理其实就是可以帮助我们去动态的获取接口的实现类

@Test
public void testSelectAccountById(){

    // 获取到AccountMapper的代理对象
    AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);

    // 调用代理对象里面的方法
    Account account = accountMapper.selectAccountById(1);

    // 接口的全限定名称+ 方法的名称

    // 调用这个接口,实际上是需要调用
    //Account account = sqlSession.selectOne("cskaoyan.selectAccountById", id);

    System.out.println("account:" + account);

}

使用动态代理相关的条件:

  • Mapper.xml和mapper.java 在编译之后,要在同一级目录下(规范)
  • mapper.xml的namespace必须是mapper.java 的全限定名称
  • mapper.xml里面 的id值和方法名对应
  • mapper.xml的resultType和parameterType必须和方法的参数以及返回值对应

在这里插入图片描述

4. 配置

4.1 properties

这个配置是可以帮助我们引入properties配置文件,一般是用来引入数据源的配置

引入properties配置

在这里插入图片描述

取值:

在这里插入图片描述


4.2 settings

这个里面可以配置很多内容,大多数都是和Mybatis的性能有关的,例如缓存,懒加载等等

<!-- 这个里面配置的是Mybatis极为重要的一些配置,例如缓存,懒加载,日志等等-->
<settings>
    <!-- 配置日志的标准输出 -->
    <setting name="logImpl" value="STDOUT_LOGGING"/>

</settings>

4.3 typeAliases

这个里面是关于别名的配置的

  • 配置方式一:

    <!--
    类型别名 :我们可以给一些对象起别名
    -->
    <typeAliases>
        <!-- 给对象起别名
            1. 好处其实就是可以去简化我们的代码
            2. 不足是我们mapper.xml的可读性会变差
        -->
        <typeAlias type="com.cskaoyan.vo.Account" alias="account"/>
    
    </typeAliases>
    
  • 配置方式二:

    <typeAliases>
       
        <!-- 起别名的第二种方式 -->
        <package name="com.cskaoyan.vo"/>
    
    </typeAliases>
    

    在这里插入图片描述

4.4 environments

<!-- 环境配置,其实也就是数据库连接的配置-->
<environments default="development">

    <!--
    1. 开发环境 development  对应你的电脑
    2. 测试环境 test  测试服务器(其实就是把你的应用程序在一个测试服务器(Linux)上运行起来)
    3. BETA环境 beta  基本上和生产环境没什么区别了(数据库和生产环境是同一个),有很多公司没有这一步
    4. 生产环境 prod  正式环境(其实就是把你的应用程序在一个正式服务器上运行起来)

    大多数情况下,不同的环境要有不同的数据库的配置

    软件公司的成本:
        硬件成本 租-阿里云、腾讯云
        人力成本
    -->

    <environment id="development">
        <!--
        JDBC:通过数据库提供的connection来管理事务
        MANAGED:依赖于让容器来管理事务
               容器:Tomcat | Spring
        -->
        <transactionManager type="JDBC"/>
        <!--
        type:
            UNPOOLED 不使用数据库连接池,每一次访问数据库都会新建一个连接,使用完之后就关闭
            POOLED 使用数据库连接池,会新建一个连接池,每一次使用连接就是从池子里面获取连接
            JNDI:使用外部的数据源
        -->
        <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>


    </environment>

    <!--<environment id="prod">-->
        <!--<transactionManager type="JDBC"/>-->
        <!--<dataSource type="POOLED">-->
            <!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
            <!--<property name="url" value="jdbc:mysql://localhost:3306/33th?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai&amp;useSSL=false"/>-->
            <!--<property name="username" value="root"/>-->
            <!--<property name="password" value="123456"/>-->
        <!--</dataSource>-->
    <!--</environment>-->



</environments>

4.5 mapper

这个是一个很重要的配置,可以帮助我们去找到对应的mapper配置文件

<!-- 映射器的配置-->
<mappers>
    <!--<mapper resource="org/mybatis/example/BlogMapper.xml"/>-->

    <!--
    第一种:直接指定文件的位置 推荐
    -->
    <mapper resource="com/cskaoyan/mapper/AccountMapper.xml"/>
    <!--<mapper resource="com/cskaoyan/mapper/AccountMapper2.xml"/>-->

    <!--
    第二种:表示注册这个包下面的所有的mapper.xml文件
    -->
    <!--<package name="com.cskaoyan.mapper"/>-->

</mappers>

5. 输入映射

输入映射是什么意思呢?其实输入映射就是说Mybatis是如何传值的

5.1 一个简单参数

什么叫简单参数呢?其实就是基本类型和String

在这里插入图片描述


5.2 传入多个参数

mapper

// 传入多个简单参数
// 根据语文成绩区间查询学生信息
List<Student> selectStudentListByChinese(
        // 需要告诉Mybatis传入的参数的名字是什么
        @Param("minScore") Integer minScore,
        @Param("maxScore") Integer maxScore);

mapper.xml

<!-- parameterType 可以省略 resultType不能省略-->
<select id="selectStudentListByChinese" resultType="com.cskaoyan.vo.Student">
    select id,name,english,math,chinese,birthday,native_place as nativePlace
    from student
    where chinese between #{minScore} and #{maxScore}
</select>

我们在做增删改操作的时候,需要在执行完SQL语句之后,执行一句

sqlSession.commit();


5.3 传入对象

不加@Param注解

mapper

// 传入对象
// insert into student values (?,?,?,?,?,?)
int insertStudent(Student student);

mapper.xml

<!--插入 返回的int-->
<!-- #{ 成员变量的名字 }-->
<insert id="insertStudent">
    insert into student values (#{id},#{name},#{chinese},#{english},#{math},#{birthday},#{nativePlace})
</insert>

加上@Param注解

mapper

// 传入对象
// insert into student values (?,?,?,?,?,?)
int insertStudent2(@Param("student") Student student);

mapper.xml

<!--插入 返回的int-->
<!-- 通过 #{ 参数的注解.成员变量的名字} 来取值-->
<insert id="insertStudent2">
    insert into student values (#{student.id},#{student.name},#{student.chinese},#{student.english},#{student.math},#{student.birthday},#{student.nativePlace})
</insert>

5.4 通过Map来传值

不推荐使用通过map来传值

  • 不使用注解

    mapper

    // 传入map
    int deleteStudentByNameOrId(Map map);
    

    mapper.xml

    <delete id="deleteStudentByNameOrId">
        delete from student where id = #{id} or name = #{name}
    </delete>
    

    #{map里面key} 来取值

  • 使用@Param注解

    mapper

    // 传入map
    int deleteStudentByNameOrId2(@Param("map") Map map);
    

    mapper.xml

    <delete id="deleteStudentByNameOrId2">
        delete from student where id = #{map.id} or name = #{map.name}
    </delete>
    

5.5 通过位置来传值

不推荐使用位置来传值(因为容易出错)

mapper

// 通过位置来传值
List<Student> selectStudentListByScore(Integer chinese,Float math,Float english);

mapper.xml

<select id="selectStudentListByScore" resultType="com.cskaoyan.vo.Student">
    select id,name,english,math,chinese,birthday,native_place as nativePlace from student
    where chinese &gt; #{arg0} and math &gt; #{arg1} and english &gt; #{arg2}
</select>

我们通过按照位置来传值的时候,可以这样来取值

  • #{arg0}、#{arg1}、#{arg2} …

    在这里插入图片描述

  • #{param1} 、 #{param2}、 #{param3} …

    在这里插入图片描述


5.6 #{}和${} 的区别

面试会问

在这里插入图片描述

总结一下:

  • ${} 来取值是字符串拼接的方式
  • #{}来取值是预编译的方式

我们在以后的工作中,去取值的时候应该尽量使用 #{} 这种方式来取值,以为 字符串拼接的方式会导致 SQL注入的问题

那么我们${}这种取值的方式是不是一无是处呢?不是的

如果在一个SQL语句里面需要我们传入表名,列名的时候,我们需要使用 ${} 这种方式来取值

  • 1 取列名

    order by、 group by

    select * from student order by columnName desc 这种需要我们把列名传入进去

    mapper

    // 传入列名,根据列名来排序,取前三个
    List<Student> selectStudentListOrderByColumnNameDescLimit3(@Param("columnName") String columnName);
    

    mapper.xml

    <select id="selectStudentListOrderByColumnNameDescLimit3" resultType="com.cskaoyan.vo.Student">
        select id,name,english,math,chinese,birthday,native_place as nativePlace from student
        order by ${columnName} desc limit 3
    </select>
    

    我们发现,在使用 ${} 取列名的时候结果是正常的,但是通过#{}这种方式来取值的时候,order by这个关键字会失效。因为#{}是使用的预编译的方式,在预编译的时候,还没有把参数(列名)传递进去,所以不能够根据列名去排序

(我觉得可以理解为:在预编译的时候,需要去检查是否有某个表或者是某个列,所以预编译阶段必须获取到表名还有列名,而不可以在预编译后再传入取值)

  • 2 取表名

    在我们分表的时候,我们需要传入表名
    mapper

    // 传入表名
    List<Student> selectStudentListByTableName(@Param("tableName") String tableName);
    

    mapper.xml

    <select id="selectStudentListByTableName" resultType="com.cskaoyan.vo.Student">
        select id,name,english,math,chinese,birthday,native_place as nativePlace from ${tableName}
    </select>
    

说明:#{} 来取值和 ${} 来取值不冲突,可以共用在同一条SQL语句里面

<select id="selectStudentByIdAndTableName" resultType="com.cskaoyan.vo.Student">
    select id,name,english,math,chinese,birthday,native_place as nativePlace from ${tableName}
    where id = #{id}
</select>

先查看有没有$,如果有就进行字符串拼接,然后再预编译,插入#的值


6. 输出映射

输出映射其实说的就是我们Mybatis如何封装参数的

如何复制Module

  • 复制module文件

    在这里插入图片描述

  • 修改

复制完之后把module改为你想要的名字
修改文件夹的名字以及文件夹下面pom.xml文件里面 artfactId的值,使他们两保持一致

  • 删除
    删除target文件夹、删除.iml文件,反正只留下src和pom就可以

  • 导入module(打开project Structure)

    在这里插入图片描述

​ 选中pom.xml文件

在这里插入图片描述

接下来点击 应用和ok即可


6.1 简单类型

mapper

// 定义了一个方法
String selectNameById(@Param("id") Integer id);

mapper.xml

<select id="selectNameById" resultType="string">
    select name from account where id = #{id}
</select>

注意:我们的查询语句,一定要写 resultType,不能不写


6.2 JavaBean

mapper

// 返回对象
Account selectAccountById(@Param("id") Integer id);

// 当我们返回一个对象的集合或者是一个对象的数组的时候,我们只需要在接口的方法的返回值这里声明即可
// mapper.xml里面配置的resultType都是单个Bean的全限定名称
List<Account> selectAccountList();

Account[] selectAccoutArray();

mapper.xml

<select id="selectAccountById" resultType="com.cskaoyan.vo.Account">
    select * from account where id = #{id}
</select>

<select id="selectAccountList" resultType="com.cskaoyan.vo.Account">
    select * from account
</select>


<select id="selectAccoutArray" resultType="com.cskaoyan.vo.Account">
    select * from account
</select>

6.3 ResultMap

这个可以帮我们去做手动的映射。

例如我们之前,假如数据库里面的列名和Java对象里面的成员变量的名字不一致,我们通过别名来解决的这种问题。其实也可以通过resultMap来解决。当然ResultMap的使用,更多的是在多表查询这一块去做复杂映射的。

mapper

// 通过resultMap来做映射
Account2 selectAccountByNameWithResultMap(@Param("name")String name);

mapper.xml

<resultMap id="accountMap" type="com.cskaoyan.vo.Account2">
    <!--
    column: 表示列名
    property: 表示成员变量名
    jdbcType: 数据库字段的类型
    javaType: 成员变量的类型
        jdbcType和javaType可以省略  jdbcType="int" javaType="int"

    说明:假如我们成员变量的名字和数据库里面表的列名是一致的时候,并且类型也能对应的时候,那么Mybatis会给我们去做自动映射
    // 因为自动映射是隐式的,所以一般我们不建议大家使用自动映射
    -->
    <!--<result column="id" property="uid" />-->
    <!-- 对于主键这一列,可以使用id这个标签 主键这一列使用id标签主要是为了效率考虑-->
    <id column="id" property="uid"/>
    <result column="name" property="username"/>
    <result column="money" property="usermoney"/>
    <result column="role" property="userrole"/>

</resultMap>

<select id="selectAccountByNameWithResultMap" resultMap="accountMap">
    select id,name,money,role from account where name = #{name}
</select>

7. 插件

7.1 Mybatis的插件

在这里插入图片描述

  • 支持xml和接口文件来回跳转
  • 可以帮助我们自动生成@Param注解
  • 可以帮助我们自动生成<update等标签>

7.2 Lombok插件

lombok这个插件其实是一个可以帮助我们自动去生成getter、setter、toString等方法的一个插件

  • 导包

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>
    
  • 在idea中下载插件

    在这里插入图片描述

    因为Idea不能够识别lombok的注解的功能,所以我们需要在idea中下载lombok的插件,来识别lombok注解的功能

  • 使用

    在JavaBean上面增加注解

    @Setter@Getter@ToString@NoArgsConstructor@AllArgsConstructor@EqualsAndHashCode

    @Data

    这些注解其实是在编译的时候生效的。也就是说,Lombok是在代码编译的时候给我们自动去生成这些方法

我们应该使用Lombok吗?

我们可以确认的是,Lombok可以帮助我们提高开发效率。

使用不使用Lombok还是得看公司里面的同事用不用,假如公司里面都用,那就可以用。假如公司里面没人用,那你就别用


8. 动态SQL

动态SQL值的是Mybatis可以根据一些标签来动态的改变执行的SQL。动态SQL是Mybatis最重要的功能之一,其实就是给我们提供了一个标签库来供我们使用

8.1 where(重要)

where标签可以帮助我们去生成where关键字,但是还有别的功能

在这里插入图片描述

8.2 if(重要)

if标签可以帮助我们动态的根据条件拼接SQL语句

mapper

// 按条件查询账户
// 如果传入了金钱数量大于100,那我们查询余额大于100的账户
// 如果传入的金钱数量小于100,那我们查询余额小于100的账户
List<Account> selectAccountListByMoney(@Param("money") Integer money);

mapper.xml

<select id="selectAccountListByMoney" resultType="com.cskaoyan.vo.Account">
    select * from account where
    <!--
    if test="" 引号中是一个OGNL表达式,你可以认为就是一个Boolean表达式,里面的结果是一个true或者是false
    在OGNL表达式中,我们大于,小于有特殊的写法
        >   gt
        <   lt
        >=  gte
        <=  lte
    -->
    <if test="money gte 100">
        money &gt;= 100
    </if>
    <if test="money lt 100">
        money &lt; 100
    </if>
</select>

说明:where标签通常和if标签配合起来一起使用

<select id="selectAccountListBySelective" resultType="com.cskaoyan.vo.Account">
    select * from account
    <where>
        <if test="id != null">
            and id = #{id}
        </if>
        <if test="name != null">
            or name = #{name}
        </if>
        <if test="money != null">
            or money = #{money}
        </if>
        <if test="role != null">
            or role = #{role}
        </if>
    </where>

</select>

where标签的作用:

  • 可以帮助我们去自动添加一个where关键字
  • 当where标签里面没有sql片段的时候,不会帮助我们去拼装一个额外的where关键字
  • where标签可以帮助我们去除相邻的 and 或者是 or关键字

8.3 choose when otherwise

就相当于我们Java里面 if … else…

mapper

// 按条件查询账户
// 如果传入了金钱数量大于等于100,那我们查询余额大于等于100的账户
// 如果传入的金钱数量小于100,那我们查询余额小于100的账户
List<Account> selectAccountListByMoneyUseChooseWhen(@Param("money") Integer money);

mapper.xml

<select id="selectAccountListByMoneyUseChooseWhen" resultType="com.cskaoyan.vo.Account">
    select * from account
    <where>
        <choose>
            <when test="money gte 100">
                money &gt;= 100
            </when>
            <otherwise>
                money &lt; 100
            </otherwise>
        </choose>
    </where>
</select>

8.4 trim

trim这个标签可以帮助我们去修剪SQL语句,也就是可以动态的去增加指定的字符或者是去除指定的字符

<update id="updateAccountBySelective">
    update account
        <!--
        suffixOverrides 去除指定的后缀
        prefixOverrides 去除指定的前缀
        prefix          增加指定的前缀
        suffix          增加指定的后缀
        -->
    <trim suffixOverrides="," prefix="set">
        <if test="account.name != null">
            name = #{account.name},
        </if>
        <if test="account.money != null">
            money = #{account.money},
        </if>
        <if test="account.role != null">
            role = #{account.role},
        </if>
    </trim>
    <where>
        <if test="account.id != null">
            id = #{account.id}
        </if>
    </where>
</update>

8.5 SET(重要)

这个标签就和 的效果是一样的

<update id="updateAccountBySelectiveWithSet">
    update account
    <set>
        <if test="account.name != null">
            name = #{account.name},
        </if>
        <if test="account.money != null">
            money = #{account.money},
        </if>
        <if test="account.role != null">
            role = #{account.role},
        </if>
    </set>
    <where>
        <if test="account.id != null">
            id = #{account.id}
        </if>
    </where>
</update>

8.6 sql-include(重要)

我们可以在xml文件中把公共的代码抽离出来,放到sql标签下,然后通过include标签来引入

在这里插入图片描述


8.7 foreach(重要)

这个标签是可以帮助我们在sql里面去循环

有两个应用场景

  • in查询

    根据一个数组或者是一个集合去查询

    mapper

    // in 查询 select * from account where id in (1,2,3);
    List<Account> selectAccountListByIdArray(int[] ids);
    
    List<Account> selectAccountListByIdArrayWithParam(@Param("ids") int[] ids);
    
    // 通过idList去查询accountList
    List<Account> selectAccountListByIdList(List<Integer> ids);
    
    List<Account> selectAccountListByIdListWithParam(@Param("ids") List<Integer> ids);
    

    mapper.xml

    <select id="selectAccountListByIdArray" resultType="com.cskaoyan.vo.Account">
        select <include refid="all_column"/>
        from account
        <where>
            id in
            <!--
                collection: 指循环的对象
                separator: 值循环之后元素之间的分隔符
                item: 泛指循环之后里面的元素的名字
                open: 这个循环以什么开始
                close: 这个循环以什么元素结尾
                index: 指元素的下标
            -->
    
            <foreach collection="array" separator="," item="id" open="(" close=")">
                #{id}
            </foreach>
        </where>
        <!--select id,name,money,role from account where id in (#{id},#{id},#{id})-->
    
    </select>
    <select id="selectAccountListByIdArrayWithParam" resultType="com.cskaoyan.vo.Account">
        select <include refid="all_column"/>
        from account
        <where>
            id in
            <foreach collection="ids" separator="," item="id" open="(" close=")">
                #{id}
            </foreach>
        </where>
    </select>
    
    <select id="selectAccountListByIdList" resultType="com.cskaoyan.vo.Account">
        select <include refid="all_column"/>
        from account
        <where>
            id in
            <!--
            这个地方,list 或者是 collection都可以
            -->
            <foreach collection="collection" separator="," item="id" open="(" close=")">
                #{id}
            </foreach>
        </where>
    </select>
    
    <select id="selectAccountListByIdListWithParam" resultType="com.cskaoyan.vo.Account">
        select <include refid="all_column"/>
        from account
        <where>
            id in
            <foreach collection="ids" separator="," item="id" open="(" close=")">
                #{id}
            </foreach>
        </where>
    </select>
    
  • 批量插入

    mapper

    // 批量插入
    int insertAccountBatch(@Param("accountList") List<Account> accountList);
    

    mapper.xml

    <insert id="insertAccountBatch">
        <!--insert into account values (?,?,?,?),(?,?,?,?),(?,?,?,?)-->
        insert into account values
        <foreach collection="accountList" item="account" separator=",">
            (#{account.id},#{account.name},#{account.money},#{account.role})
        </foreach>
    </insert>
    

8.8 selectKey

selectKey这个标签可以帮助我们在我们执行SQL语句之前或者之后执行一条额外的sql语句

一般是用来获取自增的主键的id的

mapper

// 插入,并且获取自增的id
int insertAccount(Account account);

mapper.xml

<insert id="insertAccount">
    insert into account values (#{id},#{name},#{money},#{role})
    <!--
    resultType: <selectKey> 标签里面sql语句的返回类型
    order: AFTER| BEFORE 表示在主SQL之前或者是之后执行
    keyProperty: 表示<selectKey>这个标签里面查询到的结果封装到参数的哪个字段
    keyColumn: 这个表示我们需要获取<selectKey> 这个SQL语句的结果集的哪个字段
    -->
    <selectKey resultType="int" order="AFTER" keyProperty="id">
        select LAST_INSERT_ID()
    </selectKey>
</insert>

8.9 useGeneratedKeys

只能用来获取主键id

mapper

// 插入,并且获取自增的id
int insertAccountUseGeneratedKeys(@Param("account") Account account);

mapper.xml

<insert id="insertAccountUseGeneratedKeys" useGeneratedKeys="true" keyProperty="account.id">
    insert into account values (#{account.id},#{account.name},#{account.money},#{account.role})
</insert>
  • 注册(注册表)

    insert into user (?,?,?,?);

    select id from user where ? // 有了useGeneratedKeys这个标签之后,就可以帮助我们省去中间需要查询id的这一步

    获取到id

  • 注册后需要去给用户送优惠券(优惠券的表 userId id )

    去在优惠券这个表里面去插入一些优惠券的记录

    insert into xxx

9. 多表查询

9.1 一对一

分次查询
连接查询

9.2 一对多

分次查询
连接查询

9.3 多对多

分次查询
连接查询
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值