回顾:

1)动态sql
 1.if
   <if test="条件表达式">
      sql
   </if>
 2.choose when otherwise 多选一
   <choose>
      <when test="条件表达式">
         sql
      </when>
      <when test="条件表达式">
         sql
      </when>
      <otherwise>
         sql
      </otherwise>
   </choose>
 3.where 1.去除被where标签包裹的多余的and或者or关键字 2.适当添加where关键字
    举例:
      select * from t 
      <where>
        <if test="条件表达式">
          and sql
        </if>
        <if test="条件表达式">
          and sql
        </if>
        ......
      </where>
  4.set 1.去除被set标签包裹的多余的逗号 2.适当添加set关键字  
    update t
    <set>
       <if test="字段!=null">
           字段名称1=#{字段},
       </if>
       <if test="字段!=null">
           字段名称1=#{字段},
       </if>
       .......
    </set>
    where id=#{id}
  5.foreach 遍历集合和数组
       delete from t where id in 
       <foreach collection="参数名称" item="元素名称" open="(" close=")" separator=",">
          #{元素名称}
       </foreach>
2)mybatis多表查询
  前提:查询的数据对应的字段名称要唯一;
   一对一:
     <resultMap id="唯一标识" type="映射的实体类型" autoMapping="true">
         <id column="主键字段" property="pojo属性"/>
         <result column="普通字段" property="pojo普通属性"/>
         <association property="一对一对应的属性名称" javaType="从表实体类型"  autoMapping="true">
              <id column="主键字段" property="pojo属性"/>
              <result column="普通字段" property="pojo普通属性"/>
         </association>
     </resultMap>

   一对多:
        <resultMap id="唯一标识" type="映射的实体类型" autoMapping="true">
         <id column="主键字段" property="pojo属性"/>
         <result column="普通字段" property="pojo普通属性"/>
         <collection property="一对一对应的属性名称" javaType="从表实体类型"  ofType="从表实体类型" autoMapping="true">
              <id column="主键字段" property="pojo属性"/>
              <result column="普通字段" property="pojo普通属性"/>
         </collection>
     </resultMap>

   多对多:
    <resultMap id="唯一标识" type="映射的实体类型" autoMapping="true">
         <id column="主键字段" property="pojo属性"/>
         <result column="普通字段" property="pojo普通属性"/>
         <collection property="一对一对应的属性名称" javaType="从表实体类型"  ofType="从表实体类型" autoMapping="true">
              <id column="主键字段" property="pojo属性"/>
              <result column="普通字段" property="pojo普通属性"/>
              <association property="一对一对应的属性名称" javaType="从表实体类型"  autoMapping="true">
                  <id column="主键字段" property="pojo属性"/>
                  <result column="普通字段" property="pojo普通属性"/>
              </association>
         </collection>
     </resultMap>

1. 第五章 mybatis注解开发【掌握】

1.1.1. 1、概述

​ 上述我们已经学习mybatis的SQL映射文件可以使用xml的方式配置,但是我们发现不同的用户模块接口都对应一个映射文件,并且在映射文件中书写sql语句也比较麻烦。所以Mybatis为用户提供了快速的开发方式,因为有时候大量的XML配置文件的编写时非常繁琐的,因此Mybatis也提供了更加简便的基于注解(Annnotation)的配置方式。

注解配置的方式在很多情况下能够取代mybatis的映射文件,提高开发效率。

1.1.2. 2、注解实现CRUD

注:创建新工程演示环境:

2.0、CRUD相关注解

【注解】

@Insert:保存  
         Value:sql语句(和xml的配置方式一模一样)

@Update:更新 
         Value:sql语句

@Delete: 删除
         Value:sql语句

@Select: 查询
         Value:sql语句

@Options:可选配置(获取主键)
         userGeneratedKeys:开关,值为true表示可以获取主键  相当于select last_insert_id()
         keyProperty     :对象属性
         keyColumn       : 列名

【使用方式】

【第一步】将mybatis全局配置文件mybatis-config.xml中的mapper路径改为包扫描或者class路径;

​ 说明:因为没有了映射文件,所以我们这里采用加载接口方式,需要告知mybatis哪个接口的方法上的注解需要被执行。

    <mappers>
        <package name="com.heima.mapper"/>
    </mappers>

【第二步】编写接口和注解;

【第三步】测试

2.1、新增@Insert

步骤:

第一步:UserMapper接口中新增用户方法上面编写注解;
第二步:测试

实现:完成用户添加功能

1)配置核心配置文件

<?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">
<!--mybatis核心配置文件的跟标签-->
<configuration>

    <!--<properties>
       <property name="userName" value="root"/>
    </properties>-->
  <!-- resource属性表示引入外部的properties配置文件,使用${变量}获取配置文件中的数据-->
    <properties resource="jdbc.properties"/>

     <settings>
        <!--开启驼峰映射 table :user_name 映射成: pojo userName-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
     </settings>

    <!--<typeAliases>
        &lt;!&ndash;好处:可以随便去别名
             弊端:有多个pojo就需要配置多少个别名标签
        &ndash;&gt;
        <typeAlias type="com.pojo.User" alias="user"/>
    </typeAliases>-->
    <typeAliases>
        <!--别名是类的名称,并且首字母小写-->
        <package name="com.heima.pojo"/>
    </typeAliases>

    <!--environments多环境配置标签 default="development"表示默认使用development环境 -->
    <environments default="dev">
        <!--配置具体数据库数据源环境 id表示环境的唯一标识-->
        <environment id="dev">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

        <environment id="test">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--批量加载 sql映射文件-->
    <mappers>
        <!--方式1:1.映射文件名称随便定义 2.映射文件不用与接口存放到一块-->
        <!--<mapper resource="UserDao.xml"/>
        <mapper resource="OrderDao.xml"/>-->
        <!--<mapper class="com.heima.dao.UserDao"/>-->
        <!--包扫描接口,加载-->
        <package name="com.heima.dao"/>
    </mappers>
</configuration>

1)定义接口

public interface UserDao {

    /**
     * 添加用户信息
     * @param user
     */
    @Insert("insert into tb_user values(null,#{userName}," +
            "#{password},#{name},#{age},#{sex})")
    void addUser(User user);
}

2)测试

public class TestAll {

    @Test
    public void test1() throws IOException {
        //1)加载核心配置文件,构建会话工厂
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
        //2)获取会话对象 true表示事物自动提交
        SqlSession sqlSession = sessionFactory.openSession(true);
        //3)获取接口代理对象
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //4)调用接口方法
        User user = new User();
        user.setAge(18);
        user.setName("小王");
        user.setPassword("1234");
        user.setSex(1);
        user.setUserName("王小二");
        userDao.addUser(user);
    }
}

3)效果

1604885657516

2.2、删除

目标:使用注解@Delete删除id值为1的数据

步骤:

第一步:在根据id删除数据的方法上面编写注解@Delete;
第二步:测试

实现:删除id为1的用户

1)定义接口

    @Delete("delete from tb_user where id=#{uId}")
    void deleteById(@Param("uId") Long id);

2)测试

    @Test
    public void  test2(){
        UserDao userDao = MybatisUtils.getMapper(UserDao.class);
        try {
            userDao.deleteById(6L);
            MybatisUtils.commit();
        } catch (Exception e) {
            e.printStackTrace();
            MybatisUtils.rollback();
        }finally {
            MybatisUtils.close();
        }
    }

3)结果

1604885962662

2.3、修改

目标:修改id为1的用户的数据

步骤:

第一步:在根据id修改用户数据方法上面添加注解@Update,然后在其value属性值中编写具体的SQL;
第二步:测试

实现:

1)接口

    @Update("update tb_user set user_name=#{userName},password=#{password},name=#{name}," +
            "age=#{age},sex=#{sex} where id=#{id}")
    void updateUser(User user);

2)测试

    @Test
    public void  test3(){
        UserDao userDao = MybatisUtils.getMapper(UserDao.class);
        try {
            User user = new User();
            user.setId(11l);
            user.setAge(38);
            user.setName("老王");
            user.setPassword("998877690");
            user.setSex(1);
            user.setUserName("王小二");
            userDao.updateUser(user);
            MybatisUtils.commit();
        } catch (Exception e) {
            e.printStackTrace();
            MybatisUtils.rollback();
        }finally {
            MybatisUtils.close();
        }
    }

3)效果

1604886328651

2.4、查询@Select

目标:使用注解查询所有的用户数据

步骤:

第一步:在接口中查询所有的用户数据的方法上面添加注解:@Select,然后设置其value属性值为具体的SQL查询语句;
第二步:测试

实现:

1)接口

    @Select("select * from tb_user")
    List<User> findAll();

    @Select("select * from tb_user where id=#{uId}")
    User findById(@Param("uId") Long id);

2)测试

    @Test
    public void  test3(){
        UserDao userDao = MybatisUtils.getMapper(UserDao.class);
        try {
            User user = new User();
            user.setId(11l);
            user.setAge(38);
            user.setName("老王");
            user.setPassword("998877690");
            user.setSex(1);
            user.setUserName("王小二");
            userDao.updateUser(user);
            MybatisUtils.commit();
        } catch (Exception e) {
            e.printStackTrace();
            MybatisUtils.rollback();
        }finally {
            MybatisUtils.close();
        }
    }


    @Test
    public void test5(){
        UserDao userDao = MybatisUtils.getMapper(UserDao.class);
        User user = userDao.findById(1L);
        System.out.println(user);
    }

3)效果

1604886801448

1.1.3. 3、返回新增数据的id(自增主键回填)了解

问题:上面注解实现CRUD的测试中,数据新增成功,但是id值没有正常返回.

目标:使用注解完成数据新增,新增成功后返回数据的主键id值

步骤:

1、在新增数据注解 @Insert下面,添加@Options;
2、在@Options注解中,设置useGeneratedKeys值为true,keyProperty为id,keyColumn id;

实现:

1)接口

    /**
     * @Options:表示添加插入注解的额外属性
     * useGeneratedKeys = true:表示使用数据库的自增属性
     * keyColumn = "id":表示主键对应的字段名称
     * keyProperty = "id":pojo中属性名称
     * @param user
     */
    @Insert("insert into tb_user values(null,#{userName}," +
            "#{password},#{name},#{age},#{sex})")
    @Options(useGeneratedKeys = true,keyColumn = "id",keyProperty = "id")
    void addUser2(User user);

2)测试

    @Test
    public void test6(){
        UserDao userDao = MybatisUtils.getMapper(UserDao.class);
        User user = new User();
        user.setAge(20);
        user.setName("小刘");
        user.setPassword("123");
        user.setSex(0);
        user.setUserName("刘xx");
        System.out.println(user.getId());
        userDao.addUser2(user);
        System.out.println(user.getId());//12
        MybatisUtils.commit();

    }

3)效果

1604887417919

1.1.4. 4、注解实现别名映射

根据之前的学习,如果数据表的列名和pojo实体类的属性名不一致,会导致数据表的数据无法封装到实体类属性值中,对此我们又如下解决方案:

使用注解:@Results 实现映射:

@Results注解相当于之前映射文件中的ResultMap,该注解如下:

public @interface Results {
    Result[] value() default {};
}

我们发现value属于Result数组类型,而Result属于一个注解,注解的属性如下:

public @interface Result {
    //对应数据表的列
    String column() default "";
    //对应pojo类的属性
    String property() default "";
    //javaType:返回的对象类型
    Class<?> javaType() default void.class;
    //one: 一对一配置
    One one() default @One;
    //many: 一对多配置
    Many many() default @Many;
}

目标:使用注解的方式给取别名后的字段,映射到实体类中,并查询所有用户信息

​ 注意:为方便演示效果,可将之前核心配置文件中的开启驼峰自动映射设置为false。

实现:

1)接口

    @Select("select * from tb_user where id=#{uId}")
    @Results(id="userMap",value = {
            @Result(column = "id",property = "id",id=true),
            @Result(column = "user_name",property = "userName"),
            @Result(column = "password",property = "password")
    })
    User findById(@Param("uId") Long id);

    @Select("select * from tb_user")
    @ResultMap("userMap")
    List<User> findAll();

2)测试

前提:关闭核心配置文件中的驼峰映射;

     <settings>
        <!--开启驼峰映射 table :user_name 映射成: pojo userName-->
        <setting name="mapUnderscoreToCamelCase" value="false"/>
     </settings>
    @Test
    public void test5(){
        UserDao userDao = MybatisUtils.getMapper(UserDao.class);
        User user = userDao.findById(1L);
        System.out.println(user);
    }   

   @Test
    public void test7(){
        UserDao userDao = MybatisUtils.getMapper(UserDao.class);
        List<User> users = userDao.findAll();
        System.out.println(users);
    }

3)效果

1604889206811

小结:

1)增删改 xml中怎么写,在注解下就怎么写
 1.增加
   @Insert("insert into t values(.....)")
   @Options(useGenerateKeys=true,keyColumn="表中主键名称" keyProperty="pojo中属性")
 2.删除
   @Delete("delete from t where id=#{id}")
 3.修改
   @Update("update t set 字段1=#{xxx},.... where 条件")

2)查询 (1.驼峰映射 2.使用as关键字取别名 3.使用高级映射标签--resultMap或者注解@Results)
   @select("select * from t where 条件.....")
   @Results(id="唯一标识",value={
      @Result(column="表中主键字段名称",property="pojo中属性名称",id=true),
      @Result(column="表中主字段名称",property="pojo中属性名称"),
        ......
   })

   如何使用已经注解好了的映射规则?
   @ResultMap("唯一标识)

results matching ""

    No results matching ""