对mybatis框架的再次学习以及笔记整理

Mybatis:和数据库进行交互,持久层框架

工具:一些功能的简单封装
框架: 某个领域的整体解决方案;
不用原生的jdbc:
1)麻烦

  1. sql语句是硬编码在程序中;耦合 (数据库和java编码耦合)
    库交互的框架(Hibernate--数据orm框架)
    缺点: 定制sql HQL(Hibernate自己的sql语言) 全映射 ; 部分字段映射很难;假设有1000个字段会全部帮你映射上,大大的降低了数据库的性能
    orm:对象关系映射(Object Relational Mapping,简称ORM)
  • Mybatis将重要的步骤抽取出来可以人工定制,其他步骤自动化.学习mysql只要学习如何写sql不需要关注其他的
  • 重要步骤都是写在配置文件中(好维护)
  • 完全解决了数据库的优化问题;
  • Mybatis底层就是对原生JDBC的一个简单封装
  • 即将java编码与sql抽取出来,还不会失去自动化的功能;半自动的框架.

mybatis的两个文件:

  1. mybatis-config.xml: mybatis的全局配置文件;指导mybatis正确运行的一些全局配置
  2. sql映射文件: EmployeeDao.xml 相当于对于一个dao接口的实现描述

细节:

  • 通过 session.getMapper(xx.class) 获取到的是接口的代理对象,有mybatis自动创建的


    image.png
  • SqlSessionFactory 和SqlSession

    • SqlSessionFactory 是帮助我们创建sqlSession对象 只需要new一次就行了
    • sqlSession是我们和数据库的一次会话 ,相当于Connection,一次会话就应该创建一个对象,在会话结束应该有关闭
<?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">
<!--dtd 当前配置文件的约束文件-->

<configuration>
  <properties resource="jdbc.properties"></properties>
  <!--日志的配置信息-->
  <settings>
    <setting name="logImpl" value="LOG4J"/>
  </settings>

  <typeAliases>
    <typeAlias type="com.hy.dao.EmployeeDao" alias="emp"></typeAlias>
  </typeAliases>

  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>

      <!-- 配置连接池 -->
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${jdbc.name}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>

  
  <!-- 引入我们自己编写的每一个接口的实现文件 -->
  <mappers>
    <mapper resource="com/hy/dao/EmployeeDao.xml"/>
  </mappers>
</configuration>
全局配置文件

mybatis-config.xml

  • 引入外部配置文件
<!-- 和spring中的 context:property-placeholder一样; 引用外部配置文件 -->
    <properties resource="jdbc.properties"></properties>
</configuration> 
  • settings
<!--为mybatis配置日志-->
<settings>
    <setting  name="logImpl" value="LOG4J"/>
</settings>
image.png

image.png

image.png

一个配置完整的 settings 元素的示例如下:

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

设置别名

 <typeAliases>
    <typeAlias type="com.hy.dao.EmployeeDao" alias="emp"></typeAlias>
  <!-- 采用package的方式 mybatis会为包下(后代包)的每一个实体类起一个别名 默认为类名全小写  @Alias("emp")可以为指定的类起别名 -->
    <package name="com.hy.dao"/>
  </typeAliases>
  • 引入我们自己编写的每一个接口的实现文件
<!-- 引入我们自己编写的每一个接口的实现文件 -->
  <mappers>
    <!--  resource 在类路径下找接口的xml配置文件
          url: 写磁盘的路径
          class: 接口的全类名  需要将xml和接口放在同目录下,而且文件名和接口名一致
          <mapper resource="com/hy/dao/EmployeeDao.xml"/>
           
      -->
    <!--批量注册  name : dao所在的包名
    如果没有使用注解的方式,mybatis如何知道我们的接口对应哪个配置文佳的?
    要求dao接口和配置文件在一个包下  (可以在类路径下创建一个和dao名称一样的文件夹 在编译的时候可以合并)
    -->
    <package name="com.hy.dao"/>
  </mappers>

mapper.xml 中获取插入后的自增id

<!--抽取公共的sql-->
    <sql id="select * from employee"/>
    <!--增删改不用写返回值类型-->
    <!--获取插入后自增的id
    useGeneratedKeys : true 使用原生JDBC获取自动增长的id的方法
    keyProperty : 将刚才自增的id封装给那个属性
    -->
    <insert id="saveEmployee" useGeneratedKeys="true" keyProperty="id">
        /*在核心sql文件执行之前 查询sql拿到id 之后赋值给 keyProperty 的字段*/
        <selectKey order="BEFORE" keyProperty="id">
            select max(id) from employee
        </selectKey>
        insert into employee values(default ,#{empname},#{gender},#{email})
    </insert>
  • mybatis中 方法的参数问题
1) 单个参数
  基本类型 : 
          取值:  #{随便写}
  传入pojo

2)多个参数:
Employee getEmpByIdAndName(Integer id, String name);
取值: #{参数名}  无效了
可用: 0 ,1  参数的索引 或者 param1 ,param2 (第几个参数paramN)
原因:只要传入了多个参数, mybatis会自动将这些参数封装在一个map中;
封装时使用的key就是参数的索引和参数的第几个表示  
Map<String,Object> map = new HashMap<>();
map.put("1",传入的值);
map.put("2",传入的值)
#{key}的方式就是从这个map中取值 所以可以拿到值

解决方法
Employee getEmpByIdAndName(@Param(value = "id") Integer id,@Param(value = "empname") String name); 
告诉mybatis在封装参数的时候 按照我们给定的key来封装

3) 传出pojo
#{pojo的属性名}

4)传入map:
    手动将需要的参数封装到一个map中, 在sql #{id}中写的id作为map的key,需要传入的值为value
取值:#{key}

扩展
多个参数的情况下mybatis会自动封装成map

    method01(@Param("id")Integer id,String empname,Employee employee);
    取值:
    Integer id ==>#{id}
    String empname ==> #{param2}
    Employee  employee ==> #{param3.email}

mybtis中的sql取值问题

#{xx}  :  是参数预编译的方式, 参数的位置都是?代替的,参数都是预编译设置进去的,安全不会有sql注入的问题   select * from employee where id = ${id} and empname=#{empname}

在执行的时候
${XX} 不是参数 预编译,而是直接和sql语句进行拼接的,不安全 会有sql注入的问题
${}的使用场景  :  sql语句只有参数位置才能支持预编译,如果我们想要动态的插入表名,就可以使用${}来获取表名
查询返回list问题
resultType=""; 如果返回的是list类型,写的是集合里面的元素的类型
查询单条记录返回map
dao
  /**
     * 查询单条记录 并且返回一个map
     *
     * mybatis 会把列名作为key 把 查到的结果作为value 封装到集合中
     * @param id
     * @return
     */
    Map<String,Object> getEmpByIdReturnMap(Integer id);

xml
    <select id="getEmpByIdReturnMap" resultType="java.util.Map">
        select * from employee where id=#{id}
    </select>

image.png
查询多个封装成map
dao
     /**
     * 查询多条记录 将查询到的结果返回给一个map
     * key: 这条记录的主键
     * value:就是这条记录封装好的对象
     * resultType="" 就是value封装的类型
     * @return
     * @MapKey("id")  把查询出来的值id作为主键
     */
    @MapKey("id")
    Map<Integer,Employee> getAllEmpReturnMap();

xml
      <select id="getAllEmpReturnMap" resultType="com.hy.bean.Employee">
            select * from employee
      </select>

mybatis自定义封装结果集

1) 按照列名和属性名一一对应的得到规则(不区分大小写)
2)如果不一一对应;
           1) 开启驼峰命名发(要满足驼峰命名的规则     aaa_bbb   aaa_Bbb)
           2) 使用自定义的封装结果集

<mapper namespace="com.hy.dao.CatDao">

        <!-- resultMap  使用自定义的规则-->
    <select id="getCatByid" resultMap="mycat">
        select * from cat where id= #{id}
    </select>
    <!-- 自定义结果集(resultMap):自己定义每一列数据和javaBean的映射规则
    type="" 指定为哪个javaBean指定自定义规则; 全类名
    id="" 唯一标识 让别人去引用
    -->
    <resultMap id="mycat" type="com.hy.bean.Cat">
        <!--指定主键的对应规则
        column="id" 指定那一列是主键列
        property="": 指定cat的那个属性封装id这个属性
        -->
        <id property="id" column="id"></id>

        <!--普通列-->
        <result property="age" column="cage"/>
        <result property="name" column="cname"/>
        <result property="gender" column="cgender"></result>
    </resultMap>
</mapper>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352