Mybatis整理

1、为什么使用Mybatis框架?

            首先框架就是插件(方便我们开发的工具),针对项目中的弊端,进行封装,调试

1、传统的jdbc 的弊端:

            1、每次都要获取连接、操作数据、便利结果集、关闭连接(频繁的开启,关闭,浪费资源)

            2、SQL语句和代码耦合在一起(不利于程序的维护更新)

            3、代码的冗余

            4、ORM的(对象关系mapper)好处:

                      1、代码的繁琐度

                      2、数据库对象的连接问题

                      3、系统架构

                     使用ORM技术,可以将数据库层完全隐蔽,呈献给程序员的只有Java的对象,程序员只需要根据业务逻辑的需要                          调 用Java对象的Getter和 Setter方法

                      5、性能

                        数据库发送1000次SQL语句执行请求,运行效率较低。

                         会自动延迟向后台数据库发送SQL请求

                         只会在循环完成后,一次向数据库发送操作请求,从而大大降低通讯量,提高运行效率;

 

2、Mybatis  核心配置文件的配置(怎么配,有啥)

     (百度在手,天下我有)   1、可以参考mybatis的官网


    2、(1)xml约束(dtd,schema)

          (2)

 <environments default="mysql">
         <environment id="mysql">
             <!-- 事务管理器 执行的sql单元-->
             <transactionManager type="JDBC"></transactionManager>
             <!-- 数据库连接 -->
             <dataSource type="POOLED">
                 <property name="driver" value="com.mysql.jdbc.Driver"/>
                 <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                 <property name="username" value="root"/>
                 <property name="password" value="root"/>
             </dataSource>
         </environment>

  <!--每一个environment可以操作不同的数据库  -->
        <!--
        <environment id="oracle">
             <transactionManager type=""></transactionManager>
             <dataSource type=""></dataSource>
         </environment>

         <environment id="sqlserver">
             <transactionManager type=""></transactionManager>
             <dataSource type=""></dataSource>
         </environment>
         -->
     </environments>
   <!--一定要写,扫描到我们对应的xml文件  -->
    <mappers>
          <mapper resource="com/offcn/mapper/PersonMapper.xml"></mapper>
    </mappers> 

总结: 其实就是   ----头+++environments里面的事务、数据源的配置+++Mappers开头的扫描-------------

 

3、配置结束以后我们怎么使用,怎么读取主配置文件(就是我们怎么使用)

     1、创建一个test类,里面有一个 Main 方法,用配置读取,使用mybatis的类

     2、读取配置文件   

           String resource = "mybatiscfg.xml";

           InputStream inputStream = Resources.getResourceAsStream(resource);

     3、通过配置文件实例化工厂

            SqlSessionFactory  sf = new SqlSessionFactoryBuilder().build(inputStream);

     4、通过工厂获取session  ,传统的不使用代理模式(没有事务),直接再后面写

              SqlSession session = sf.openSession();

     5、通过session获取接口的代理,(反射,获取代理)

               PersonMapper mapper = session.getMapper(PersonMapper.class);

     6、操作数据(自己要写的增删改查方法)

       PersonMapper mapper = session.getMapper(PersonMapper.class);

        Person person1 = new Person();

        person1.setPname("张三");

        System.out.println(mapper+"====");

        mapper.saveInfo(person1);

     7、提交事务

        session.commit();

     8、关闭session

         session.close();

代码:

    

 

4、关于mybatis的增删改查(CRUD)  简单的demo

      1、mapper.xml 里面有对应的.java的地方

<mapper namespace="com.offcn.mapper.CarDetailMapper">

 

5、关于多个参数的处理(输入数据的出处理,一共四种),哪种更好用

      1、数组下表

            public   int  deleteInfo(Integer pid,String pname);

    mapper.xml里面直接用数组下标接着#{0}

       2、map集合

    public   int  deleteInfo2(Map<String,Object> map);

    mapper.xml集合里面

       <delete id="deleteInfo2" parameterType="java.util.Map">
              delete from  person where pid=#{pid} and pname=#{pname}
       </delete>

       3、使用Param

         public   int  deleteInfo3(@Param("pid") Integer pid, @Param("pname") String pname);

        此时直接用我们的pid=#{pid} and pname=#{pname}

       4、业务模型    传入的参数是一个对象(业务模型 vo)

                       数据模型: 数据库中的表进行映射

                   业务模型: 和我们的页面数据进行映射 

          原理 : 使用查询字段的名称充当我们类中的属性名称,反射获取类型的属性对象,然后给属性对象赋值
           pname 获取属性对象(Person  name) 也就无法完成赋值,使用了当前对象属性的默认值.

       总结:首先选择后面的两个,对于一些数据的封装,以及数据的获取和快捷    

       

6、主键值返回的问题(关于selectKey的操作)、

        解决的问题:插入数据后,直接要使用自增长的主键        


<insert id="saveInfo" parameterType="com.offcn.bean.Person">
              <!-- 主键值  自增长 -->
             <!-- <selectKey keyProperty="pid" keyColumn="pid" resultType="int" order="AFTER">
                     SELECT last_insert_id();
              </selectKey>-->


              <!-- 主键值是 UUID -->
               <selectKey keyProperty="pid" keyColumn="pid" resultType="string" order="BEFORE">
                      SELECT UUID();
               </selectKey>
              insert into person(pid,pname) values(#{pid},#{pname})
       </insert>


      mapper.saveInfo(person);
      System.out.println(person.getPid());

     之后,直接调用。就可以得到这个值。

     总结:selectkey的作用就是  获取主键值。记得order后面的值,表示之前还是之后。

 

7、参数位置的占位符的两种区别#{}  和 ${}  区别联系

     #{}   参数位置被解析称为一个占位符 ?  (已经预编译了)

     ${}    参数的位置被解析成一个字符串的拼接的位置 Statement(静态sql) sql注入风险

     concat(${})实现字符串的拼接同时没有sql注入的风险。

 

8、输出结果映射(resultMap的使用)

      resultMap标签 (自定义结果映射):解决的基本的问题是,属性名和表的字段名不一致的问题

      我们自己定义了一个查询结果的映射类型

 

9、多表查询的问题,怎么查,1对1 和1对多,我们怎么去处理

   无非就是1对1  用association  ,一对多用collection

          property: 关联对象属性
          column: 提供给级联查询的字段名称
          javaType: 结果类型
          select : 调用其他工作空间下的查询标签

<resultMap id="newPerson" type="com.offcn.bean.Person">
       <id property="pid" column="pid"></id>
       <result property="pname" column="pname"></result>

  <association property="car" column="pid" javaType="com.offcn.bean.Car" select="com.offcn.mapper.CarMapper.getInfoByPid">
       </association>
</resultMap>

  resultType: 原生类型
    resultMap: 我们自己定义了一个查询结果映射类型

<select id="getInfo" resultMap="newPerson">
       select *  from  person
</select>

下一个表中

<resultMap id="newCar" type="com.offcn.bean.Car">
       <id property="cid" column="cid"></id>
       <result property="dis" column="dis"></result>
       <result property="total" column="total"></result>

 

//这里是一对多的查询       ofType 和select的书写
       <collection property="carDetailList" column="cid" ofType="com.offcn.bean.CarDetail" select="com.offcn.mapper.CarDetailMapper.getInfoByCid">
       </collection>
</resultMap>

<select id="getInfoByPid" parameterType="int" resultMap="newCar">
       select *  from  car  where p_fk=#{pid}
</select>

总结:这个时候还要注意,我们再实体类中申明一个类,关联对象的私有属性,同时提供set和get的方法

  

 

10、动态sql(什么是动态sql),他有哪些标签

     1、where  if  

实例:

<where>
      <if test="pid!=null and pid>3">
           and pid=#{pid}
      </if>
       <if test="pname!=null and pname.length()>4">
            or pname=#{pname}
       </if>
</where>

     2、choose(when otherwise)  

   同上

    3、set  标签  

    替换我们的set标签

      必须要传入数据的
     set 标签替代set关键字
     同时忽略最后一个成立条件后面逗号

     4、trim 标签    

<trim prefix="where" prefixOverrides="and|or">
       <if test="pid!=null and pid>3">
              and pid=#{pid}
       </if>
       <if test="pname!=null and pname.length()>4">
              or pname=#{pname}
       </if>
</trim>

<trim prefix="set" suffixOverrides=",">
       <if test="pname!=null">
              pname=#{pname},
       </if>
</trim>

   总结:使用trim可以替换where 和set,他的效果就是,我们可以做拼接,让我们的sql更灵活

     5、foreach标签:批量操作的方法

      通过ids这个集合,实现的是批量的删除id,map也是可以的

<delete id="batchDelete" parameterType="com.offcn.bean.PersonVo">
         delete from  person where pid in
         <foreach collection="ids" item="id" separator="," open="(" close=")">
                #{id}
         </foreach>
</delete>

注意:我们在mysql的批量更新必须要在mysql连接的url中添加一个键值对,允许我们远程批量更新动作

<property name="url" value="jdbc:mysql://localhost:3306/test?allowMultiQueries=true"/>

11、别名是啥,有什么效果,卸载哪里

          1、  在我们的mapper.xml中经常使用我们类型的名称(就像我们多表查询中书写表全名,如果表名过于长,需要给表设定           别名)             需要在xml配置文件中添加别名

          2、

          <typeAlias type="com.offcn.bean.Person" alias="person"></typeAlias>
          <typeAlias type="com.offcn.bean.PersonVo" alias="vo"></typeAlias>

          3、 在我们的mapper对应的xml文件中我们可以直接使用类名或者是类名的首字母小写形式 

          4、 <package name="com.offcn.bean"></package>   加扫描mapper ,更fangbian

12、缓存的效果

          1、效果:提高查询效率

          2、一级缓存:session默认就是一级缓存 同一个session 使用的数据

          3、二级缓存:

  <settings>
    <setting name="cacheEnabled " value="true"/>
</settings>

mapper.xml

<cache></cache>

当前工厂生产出来的所有的session都可以共享的数据

总结;需要设置三个地方

 

13、简述一下延时加载(懒加载的工作原理)

    1、减少我们的数据库的交互(场景必须是级联查询)

    2、

<settings>
     <setting name="lazyLoadingEnabled" value="true"></setting>
     <setting name="aggressiveLazyLoading" value="false"></setting>
 </settings>

    3、使用关联对象到时候才会产生我们的关联表的sql语句,按需加载。

 

 

14、MBG(逆向工程的使用),需要修改哪些地方,参考那些文档

    参考官方文档: mybatis generater,修改

 

15、Mybatis的注解的使用,怎么用,注意哪些问题

使用注解的形式将sql放入到我们的接口方法上,有效的减少我们的xml的配置(去除掉xml文件)

@Select

 @Insert

 @update

 @delete  

 @Results  

 @Result...

 //一对多的注解配置
  @Select("select *  from  person where pid=#{pid}")
  @Results({
          @Result(id = true,property = "pid",column = "pid"),
          @Result(property = "pname",column = "pname"),
          @Result(property = "car",javaType = List.class,column = "pid",
          many =@Many(select = "com.offcn.mapper.CarMapper.getInfosByPid") )
  })
  Person  getOne(Integer pid);

  

@Results({
         @Result(id = true,property = "pid",column = "pid"),
         @Result(property = "pname",column = "pname"),
         @Result(property = "car",javaType = Car.class,column = "pid",
                 one = @One(select = "com.offcn.mapper.CarMapper.getInfoByPid"))
 })
 Person  getOne(Integer pid);

 

16、总结一下mybatis的好处,以及关于mybatis的常见的面试题(百度)

        1、持久层框架,解决了jdbc带来的不方便

        2、半orm,半sql,

        3、支持级联查询,支持缓存机制,懒加载机制

        4、条件语句块,可以定义动态sql

        5、逆向工程,简化,方便了我们写实体类

        6、注解

        7、处理结果集,多表查询很方便

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值