Mybatis学习之路(二)
3. mybatis开发dao两种方法
1.原始dao开发方法(程序需要编写dao接口和dao实现类)
2.mybatis的mapper接口(相当于dao接口)代理开发方法
3.1 SqlSession使用范围
3.1.1 SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理
SqlSessionFactoryBuilder在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
3.1.2 SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理SqlSessionFactory
(工厂一旦创建,使用一个实例)
将来mybatis和spring整合后,使用单例模式管理SqlSessionFactory。
3.1.3 SqlSession
SqlSession 是一个面向用户(程序员)的接口。
SqlSession 中提供了许多操作数据库的方法:
selectOne(返回单个对象)、selectList(返回单个或多个对象)、
SqlSession是线程不安全的,在SqlSession 实现类中除了有接口中的方法(操作数据库的方法)还有数据域的属性。
SqlSession最佳应用场合在方法体内,定义成局部变量。3.2原始dao开发方法(程序需要编写dao接口和dao实现类)
3.2.1 思路
程序员需要写dao接口和dao实现类。
需要向dao实现类中注入SqlSessionFactory ,在方法体内通过SqlSessionFactory 创建SqlSession
3.2.2 dao接口
UserDao接口
UserDao的实现类
3.2.3 测试代码
3.2.4 总结原始dao开发问题
1.dao接口实现类方法中存在大量的模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量
2.调用sqlsession方法时将statement的id硬编码了
3.调用sqlsession方法时,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
3.3 mybatis的mapper接口(相当于dao接口)代理开发方法
3.3.1 思路
程序员还需要编写mapper.xml映射文件
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。mybatis可以自动生成mapper接口实现类代理对象。
开发规范:
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
指定的类型一致。
总结:以上开发规范主要是对下边的代码进行统一生成
User user=sqlSession.selectOne(“test.findUserById”,id);
sqlSession.insert("test.insertUser",user);
3.3.2 mapper.java
3.3.3 mapper.xml
3.3.4 在SqlMapConfig.xml中加载mapper.xml配置文件
3.3.5 测试
3.3.6 代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库
3.3.6.1 mapper接口方法参数只能有一个是否影响系统开发
mapper接口方法参数只能有一个,系统是否不利于扩展维护。
系统框架中,dao层的代码是被业务层公用的。
即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。
注意:持久层方法的参数可以包装类型、map……,service方法中建议不要使用包装类型(不利于业务层的可扩展)
4. mybatis配置文件sqlMapConfig.xml
mybatis的全局配置文件sqlMapConfig.xml,配置内容如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environments(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
4.1 properties(属性)
需求:
将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值
在SqlMapConfig.xml中就不需要对数据库连接参数硬编码
将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其他xml可以引用该db.properties。
在SqlMapConfig.xml中加载db.properties文件:
properties特性:
注意:mybatis将按照下面的顺序来加载属性:
◆在properties元素体内定义的属性首先被读取。
◆然后会读取properties元素中resource或url加载的属性,它会覆盖已读取的同名属性。
◆最后读取parameterType传递的属性,它会覆盖已读取的同名属性。
建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
在properties文件中定义属性名要有一定的特殊性,例如:jdbc.xxxx.xxxx
4.2 settings全局参数配置
Mybatis框架在运行时可以调整一些运行参数。
比如:开启二级缓存、开启延迟加载
全局参数将会影响mybatis的运行行为
4.3 typeAliases(别名) 重点
4.3.1 需求
在mapper.xml中,定义很多的statement,statement需要parameterType指定参数的类型、需要resultType指定输出结果的映射类型。
如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发
4.3.2 自定义别名
4.3.2.1单个别名定义:
引用别名:
4.3.2.2批量别名(常用):
resultType则为类名,(不区分大小写)
4.4 typeHandlers(类型处理器)
mybatis中通过typeHandlers完成jdbc类型和java类型的转换。
通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义
4.5 mappers(映射配置)
4.5.1通过resource单个映射文件的加载
4.5.2 通过mapper接口加载
4.5.3通过package批量加载mapper(推荐使用)
5. mabatis核心:mybatis输入映射,mybatis输出映射
5.1输入映射
通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo类型
5.1.1 传递pojo的包装对象
5.1.1.1 需求
完成用户信息的综合查询,需要传入查询条件和复杂(可能包括用户信息、其他信息,比如商品、订单的)
5.1.1.2 定义包装类型pojo
针对上面的需求,建议使用自定义的包装类的pojo
在包装类型的pojo中将复杂类型的查询条件包装进去
5.1.1.3 mapper.xml
在UserMapper.xml中定义用户信息综合查询(查询条件复杂,通过高级查询)
5.1.1.4 mapper.java
5.1.1.5 测试代码
5.2输出映射
5.2.1 resultType
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
5.2.1.1 输出简单类型
5.2.1.1.1需求
用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。
5.2.1.1.2 mapper.xml
5.2.1.1.3 mapper.java
5.2.1.1.4 测试代码
5.2.1.1.5 小结
查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。
5.2.1.2 输出pojo对象和pojo列表
不管是输出的pojo对象还是一个列表(list中包括Pojo),在mapper.xml中resultType中指定的类型是一样的。在mapper.java指定的方法返回值类型不一样:
1、输出单个pojo对象,方法返回值是单个对象类型
2、输出多个pojo对象,方法返回值是列表类型list<pojo>
生成的动态代理对象中是根据mapper方法的返回值类型确定是调用selectOne(返回单个对象调用),还是selectList(返回集合对象调用)
5.2.2 resultMap
mybatis中使用resultMap完成高级输出结果映射。
5.2.2.1 resultMap使用方法
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系。
1.定义resultMap
2.使用resultMap作为statement的输出映射类型
5.2.2.2 将下边的sql使用User完成映射
select id id_,username username_ from userwhere id=#{value}
User类中属性名和上边查询的列名不一致。
5.2.2.2.1 定义resultMap
5.2.2.2.2使用resultMap作为statement的输出映射类型
5.2.2.2.3 mapper.xml
5.2.2.2.4 mapper.java
5.2.2.2.5 测试代码
5.2.3 小结
使用resultType进行输出映出,只有查询出来的列名和Pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系。