MyBatis快速入门

文章内容输出来源:拉勾教育Java就业急训营

MYBATIS

基于ORM的半自动轻量级持久层框架

ORM实现

object relational mapping 对象关系映射
  O 对象模型 根据数据库表创建的JavaBean
  R 数据库表
  M 从R到O的映射 让实体类和数据库表一一映射

MYBATIS 快速入门

  • 创建数据库和表
  • 创建maven项目,pom引入 mybatis mysql-connector 等依赖
  • 创建对应JavaBean
  • 创建对应JavaBean的mapper映射文件 如UserMapper.xml 编写sql
  • 创建sqlMapConfig.xml核心配置文件
  • 配置数据库连接信息和填写对应的mapper映射
  • 创建test类,进行测试

把数据库连接信息另外放在一个properties文件中
引入properties文件的路径后,就可以使用"${key}"的方式去获取properties中value

注意:数据库连接信息中加上?characterEncoding=UTF-8 可以防止数据乱码

//获取核心配置文件的字节码数据
InputStream is = Resources.getSourcesAsStream("核心配置文件的路径")
//获取sqlSession对象
SqlSessqddasssqsssssasrion sqlSession = new SqlSessionFactoryBuilder(is).openSqlSession()
//调用CRUD方法
sqlSession.selectList("命名空间.id")

mybatis配置解析

<environments>标签
  内配置有数据库连接的信息
<properties>
  可添加properties文件的路径,在xml中引用
<typeAliases>
  为resultsType中的类全类名起别名
<package>
  指定包下所有类自动起别名,为类名不区分大小写
<typeAlias>
  为指定类起别名

mybatis之动态代理使用方式

不需要创建dao的实现类,不用硬编码的方式获取stamentId

  • 创建UserDao接口,对应的方法
  • 在resources下创建和UserDao接口同样路径的UserDao.xml,namespace使用UserDao接口的全类名
  • 使用sqlSession.getMapper(UserDao.class)就可以创建出代理类对象,调用方法

MYBATIS的基本原理

new salSessionFactoryBuilder().build("核心配置文件")  
把映射文件中的每一条sql封装进一个个mapperStatement对象中,再将每个mapperStament放到map,key是namespace.id    
sqlsession.selectList(namespace.id)  
这个sqlsession对话对象本身不去执行sql而是调用底下的执行器,执行器再根据namespace.id去找到对应的mapperstatement对象,获取里面的sql,参数等 再去调用JDBC操作数据库  

提问:当JavaBean的属性和数据库表的字段没有一一对应的时候怎么处理呢?

使用resultMap结果集指定对应关系

   <!--id : 标签的唯一标识
       type: 封装后实体类型-->
   <resultMap id="userResultMap" type="com.lagou.domain.User">
       <!--手动配置映射关系-->
       <!--id: 用来配置主键-->
       <id property="id" column="id"></id>
       <!-- result: 表中普通字段的封装-->
       <result property="username" column="username"></result>
       <result property="birthday" column="birthday"></result>
       <result property="sex" column="sex"></result>
       <result property="address" column="address"></result>
   </resultMap>

提问:当传过来多个参数的时候,如何判断某个占位符就是某个参数?

多条加查询

  • 方式一
    在占位符中使用#{arg0},#{arg1}... 或 #{param1},#{param2}...表示顺序
  • 方式二
    在参数前加@param("")注解获取参数
  • 方式三
    把多参数封装到对象中,参数中只传递一个对象参数,然后在占位符中使用对象中的get方法后内容首字符小写的方式获取到该属性值

提问:mybatis如何实现模糊查询的?

- 传参数的时候可以给参数拼接上%%再放到占位符中,或者在sql上拼接% #{} %  
- #{}可以自动进行Java类型和jdbc类型转换,无需手动添加 ‘’  
- 而使用${}的话就需要手动添加 ‘’  

提问:#{} 和 ${}的区别

- #{}可以实现prepareStament自动进行Java类型和jdbc类型转换,防止sql注入,当只有一个占位符的时候可以随便填写内容填充  
- ${}不会将parametertype进行jdbc类型,而是直接把内容拼接在sql上,存在SQL注入问题,当只有一个占位符的时候括号中只能是value  

提问:如何实现在插入一条数据后返回其主键ID?

  • 方式一:
    只支持主键自增策略的数据库,如MySQL sqlserver 。Oracle不支持
    设置userGenerateKeys=true keyProperty="JavaBean中代表主键的值"
<insert id="save" parameterType="user" useGeneratedKeys="true" keyProperty="id">

执行插入操作成功后JavaBean中的主键id就会由null获取到生成的主键ID

  • 方式二
    通用方式,所有数据库都能获取到主键值
<!--
    selectKey 适用范围广,支持所有类型数据库
    keyColumn="id" 指定主键列名
    keyProperty="id" 指定主键封装到实体的id属性中
    resultType="int" 指定主键类型
    order="AFTER" 设置在sql语句执行前(后),执行此语句
-->
<insert id="save" parameterType="user">
    <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
        SELECT LAST_INSERT_ID();
    </selectKey>
    INSERT INTO `user`(username,birthday,sex,address)
    values(#{username},#{birthday},#{sex},#{address})
</insert>

动态sql之if

不清楚可能传过来几个有值参数时使用,如多条件查询操作

<if test="判断表达式>
表达式成立的话才会执行这里的内容
</if>
常与<where>同用

动态sql之set

进行更新操作不清楚可能更新几个字段的时候使用
set标签在更新的时候,自动加上set关键字,然后去掉最后一个条件的逗号

<set>
    <if></if>
</set>

动态sql之foreach

如果参数是集合类型 parameter使用collection或list

<foreach collection="collection" open="id in(" close=")" item="id"  separator=",">

如果参数是数组类型 parameter使用array

<foreach collection="array" open="id in(" close=")" item="id" separator=",">

提问:当有部分sql被重复使用,可以怎么做到优化

提取出sql片段

<!--抽取的sql片段-->
<sql id="selectUser">
    SELECT * FROM `user`
</sql>

<!--引入sql片段-->
<include refid="selectUser"></include>

提问:JavaBean中还包含了另一个类对象,该怎么进行字段和属性的一一对应?

使用resultMap中的association标签定义该类的属性和字段的对应关系

提问:JavaBean中还包含了另一个类对象的集合,该怎么进行字段和属性的一一对应?

使用resultMap中的collection标签定义该类的属性和字段的对应关系

延迟加载

可全局配置或单个配置
实际开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的订单
信息。此时就是我们所说的延迟加载。

<settings>
    <!--所有方法都会延迟加载-->
    <setting name="lazyLoadTriggerMethods" value="toString()"/>
    <!--开启全局延迟加载功能-->
    <setting name="lazyLoadingEnabled" value="true"/>
</settings>

mybatis一级缓存

默认开启
同一个sqlSession下,多次执行相同sql同一参数时,第一次的结果会缓存起来,第二次直接从缓存中取数据,减少交互次数
注意
一级缓存是SqlSession范围的缓存,执行SqlSession的C(增加)U(更新)D(删除)操作,或者调用clearCache()、commit()、close()方法,都会清空缓存。

mybatis二级缓存

默认不开启
要求返回的JavaBean必须实现序列化操作
存在脏读问题,不建议使用
mybatis的二级缓存因为是namespace级别,所以在进行多表查询时会产生脏读问题

<settings>
    <!--
        因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。
        为true代表开启二级缓存;为false代表不开启二级缓存。
    -->
    <setting name="cacheEnabled" value="true"/>
</settings>

MYBATIS常用注解

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