Mybatis入门知识
sqlsession的使用范围:
通过sqlsessionfactorybuilder创建会话工厂(只需要当成一个工具类即可,不需要使用单例来管理sqlsessionfactorybuilder)
在需要创建工厂的时候,只需要new一次即可
创建一个工厂的对象,创建了一直放在这里,不再销毁,一直使用一个实例
单例模式,管理sqlsessionfactory
mybatis和Spring整合之后,使用单例模式管理sqlsessionfactory
sqlsessionfactory创建sqlsession
sqlsession面向用户的接口,在sqlsession中提供了很多用于操作数据库的方法
selectOne:返回单个对象
selectList:返回单个或者多个对象
sqlsession是线程不安全的,在sqlsession的实现类中除了有接口中的方法,还有数据域的属性,导致线程不安全
sqlsession的最佳应用场所在方法体内,定义成局部变量
1、原始Dao的方法:
程序员只需要写dao接口和dao的实现类
dao接口:
dao实现类:
2、mapper代理的方法:
程序员只需要写mapper接口(相当于dao的接口)
原始Dao的开发方法:
1、dao的接口实现类存在大量的模板方法,设想能否将这些代码提取出来,可以减轻程序员的工作量
2、调用sqlsession方法时将statement的id硬编码
3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发
mapper代理的方法
1、程序员需要编写mapper接口(相当于dao接口)需要遵循一些的开发规范
mybatis可以自动的生成mapper接口实现类的代理对象
开发规范:
mapper.xml中的namespace等于mapper接口的地址
mapper.java接口中的方法名和mapper.xml中statement的id一致
mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致
mapper.java接口中的返回值的类型和mapper.xml中statement的resultType指定的类型一致
开发规范是对sqlsession调用方法(sqlsession.selectOne...)代码统一的生成
2、程序员还需要编写mapper.xml映射文件
在SqlMapConfig中加载mapper映射文件
代理对象内部调用selectOne或者selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过调用selectOne查询数据库
如果mapper方法返回集合对象,代理对象内部通过调用selectList查询数据库
mapper接口方法参数只能有一个是否影响系统开发
mapper接口方法参数只能有一个,系统是否不利于扩展维护
系统框架中,dao中层的代码是被业务层公用的
即使mapper接口只有一个参数,可以使用包装类型的pojo来满足不同的业务方法的需求
注意:持久层中方法的参数可以用包装类型、map...,但是service方法中建议不要使用包装类型(不利于业务层的的可扩展性)
SqlMapConfig
mybatis的全局配置文件
需求:将数据库的连接参数单独的配置到db.properties中,只需在SQLMapConfig中加载db.properties的属性值
在SqlMapConfig中就不需要对数据库的连接参数硬编码
将数据库的连接参数只配置在db.properties中,原因是方便对运行的参数进行统一的管理,其他的xml可以引用该配置文件
配置到SqlMapConfig中不利于升级和维护
配置完成db.properties后对数据库进行正常测试和异常测试
1、property:属性
mybatis的加载顺序:
在properties元素体中定义的属性首先被读取
然后读取properties元素中resource或url加载的属性,他会覆盖已读取的同名属性
最后读取parameterType传递的属性,他会覆盖已读取的同名属性
注意:逐步覆盖的
建议:不要在properties元素体内添加任何属性,只将属性值定义到properties的文件中,在文件中定义的属性名要有一定的特殊性,如xxxx.xxxx.xxxx
2、settings
mybatis在运行时可以调整一些运行参数
比如:开启二级缓存、开启延迟加载
参考学习资料/mybatis-settings.xlsx文件
3、typeAliases别名
在mapper.xml中定义了很多的statement,statement需要parameterType指定输入参数的类型,需要resultType来指定输出结果的类型
如果在指定类型的时候,输入类型的全路径,不方便开发,可以设置针对parameterType和resultType一些类型定义别名,在mapper.xml中通过别名来定义,
方便开发
mybatis默认支持别名
针对pojo自定义别名
<!-- 针对单个别名的定义 -->
<typeAlias type="com.mybatis.po.User" alias="user"/>
4、typeHandlers类型处理器
mybatis中通过类型处理器,完成jdbc类型和java类型的转换
一般情况下mybatis默认支持的类型处理器够用,通常不需要自定义
5、mapper映射器(映射配置)
通过mapper接口来加载映射文件
需要遵循一定的规范:
需要将mapper接口的类名和mapper.xml映射文件名称保持一致,且在一个目录
前提是使用mapper代理的方法
推荐使用批量加载mapper文件
输入映射&输出映射
1、输入映射
通过parameterType指定输入参数的类型,类型可以是简单类型、map、pojo包装类型
传递pojo的包装对象:
完成用户信息的综合查询,需要传入查询条件(可能包括用户信息、其他信息、商品、订单信息)
针对上面的需求,建议使用包装类型的pojo,包装自己所需要的查询条件
扩展类型,建立一个类Custom,然后继承自要扩展的基本类
定义映射文件
mapper.xml/mapper.java
在UserMapper.xml中定义用户的综合查询(查询条件复杂,通过高级查询进行复杂的查询,关联查询)
2、输出映射
resultType:
如果作为输出的映射,只有查询出来的列名和pojo的属性名一致,该列才可以映射成功,如果查询出来的内容和pojo的属性名全部不一致,没有创建pojo对象
只要查询出来的内容和pojo的属性名有一个一致,就会创建pojo对象
输出简单类型:
用户信息的综合查询的列表总数,通过查询总数和查询列表才可以实现分页
只有查询出来的结果只有一行且一列,可以使用简单类型进行输出映射
输出pojo对象、输出pojo列表:
不管输出是pojo单个对象还是一个列表,在mapper.xml中resultType指定的类型是一样的
在mapper.java中指定的类型的返回值不一样
输出单个对象:方法返回值是单个对象类型
输出pojo对象列表:方法的返回值就是List,里面是pojo
动态代理中生成的对象根据mapper方法的返回值类型来确定是调用selectOne还是selectList
resultMap:
mybatis中可以使用resultMap完成高级输出结果的映射
使用方法:
如果说查询出来的列名和pojo的属性名不一致,通过定义一个resultMap来对列名和pojo属性名之间做一个映射关系
1、定义resultMap
2、使用resultMap作为statement的映射类型
需求:将下面的SQL使用user类完成映射
select id id_,username username_ from user where id=#{value}
user类中属性名和上边查询列名不一致
步骤:
1、定义resultMap
2、输出类型设置为自定义的resultMap
resultType:必须列名和属性名一致
resultMap:不一致的时候可以进行自定义
3、动态SQL
mybatis的核心是对SQL语句进行灵活的操作,通过表达式对SQL进行判断,对SQL进行灵活拼接、组装
需求:
用户信息综合查询列表和用户信息查询列表总数这两个statement的定义,要使用动态SQL
对查询条件进行判断,如果输入的参数不为空,才进行查询条件的拼接
where标签可以自动完成拼接并且去掉拼接条件中的第一个and
if标签进行判断,可以判断相应的条件是否为空
需求2:
将上边实现的动态SQL的代码块抽取出来,组成一个SQL片段,其他的statement中就可以来引用这个SQL片段
定义SQL片段:sql标签
引用SQL片段
在mapper.xml中定义的statement中引用SQL片段
foreach标签
向SQL传递数组或者List,mybatis使用foreach来解析
需求:
在用户查询列表和查询总数的statement,要增加多个id输入查询
SQL语句如下:
select * from user where 1=1 and(id=1 or id=2 or id=3)
在输入的参数类型中添加List<Integer>
修改mapper.xml
在查询条件中,查询定义成了SQL片段,需要修改SQL片段