mybatis 第一天 mybatis的基础知识

1.JDBC的问题

  • 数据库经常连接和释放:使用连接池
  • SQL硬编码到Java代码中,不利于维护:使用XML配置文件的形式进行维护
  • 参数硬编码到preparedStatement中:使用XML配置参数
  • 从resultSet中获取结果集存在硬编码:把结果集硬编码成Java对象

2.mybatis框架

mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句

3.入门程序

3.1 准备

需求:根据用户id(主键)查询用户信息、根据用户名称模糊查询用户信息、添加用户、删除 用户、更新用户

导包:mybatis及本身依赖的包,数据库驱动以及log4j.properties文件
在这里插入图片描述
创建SqlMapConfig.xml文件:配置mybatis的运行环境(不掌握),数据源

3.2 【功能1】根据用户id(主键)查询用户信息

(1)创建用户类User.class:对应数据库的表结构
(2)创建映射文件UserMapper.xml:配置实现不同功能的SQL语句

#{}表示一个占位符号
#{id}:其中的id表示接收输入的参数,参数名称就是id,
       如果输入 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称	

在这里插入图片描述
(3)在SqlMapConfig.xml加载映射文件
在这里插入图片描述
(4)创建测试类
在这里插入图片描述

3.3 【功能2】根据用户名称模糊查询用户信息

(1)在User.xml,添加根据用户名称模糊查询用户信息的sql语句。

${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。
    使用${}拼接sql,引起 sql注入
${value}:接收输入参数的内容,如果传入类型是简单类型,${}中只能使用value

在这里插入图片描述
(2)在测试类添加新函数
这里返回的结果是对象列表,使用List类型
在这里插入图片描述

3.4 【功能3】添加用户

(1)在 User.xml中配置添加用户的Statement

parameterType:指定输入 参数类型是pojo(包括 用户信息)
#{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值

在这里插入图片描述
(2)在测试类添加新函数
对于修改数据库的函数,需要使用事务
在这里插入图片描述
(3)自增主键返回
功能:将插入数据的主键返回,返回到user对象中

SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用于自增主键
keyProperty:			 将查询到主键值设置到parameterType指定的对象的哪个属性
order:		 SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
resultType: 指定SELECT LAST_INSERT_ID()的结果类型

在这里插入图片描述
(4)非自增主键返回
功能:使用mysql的uuid()函数生成主键,需要修改表中id字段类型为string,长度设置成35位。
执行思路
先通过uuid()查询到主键,将主键值输入到sql语句中。
执行uuid()语句顺序在insert语句之前执行。
在这里插入图片描述

3.5 【功能4】删除用户

(1)在映射文件添加删除语句
在这里插入图片描述
(2)测试函数
在这里插入图片描述

3.6 【功能5】更新用户

(1)在映射文件添加更新语句
需要传入用户的id
需要传入用户的更新信息
parameterType指定user对象,包括 id和更新信息,注意:id必须存在
#{id}:从输入 user对象中获取id属性值
在这里插入图片描述
(2)测试函数
在这里插入图片描述

3.7 总结

(1)parameterType
在映射文件中通过parameterType指定输入参数的类型。
(2)resultType
在映射文件中通过resultType指定输出结果的类型。
(3)#{}和${}

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
'如果接收简单类型,#{}中可以写成value或其它名称'。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
${}表示一个拼接符号,会引用sql注入,'所以不建议使用${}'。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
'如果接收简单类型,${}中只能写成value'。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

(4)selectOne和selectList
selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现,那么使用selectList也可以实现(list中只有一个对象)。
selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。

如果使用selectOne报错:

org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4

(5)mybatis和hibernate本质区别和应用场景

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

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

4. mybatis开发->dao的方法

4.1 思路

上面我们每个测试方法都需要创建SqlSessionFactoryBuilder、 SqlSessionFactory和SqlSession,修改如下:

  1. SqlSessionFactoryBuilder当成一个工具类使用即可
  2. 单例模式管理sqlSessionFactory
  3. SqlSession最佳应用场合在方法体内,定义成局部变量使用

程序员需要写dao接口和dao实现类。需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession。

4.2 总结原始 dao开发问题

在这里插入图片描述

  1. dao接口实现类方法中存在大量模板方法(session的关闭等),设想能否将这些代码提取出来,大大减轻程序员的工作量。
  2. 调用sqlsession方法时将statement的id硬编码了(sql的映射id)
  3. 调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

4.3 mapper代理方法

程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

mapper.java:接口文件(相当于dao接口)。接口里面是针对数据库的不同操作方法的集合
mapper.xml:映射文件。针对接口中不同方法配置对应的SQL语句

开发规范
1、mapper.xml:namespace等于mapper接口路径
2、mapper.java:接口中的方法名等于mapper.xml中statement的id
3、mapper.java:接口中的方法输入参数类型等于mapper.xml中statement的parameterType指定的类型
4、mapper.java:接口中的方法返回值类型等于mapper.xml中statement的resultType指定的类型
(1)mapper.java
在这里插入图片描述
(2)map.xml
在这里插入图片描述
(3)在SqlMapConfig.xml中加载mapper.xml
在这里插入图片描述
(4)测试:接口对象 = sqlSession.getMapper(接口名.class)
在这里插入图片描述
(5)问题总结
代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。

mapper接口方法参数只能有一个是否影响系统 开发
系统框架中,dao层的代码是被业务层公用的。
即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。
注意:持久层方法的参数可以包装类型、map。。。,service方法中建议不要使用包装类型(不利于业务层的可扩展)。

5 SqlMapConfig.xml

mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:

-properties(属性)
-settings(全局配置参数)
-typeAliases(类型别名)
-typeHandlers(类型处理器)
-objectFactory(对象工厂)
-plugins(插件)
-environments(环境集合属性对象)
	environment(环境子属性对象)
		transactionManager(事务管理)
		dataSource(数据源)
-mappers(映射器)

5.1 properties 属性

MyBatis 将按照下面的顺序来加载属性:

  • 首先,读取在 properties 元素体内定义的属性
  • 然后,会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
  • 最后,读取parameterType传递的属性,它会覆盖已读取的同名属性。

建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
在properties文件中定义属性名要有一定的特殊性,如:XXXXX.XXXXX.XXXX

例如数据库参数配置:
数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。
在这里插入图片描述
在这里插入图片描述

5.2 settings 全局参数配置

mybatis框架在运行时可以调整一些运行参数。比如:开启二级缓存、开启延迟加载。。
全局参数将会影响mybatis的运行行为。

5.3 typeAliases 类型别名(重点)

(1)可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。
(2)默认支持别名
在这里插入图片描述
(3)自定义别名
单个别名
别名定义:
在这里插入图片描述
别名引用:
在这里插入图片描述
批量别名】(常用)
在这里插入图片描述

5.4 typeHandlers 类型处理器

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

5.5 mappery 映射配置

作用在于告诉 MyBatis 到哪里去找映射文件SQL。
(1)通过resource加载单个映射文件

<mapper resource="mapper/UserMapper.xml"/>

(2)通过mapper接口加载单个mapper
规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中。这样就不需要配置mapper.xml路径。
规范的前提:使用的是mapper代理方法

<mapper class="cn.itcast.mybatis.mapper.UserMapper"/> 

(3)批量加载mapper(推荐使用)
指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载多个接口。
遵循规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
规范的前提是:使用的是mapper代理方法

<package name="cn.itcast.mybatis.mapper"/>

6. 输入映射

有时传入查询条件很复杂(可能包括用户信息、其它信息,比如商品、订单的),需要使用复杂的输入。
针对上边需求,建议使用自定义的包装类型的pojo。在包装类型的pojo中将复杂的查询条件包装进去。

6.1 传递pojo的包装对象

(1)定义包装类型
在这里插入图片描述
(2)UserMapper.xml
在UserMapper.xml中,把定义的包装类型作为输入参数
在这里插入图片描述
(3)mapper.java
定义功能接口
在这里插入图片描述
(4)测试
基于接口创建对象,设置查询条件,调用对象的方法,使用sql语句进行查询。
在这里插入图片描述

6.2 hashmap

7. 输出映射

7.1 resultType

(1)使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。

(2)查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。

(3)输出pojo对象和pojo列表
不管是输出的pojo单个对象还是一个列表(list中包括pojo),在mapper.xml中resultType指定的类型是一样的,但是在mapper.java指定的方法返回值类型不一样

1、输出单个pojo对象,方法返回值是单个对象类型Pojo  ————>动态代理对象调用selectOne
2、输出pojo对象list,方法返回值是List<Pojo>  ————>动态代理对象调用selectList 

7.1 resultMap

(1)作用:如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
(2)如何定义resultMap
在UserMapper.xml中定义sql语句中不同列名对应的pojo属性名:
在这里插入图片描述
(3)使用resultMap作为statement的输出映射类型,而不是原来的pojo类型
在这里插入图片描述

8. 动态sql

对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装,减少重复语句。

8.1 动态SQL语句

(1)需求:用户信息综合查询列表这个statement的定义使用动态sql。对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。
(2)实现:mapper.xml文件的SQL中增加判断语句
在这里插入图片描述

8.2 定义sql片段

(1)需求:将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。方便程序员进行开发。
(2)实现:
在这里插入图片描述
在这里插入图片描述

8.3 foreach

向sql传递数组或List,mybatis使用foreach解析
(1)需求:
在用户查询列表的statement中增加多个id输入查询。

两种sql语句:
SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
SELECT * FROM USER WHERE id IN(1,10,16)

(2)实现
在输入参数类型中添加List 属性ids用于传入多个id
在这里插入图片描述
修改mapper.xml的sql片段:
在这里插入图片描述
或者:
在这里插入图片描述
总结:

发布了135 篇原创文章 · 获赞 5 · 访问量 7082

猜你喜欢

转载自blog.csdn.net/qq_27921205/article/details/104592280