zoukankan      html  css  js  c++  java
  • mybatis入门(三):mybatis的基础特性

    mybatis的知识点:

      1.mybatis和hibernate本质区别和应用场景
        hibernate:是一个标准的ORM框架(Ojbect relation mapper对象关系映射).入门门槛较高的,不需要程序员写sql,
        sql语句自动生成了。对sql语句进行优化,修改比较困难。
        应用场景:
          适用于需求变化不多的中小型项目.比如后台管理,erp,orm,oa..

        mybatis:专注于sql本身,需要程序员自己编写sql语句,sql修改,优化比较方便,mybatis是一个不完全的ORM框架,
        虽然程序员自己写sql,mybatis也可以实现映射(输入映射,输出映射)
        应用场景:
        适用于需求变化较多的项目,比如:互联网项目

      2.sqlSession:是一个面向用户(程序员)的接口
        sqlSession中提供了很多操作数据的方法.如:selectOne(返回单个对象),selectList(返回单个或多个对象)
        sqlSession是线程不安全的,在sqlSession实现了除了接口有的方法(操作数据库的方法)还有数据域属性
        sqlSession最佳应用场合在方法体内,定义成局部变量使用。

      3.总结原始dao开发的问题(User.xml)
        1.dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量
        2.调用sqlsession方法是将statement的id硬编码了 3.调用sqlsession方法是传入的变量,由于sqlsession方法使用泛型,即使变量传入错误,在编译阶段也不报错。

        不利于程序员开发

      4.mapper代理方法(程序员只需要mapper接口(相当于dao接口))
        1.还需要编写mapper.xml映射文件(同时切记要在sqlMapConfig.xml里面加上这个)

        2.程序员只需要开发mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类的代理对象
          开发规范:
            1.在mapper.xml中namespace等于mapper接口地址
              <!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离-->
              <!--注意:使用mapper代理方法开发,namespace有特殊重要的作用-->
              <mapper namespace="cn.wj.test.mybatis.mapper.UserMapper">
            2.mapper.java接口中的方法名和mapper.xml中statement的id一致 3.mapper.java接口中的方法输入参数类型和mapper.xml中parameterType指定的类型一致         4.mapper.java接口中方法的返回值的类型和mapper.xml中statement中resultType的类型一致
            例如:
            mapper.java接口方法:
            //根据id查询查询用户(此时这个方法名要和statement的id保持一致)

              public User findUserById(int id) throws Exception;

            UserMapper.xml:

    1 <select id="findUserById" parameterType="int" resultType="cn.wj.test.mybatis.pojo.User">
    2   select * from user where id = #{id}
    3 </select>

          在sqlMapper.xml添加UserMapper.xml映射
          总结:以上的开发规范主要是对下边代码进行统一的生成

        

        3.代理对象内部调用selectOne或selectList
          如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库
          如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库

        

        4.mapper接口方法参数只能有一个是否影响系统开发
          mapper接口方法参数只有一个,系统是否不利于扩展维护?
          答:系统框架中,dao层的代码是被业务员公用的
          即使mapper接口中只有一个参数,也可以使用包装类型的pojo满足不同的业务方法的需求 注意:持久层方法的参数可以是包装类型,

          map...,service方法中建议不要使用包装类型(不利于业务层的可扩展)

        

        5.sqlMapConfig.xml中配置文件的内容和顺序如下:
          properties(属性)
          settings(全局配置参数)
          typeAliases(类型别名)
          typeHandlers(类型处理器)
          objectFactory(对象工厂)
          plugins(插件)

          1.properties(属性)
          需求: 将数据库连接参数单独配置在db.properties中,只需要在sqlMapConfig.xml中加载dp.properties的属性值,

          在sqlMapperConfig.xml就不需要对数据库的连接参数进行编码了
          properties特性:
          注意:mybatis将按照下面的顺序加载属性
            1.在properties元素体内定义的属性首先挥别读取
            2.然后会读取properties元素中resource或url加载的属性,他会覆盖已读取的同名属性
            3.最后读取parameterType传递的属性,他会覆盖已读取的同名属性
            建议:
            不要在properties元素体内添加任何属性值,只将属性值定义在prperties中,在properties文件中属性名一定有一定的特性:如xxxx.xxx.xx

          例子:

          1.db.properties(这个里面就是属性名就是比较特殊,例如jdbc.driver,jdbc。url)

    1       jdbc.driver=com.mysql.jdbc.Driver
    2           jdbc.url=jdbc:mysql://localhost:3306/mybatisData?characterEncoding=utf-8
    3           jdbc.username=root
    4           jdbc.password=root

          sqlMapConfig文件中: 

     1         <!-- 加载属性文件 -->
     2                 <properties resource="db.properties">
     3                     <!--properties中可以配置一些属性名和属性值-->
     4                     <!--<property name="" value=""/>-->
     5                 </properties>
     6                 <dataSource type="POOLED">
     7                     <property name="driver" value="${jdbc.driver}"/>
     8                     <property name="url" value="${jdbc.url}"/>
     9                     <property name="username" value="${jdbc.username}"/>
    10                     <property name="password" value="${jdbc.password}"/>
    11                 </dataSource>
    12                 (其中加载这个文件properties,则底下dataSource里面的参数则是property)

        2.settings(配置)

        mybatis全局配置参数,全局参数将会影响mybatis运行行为

        3.typeAliases(别名)

          需求:
          在mapper.xml中定义了很多的statement,statement需要指定参数的类型,需要resultMap指定输出结果的映射类型
          如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义的一些别名,在mapper.xml通过别名定义,方便开发。

     1                <typeAliases>
     2                             <!--
     3                                 针对单个别名的定义
     4                                 type:类型的路径
     5                                 alias:别名
     6                             -->
     7                             <typeAlias type="cn.wj.test.mybatis.pojo.User" alias="user"/>
     8                           <!--
     9                             批量定义别名(较为常用)
    10                             指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大小写都可)
    11                             -->
    12                             <package name="cn.wj.test.mybatis.pojo"/>
    13                         </typeAliases>
    14                         引用别名:
    15                         <select id="findUserById" parameterType="int"        resultType="user">
    16                             select * from user where id = #{id}
    17                         </select>

        4.typeHandlers(类型处理器)

          mybatis中通过typeHandlers完成jdbc类型和java类型的转换。
          通常情况下,mybatis提供的类型处理器满足日常的需要,不需要我们自定义转换

        5.mappers(mapper的映射配置)

          1.通过resource来加载单个的映射文件
            <!--通过resource方法一次加载一个映射文件-->
            <mapper resource="mapper/UserMapper.xml"/>

          

          2.通过mapper接口加载映射文件
            <!--
              通过mapper接口加载映射文件
              遵循一些规范:需要将mapper接口类名和mapper.xml映射文件保持一致,且在一个目录中
              上边的规范是mapper接口加载映射文件
            -->
            <mapper class="cn.wj.test.mybatis.mapper.UserMapper"/>

          3.批量添加mapper(包名,推荐使用)

            <!--
              批量加载mapper
              指定mapper接口的包名,mybatis自动扫描包下面所有的mapper接口进行加载
              上边的规范是mapper接口加载映射文件
            -->
            <package name="cn.wj.test.mybatis.mapper"/>

        6.输入映射

          通过parameterType指定输入参数的类型,类型可以是简单类型,hashmap,poji的包装对象

          需求:
            完成用户信息的综合查询,需要传入的查询条件很复杂(可能包括用户信息,其他信息,比如商品,订单)
            针对

            UserMapper.xml

    1               <!--
    2                             用户的综合查询
    3                             #{userCustom.sex}:取出包装类型的值
    4                             ${userCustom.username}:取出pojo包装类型对象的名称
    5                         -->
    6                             <select id="findUserList"                    parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
    7                                 select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'
    8                             </select>

            UserMapper.java

      

     1             //用户信息的综合查询
     2                     public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
     3                     
     4                       测试代码:
     5                         @Test
     6                         public void testfindUserList()throws Exception{
     7                             SqlSession sqlSession = sqlSessionFactory.openSession();
     8                             //创建UserMapper对象,mybatis自动生成mapper对象
     9                             UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    10                             //调用userMapper的方法
    11                             UserCustom userCustom = new UserCustom();
    12                             userCustom.setSex("m");
    13                             userCustom.setUsername("123");
    14                             UserQueryVo userQueryVo = new UserQueryVo();
    15                             userQueryVo.setUserCustom(userCustom);
    16                             List<UserCustom> userList = userMapper.findUserList(userQueryVo);
    17                             System.out.println(userList);
    18                         }

        7.输出映射

          1.resultType:
            使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名保持一致,该列才可以映射成功。
            如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象
            只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
              输出简单类型:切记:输出简单类型只有一行一列的数据

          2.resultMap:
            mybatis中使用resultMap完成高级输出结果映射
            resultMap使用方法:
            如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap列名和pojo属性名做一个映射关系

            1.定义resultMap

            UserMapper.xml

     1                <!--
     2                             定义resultMap
     3                             将select id id_,username username_和User中的属性作为一个映射关系
     4                             type:resultMap最终映射的java对象类型,可以使用别名
     5                             id:对resultMap的唯一标识
     6                         -->
     7                         <resultMap id="userResultMap" type="cn.wj.test.mybatis.pojo.User">
     8                             <!--
     9                                 id表示查询结果集中唯一标识
    10                                 column:查询出来的列名
    11                                 property:type指定的pojo类型中的属性名
    12                                 最终resultMap对column和property做一个映射关系(对应关系)
    13                             -->
    14                             <id column="id_" property="id"/>
    15                             <!--
    16                                 result:标识对于普通名的映射
    17                                 column:查询出来的列名
    18                                 property:type指定的pojo类型中的属性名
    19                                 最终resultMap对column和property做一个映射关系(对应关系)
    20                             -->
    21                             <result column="username_" property="username"></result>
    22                         </resultMap>

             2.使用resultMap作为statement的输出映射类型(返回参数使用resultMap)

    1                   <!--
    2                                 使用resultMap来进行输出的映射
    3                                 resultMap:指定定义的resultMap的id,如果这个resultMap在其他mapper文件中,前边需要加namespace
    4                             -->
    5                             <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
    6                                 select id id_,username username_ from user where id = #{id}
    7                             </select>        

              userMapper.java中的接口调用
              //根据用户信息查询用户列表,根据resultMap输出
              public User findUserByIdResultMap(int id) throws Exception;

        小节:
          使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
          如果查询出来的列名和pojo属性名不一致,通过定义一个resultMap队列名和pojo属性名之间做一个映射关系。

        8.动态sql

          1.什么是动态sql:
            mybatis核心:对sql语句进行灵活的操作,通过表达式进行判断,对sql进行灵活的拼接,组装。
            原来的查询语句:

    1           <select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
    2                      select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'
    3                  </select>

            现在的查询语句
            理由:由于原来的查询语句可能userCustom是null或者里面的参数为‘’,所以我们可以使用动态sql来进行判断

     1                          <select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
     2                             <!--
     3                                 where可以自动去掉条件中的第一个add
     4                             -->
     5                             <where>
     6                                 <if test="userCustom != null">
     7                                     <if test="userCustom.sex != null and userCustom.sex = ''">
     8                                         and user.sex = #{userCustom.sex}
     9                                     </if>
    10                                     <if test="userCustom.username != null and userCustom.username = ''">
    11                                         and username like '%${userCustom.username}%'
    12                                     </if>
    13                                 </if>
    14                             </where>
    15                         </select>

         9.动态sql代码段

          将上边实现的动态sql判断代码块抽取出来,组成一个sql片段,其他的statement就可以引用sql片段

          1.定义sql片段
          <!--
            定义sql片段
            id:sql片段的唯一标识
            经验:是基于单表来定义sql片段,这样的话sql片段的可重用性才高
            在slq片段中不要包括where
          -->

          sql片段定义:

     1               <sql id="query_user_where">
     2                                 <if test="userCustom != null">
     3                                     <if test="userCustom.sex != null and userCustom.sex = ''">
     4                                         and user.sex = #{userCustom.sex}
     5                                     </if>
     6                                     <if test="userCustom.username != null and userCustom.username = ''">
     7                                         and username like '%${userCustom.username}%'
     8                                     </if>
     9                                 </if>
    10                         </sql>
    11                         sql片段引用:
    12                        <select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
    13                             <!--select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'username-->
    14                             select * from user
    15                             <!--
    16                                 where可以自动去掉条件中的第一个add
    17                             -->
    18                             <where>
    19                             <!--引用sql片段的id,如果refid指定的id不在本mapper文件中,需要前边加namespace-->
    20                               <include refid="query_user_where"></include>
    21                             </where>
    22                         </select>

        foreach标签

          向sql传递数据或List,mybatis使用foreach解析
          两种方法:
            select * from user where (id = 1 or id =2)
            select * from user where id in (1 , 2)

          foreach的sql片段:

                    <sql id="query_user_where">
                                    <if test="userCustom != null">
                                        <if test="ids != null">
                                            <!--
                                                使用foreach遍历ids
                                                    collection:指定输入对象中集合属性
                                                    item:每个遍历生成的对象中
                                                    open:开始遍历时拼接的串
                                                    close:结束遍历时拼接的串
                                                    separator:遍历中两个对象需要拼接的串
                                             -->
                                            <!--
                                                方法一:
                                                使用实现下边的sql拼接:
                                                AND (id = 1 OF id = 10)
                                            -->
                                            <foreach collection="ids" item="item_id" open="and (" close=")" separator="or">
                                              <!--每个遍历需要拼接的串-->
                                                id = #{item_id}
                                            </foreach>
                                            
                                            或者我们也可以才去这种方法
                                            <!--
                                                方法二:
                                                使用实现下边的sql拼接:
                                                And id  in (1,10)
                                            -->
                                            <foreach collection="ids" item="item_id" open="and id in (" close=")" separator=",">
                                                <!--每个遍历需要拼接的串-->
                                                #{item_id}
                                            </foreach>
                                        </if>
                                    </if>
                                </sql>
                                UserMapper.xml的sql片段的调用
                                 <select id="selectUserByForeach" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.User">
                                    select * from user
                                    <where>
                                        <include refid="query_user_foreach"/>
                                    </where>
                                </select>
  • 相关阅读:
    AES加密
    Axis创建webservice客户端和服务端
    RandomAccessFile操作文件
    使用HttpClient实现文件的上传下载
    System.getProperty()方法可以获取的值
    C#面向对象 基础概念25个
    C#面向对象基础
    JQuery————基础&&基础选择器
    css3实现图片遮罩效果鼠标hover以后出现文字
    JAVASCRIPT——图片滑动效果
  • 原文地址:https://www.cnblogs.com/wnbahmbb/p/7362375.html
Copyright © 2011-2022 走看看