• JavaWeb之Mybatis进阶


    MyBatis三种开发方式

    接口代理的开发方式(重点)

    使用注解的开发方式(重点)

    传统DAO实现类的开发方式(目前淘汰,因为分布式的使用)

    mybatis中的sql

    参数占位符:

    #{}:先使用?占位,执行SQL时将具体值赋值给?

    ${}:拼SQL,会存在SQL注入问题

    parameterType:

    用于设置参数类型,该参数可以省略

    SQL语句中特殊字符处理:

    转义字符

    :CD提示
    <select id="selectById" resultType="User">
            select * from user where id = #{id};
            
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    事务

    查询数据可以直接查不会出错

    但是增删改必须要开启事务,因为在mybaits中默认不会自动提交

    事务两种开启方式:

    在sqlSessionFactory.openSession(true);

    sqlSession.commit()

    增删改查

    删除

    1.在接口中添加方法

    2.在接口映射文件UserMapper.xml配置SQL语句

    3.执行方法

    1.在接口中添加方法
    void deleteById(int id);

    2.在接口映射文件UserMapper.xml配置SQL语句
    delete from user where id = #{id};

    3.执行方法

    @Test
        public void test3() throws IOException {
    
            //因为要使用mybatis,所以要把配置文件mybatis-config.xml加载过来(在测试案例访问resoureces的资源,可以直接访问文件)
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            //将这个文件转为流的形式,这个流会自动关闭,然后使用这个流获取连接,首先获得连接的builder对象
            //这个builder需要new
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //到这步获得了连接的工厂类,接下来通过工厂类获得连接
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //成功获得连接,使用这个连接将接口使用动态代理生成对象
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);//因为是动态代理所以用.class
            //用代理对象调用接口中的方法
            mapper.deleteById(3);
            //提示成功,但是实际上确删除不成功,这是因为mybatis的事务
            //在进行增删改的操作,要提交事务,mybatis事务的自动提交默认时关闭的
            //有两种设置事务的方法,1.在sqlSessionFactory.openSession(true);2.sqlSession.commit()
            sqlSession.commit();
    
            //关闭资源,只需要关闭sqlSession
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    修改

    int update(User user);
    
    
    • 1
    • 2
    <update id="update">
            UPDATE user
            SET username = #{username},
                birthday =#{birthday},
                sex=#{sex},
                address=#{address}
            WHERE id = #{id};
        update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @Test
        public void test4() throws IOException {
    
            //因为要使用mybatis,所以要把配置文件mybatis-config.xml加载过来(在测试案例访问resoureces的资源,可以直接访问文件)
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            //将这个文件转为流的形式,这个流会自动关闭,然后使用这个流获取连接,首先获得连接的builder对象
            //这个builder需要new
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //到这步获得了连接的工厂类,接下来通过工厂类获得连接
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //成功获得连接,使用这个连接将接口使用动态代理生成对象
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);//因为是动态代理所以用.class
            //用代理对象调用接口中的方法
            User user = new User(1, "cat", Date.valueOf("2022-01-11"), "男", "地球");
            mapper.update(user);
            //提示成功,但是实际上确删除不成功,这是因为mybatis的事务
            //在进行增删改的操作,要提交事务,mybatis事务的自动提交默认时关闭的
            //有两种设置事务的方法,1.在sqlSessionFactory.openSession(true);2.sqlSession.commit()
            sqlSession.commit();
    
            //关闭资源,只需要关闭sqlSession
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    插入

    插入并获取新的主键值

    int add(User user);
    
    • 1
    
        <insert id="add" useGeneratedKeys="true" keyProperty="id">
            INSERT INTO user
            VALUES (null, #{username}, #{birthday}, #{sex}, #{address});
        insert>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    @Test
        public void test5() throws IOException {
    
            //因为要使用mybatis,所以要把配置文件mybatis-config.xml加载过来(在测试案例访问resoureces的资源,可以直接访问文件)
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            //将这个文件转为流的形式,这个流会自动关闭,然后使用这个流获取连接,首先获得连接的builder对象
            //这个builder需要new
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //到这步获得了连接的工厂类,接下来通过工厂类获得连接
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //成功获得连接,使用这个连接将接口使用动态代理生成对象
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);//因为是动态代理所以用.class
            //用代理对象调用接口中的方法
            User user = new User(10086, "dog", Date.valueOf("1980-10-24"), "男", "地球");
            System.out.println(user.getId());
            int row = mapper.add(user);
            System.out.println(row);
            System.out.println(user.getId());
            //提示成功,但是实际上确删除不成功,这是因为mybatis的事务
            //在进行增删改的操作,要提交事务,mybatis事务的自动提交默认时关闭的
            //有两种设置事务的方法,1.在sqlSessionFactory.openSession(true);2.sqlSession.commit()
            sqlSession.commit();
    
            //关闭资源,只需要关闭sqlSession
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    多参数处理

    当只有一个参数时,在xml中编写sql时可以使用传入的参数名,但是多参数的时候不能直接用参数名

    select

    	//多参数
        //报错Available parameters are [arg1, arg0, param1, param2]
        //方案1,散装,用@Param给咱们的参数起个名字
        //List selectByCondition(@Param("username") String username, @Param("sex") String sex);
        //方案2,使用对象封装
        //List selectByCondition(User user);
        //方案3,使用Map集合封装
        List<User> selectByCondition(Map<String,String> map);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    <select id="selectByCondition" resultType="com.jwl.pojo.User">
            
            select * from user where username like #{username} and sex = #{sex};
    
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    动态sql

    sql语句并不是固定不变的,要根据条件编写合适的sql语句

    if标签

    select if标签 where标签

    //动态sql
        List<User> selectByIf(@Param("username") String username, @Param("sex") String sex);
    
    • 1
    • 2
    <select id="selectByIf" resultType="com.jwl.pojo.User">
            
    
            select * from user
            <where>
                <if test="username!=null and username != ''">
                    username = #{username}
                if>
    
                <if test="sex != null and sex !=''">
                    and sex = #{sex};
                if>
            where>
    
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    update set标签

    //这样new一个user,再通过set方法传入数据,如果没传入数据的字段就会是null,会把数据库中不准备修改的数据变为Null
        //为了避免这种情况,也要加入if标签来判断
        int updateByIf(User user);
    
    • 1
    • 2
    • 3
    <update id="updateByIf">
            
            UPDATE user
            <set>
                <if test="username !=null and username != ''">
                    username = #{username},
                if>
    
                <if test="birthday !=null">
                    birthday = #{birthday},
                if>
                <if test="sex !=null and sex != ''">
                    sex = #{sex},
                if>
                <if test="address !=null and address != ''">
                    address = #{address},
                if>
            set>
    
            WHERE id = #{id};
        update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    批量删除 foreach标签

    void deleteByIds(int[] ids);
    
    • 1
    
        <delete id="deleteByIds">
            delete from user where id in
            
            <foreach collection="array" item="id" open="(" close=")" separator=",">
                #{id}
            foreach>
        delete>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    choose标签
    跟java的switch类似

    List<User> selectBySex(int sex);
    
    • 1
    <select id="selectBySex" resultType="com.jwl.pojo.User">
            select * from user
            <where>
                <choose>
                    <when test="sex==1">
                        sex = '男';
                    when>
                    <when test="sex==0">
                        sex = '女';
                    when>
                    <otherwise>
                        sex = '女';
                    otherwise>
                choose>
            where>
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    sql标签

    <select id="selectAll" resultType="User">
            select
            <include refid="useAll"/>
            from user;
        select>
    
        
        <sql id="useAll">
            id
            ,username,birthday,sex,address
        sql>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    ResultMap

    在上述的例子中都是数据库字段名和实体类名相同,查询方便

    但是很多情况下数据库字段名和实体类名不同

    因为数据库字段名和实体类的属性名不一致,查到的数据封装不到Order中,
    解决方法有三种

    1.取别名,在写sql时,取对应实体类的别名

    2.在mybaits配置文件中的标签中设置自动将数据库和实体类名称转换< setting name=“mapUnderscoreToCamelCase” value=“true”/>,默认为关闭

    3.使用resultMap

    <settings>
            
            <setting name="logImpl" value="STDOUT_LOGGING"/>
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        settings>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    <resultMap id="OrderMap" type="Order">
            <id column="o_id" property="oId"/>
            <result column="user_id" property="userId"/>
            <result column="create_time" property="createtime"/>
        resultMap>
        <select id="selectAllBy" resultMap="OrderMap">
            select * from tb_order;
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    最后

    如果你对本文有疑问,你可以在文章下方对我留言,敬请指正,对于每个留言我都会认真查看。

  • 相关阅读:
    如何高效开发一款微信小程序
    Weblogic弱口令getshell
    stm32通过AT指令与esp8622通信
    [论文工具] LaTeX论文撰写常见用法及实战技巧归纳(持续更新)
    新闻列表页:通过WEUI框架实战我深入理解了块级作用域与点击事件
    HJ2 计算某字符出现次数
    flutter StreamSubscription 订阅者 stream
    Python手册
    C++模拟OpenGL库——图形光栅化理论及实现(三):三角形绘制
    Java-泛型
  • 原文地址:https://blog.csdn.net/weixin_47543906/article/details/128042693