Mybatis映射文件深入

返回主键

应用场景
我们很多时候有这种需求,向数据库插入一条记录后,希望能立即拿到这条记录在数据库中的主键 值。
 

1.1 方式一

UserMapper接口

 /*
     添加用户:获取返回主键:方式一
     */
    public void saveUser(User user);

UserMapper.xml

  <!--添加用户:获取返回主键:方式一-->
    <!--
        useGeneratedKeys: 声明返回主键
        keyProperty:把返回主键的值,封装到实体中的那个属性上
    -->
    <insert id="saveUser" parameterType="user" useGeneratedKeys="true" keyProperty="id">
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
    </insert>

测试

/*
        添加用户:返回主键方式一
     */
    @Test
    public void test8() throws IOException {

        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = new User();
        user.setUsername("某冰冰");
        user.setBirthday(new Date());
        user.setAddress("北京昌平");
        user.setSex("女");

        System.out.println(user);
        mapper.saveUser(user);
        System.out.println(user);

        sqlSession.commit();
        sqlSession.close();

    }

1.2 方式二

UserMapper接口

 /*
    添加用户:获取返回主键:方式二
    */
    public void saveUser2(User user);

UserMapper.xml

  <!--添加用户:获取返回主键:方式二-->

    <insert id="saveUser2" parameterType="user" >

        <!--
            selectKey : 适用范围更广,支持所有类型的数据库
                order="AFTER"  : 设置在sql语句执行前(后),执行此语句
                keyColumn="id" : 指定主键对应列名
                keyProperty="id":把返回主键的值,封装到实体中的那个属性上
                 resultType="int":指定主键类型
        -->
        <selectKey order="AFTER" keyColumn="id" keyProperty="id" resultType="int">
            SELECT LAST_INSERT_ID();
        </selectKey>
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
    </insert>

测试

/*
       添加用户:返回主键方式二
    */
    @Test
    public void test9() throws IOException {

        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = new User();
        user.setUsername("汤唯");
        user.setBirthday(new Date());
        user.setAddress("北京昌平");
        user.setSex("女");

        System.out.println(user);
        mapper.saveUser2(user);
        System.out.println(user);

        sqlSession.commit();
        sqlSession.close();

    }

 

2. 动态SQL

应用场景
当我们要根据不同的条件,来执行不同的sql语句的时候,需要用到动态sql
 

2.1 动态 SQL <if>

需求
根据idusername查询,但是不确定两个都有值。
 

aUserMapper接口

  /*
      动态sql的if标签:多条件查询
    */
    public List<User> findByIdAndUsernameIf(User user);

bUserMapper.xml映射

<!-- 动态sql之if : 多条件查询-->
    <select id="findByIdAndUsernameIf" parameterType="user" resultType="com.lagou.domain.User">
        select * from user
        <!-- test里面写的就是表达式
            <where>: 相当于where 1= 1,但是如果没有条件的话,不会拼接上where关键字
        -->
        <where>
           <if test="id != null">
                and id = #{id}
           </if>
           <if test="username !=null">
                and username = #{username}
           </if>
        </where>

    </select>

c)测试代码

/*
     动态sql之if: 多条件查询
  */
    @Test
    public void test10() throws IOException {

        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = new User();
        user.setId(11);
        user.setUsername("汤唯");

        List<User> users = mapper.findByIdAndUsernameIf(user);
        for (User user1 : users) {
            System.out.println(user1);
        }

        sqlSession.close();

    }

2.2 动态 SQL <set>

需求
动态更新user表数据,如果该属性有值就更新,没有值不做处理。
 

aUserMapper接口

 /*
     动态sql的set标签:动态更新
   */
    public void updateIf(User user);

bUserMapper.xml映射

 

 

<!--动态sql之set : 动态更新-->
    <update id="updateIf" parameterType="user">
        update user
        <!--<set> : 在更新的时候,会自动添加set关键字,还会去掉最后一个条件的逗号 -->
        <set>
            <if test="username != null">
                username = #{username},
            </if>
            <if test="birthday != null">
                birthday = #{birthday},
            </if>
            <if test="sex != null">
                sex = #{sex},
            </if>
            <if test="address != null">
                address = #{address},
            </if>

        </set>
            where id = #{id}
    </update>


    <sql id="selectUser">
        select * from user
    </sql>

c)测试代码

 /*
        动态sql之set: 动态更新
    */
    @Test
    public void test11() throws IOException {

        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = new User();
        user.setId(1);
        user.setUsername("子慕最帅");
        user.setAddress("北京海淀区拉勾网");

        mapper.updateIf(user);

        sqlSession.commit();

        sqlSession.close();

    }

2.3 动态 SQL <foreach>

foreach主要是用来做数据的循环遍历

例如: select  *  from user where id in (1,2,3) 在这样的语句中,传入的参数部分必须依靠 foreach遍历才能实现。
 
<foreach>标签用于遍历集合,它的属性:
• collection:代表要遍历的集合元素
• open:代表语句的开始部分
• close:代表结束部分
• item:代表遍历集合的每个元素,生成的变量名
• sperator:代表分隔符
 

2.3.1 集合

UserMapper接口

 /*
        动态sql的foreach标签:多值查询:集合
    */
    public List<User> findByList(List<Integer> ids);

UserMaper.xml映射

<!--动态sql的foreach标签:多值查询:根据多个id值查询用户-->
    <select id="findByList" parameterType="list" resultType="user">
        <include refid="selectUser"/>
        <where>
            <!--
                collection : 代表要遍历的集合元素,通常写collection或者list
                open : 代表语句的开始部分
                close : 代表语句的结束部分
                item : 代表遍历结合中的每个元素,生成的变量名
                separator: 分隔符
             -->
            <foreach collection="collection" open="id in (" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>

    </select>

测试代码

 /*
     动态sql之foreach: 多值查询
 */
    @Test
    public void test12() throws IOException {

        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(6);
        ids.add(2);

        List<User> users = mapper.findByList(ids);
        for (User user : users) {
            System.out.println(user);
        }


        sqlSession.close();

    }

2.3.2 数组

UserMapper接口

 /*
       动态sql的foreach标签:多值查询:数组
   */
    public List<User> findByArray(Integer[] ids);

UserMaper.xml映射

 <!--动态sql的foreach标签:多值查询:根据多个id值查询用户-->
    <select id="findByArray" parameterType="int" resultType="user">
        <include refid="selectUser"/>
        <where>
            <!--
                collection : 代表要遍历的集合元素,通常写collection或者list
                open : 代表语句的开始部分
                close : 代表语句的结束部分
                item : 代表遍历结合中的每个元素,生成的变量名
                separator: 分隔符
             -->
            <foreach collection="array" open="id in (" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>

    </select>

测试代码

/*
   动态sql之foreach: 多值查询 :数组
*/
    @Test
    public void test13() throws IOException {

        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Integer[] ids = {2,6,9};

        List<User> byArray = mapper.findByArray(ids);
        for (User user : byArray) {
            System.out.println(user);
        }


        sqlSession.close();

    }

 

3. SQL片段

应用场景
映射文件中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
 

 

4 知识小结

MyBatis映射文件配置
 
<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<selectKey>:返回主键
<where>where条件
<if>if判断
<foreach>for循环
<set>set设置
<sql>sql片段抽取
 
节选自拉钩教育JAVA集训营系列课程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值