使用jdbc开发时,和mybatis相比的不足
1,数据库连接,使用时就创建,不使用就释放,对数据库进行频繁连接开关和关闭,造成数据库资源浪费,影响数据库的性能
解决:使用数据库连接池管理数据库的连接
2,sql语句使用硬编码在java程序中,修改sql语句,就需要重新编译java代码,不利于系统维护
解决:把sql语句放在xml配置文件中,修改sql语句也不需要重新编译java代码
3,向预编译语句PreparedStatement中设置参数,对占位符位置和设置参数值,硬编码,修改sql语句也不需要重新编译java代码
解决:把sql语句和占位符设置参数值放在xml配置文件中
4,从result中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码
解决:将查询的结果集,自动映射成 java对象
二 mybatis框架,是一个持久层框架,是apache下的顶级项目
mybatis让程序员将主要精力放在sql上,通过mytabis提供的映射方式,自动生成满足需要的sql语句
mybatis可以向PreparedStatement中输入参数自动进行输入映射,将查询结果集灵活的映射成Java对象(输出映射),输入映射和输出映射这是mybatis的核心
mybatis框架执行流程图
三 mybatis的工作环境搭建和架构示意图
四 mybatis的开发
1.映射文件的开发如下图
2,映射文件配置好了之后,还需要在全局配置文件sqlMapConfig.xml中添加映射文件
3,sqlsession会话去执行操作查询数据库映射文件,下图中的错误纠正为’%${value}%’
查询出的是单条记录使用selectOne,下图中的错误纠正为把“1”改为int类型的1
sqlsession.selectOne(“test.findUserById”, 1);
查询出的是多条记录使用selectList
sqlsession.selectList(“test.findUserByName”, “hello”);
4,添加用户映射文件配置如下:
程序代码:
5,总结:
四 mybatis开发dao方法
mybatis的配置文件不变
1,先使用原型的开发dao方法
开发接口
2, 开发接口实现
3, 测试代码
4,总结
五 mybatis利用mapper代理开发dao(重点掌握)
mapper代理开发,就不需要接口的实现类,只需要接口UserMapper.java和映射文件UserMapper.xml就可以了,但是遵循一定的开发规范:
1,在UserMapper.xml文件中namespace等于UserMapper接口地址
2,UserMapper.java接口中的方法名要和UserMapper.xml中的statement的id一致
3,UserMapper.java接口中的方法输入参数要和UserMapper.xml中的statement的parameterType指定的类型一致
4,UserMapper.java接口中的方法的返回值类型要和UserMapper.xml中的statement的resultType指定的类型一致
测试代码:
上图画线区域:这里没有实现接口的实现类,而是使用mybatis生成的代理对象来生成UserMappper接口的对象,从而能够调用其方法
mapper代理开发dao出现的问题总结:
1,代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库,也可以使用selectList查询。
如果mapper方法返回集合对象,代理对象内部通过selectList查询 数据库,不能使用selectOne查询,否则会出错。
问题是: 编译期间不会报错,二者容易写错使用。
2,mapper接口方法参数只有一个
根据规范编写的代理对象的传入参数只能有一个(mapper.xml文件中的parameterType参数只有一个),不利于系统的扩展
解决:即使mapper接口中只有一个参数,可以使用包装类型的pojo满足不同的业务方法需求
mybatis的一些细节剖析:
1,全局配置文件sqlMapConfig.xml中配置内容如下:
- properties(属性)
注意:mybatis将按照下面的顺序来加载属性:
(1)在properties元素体内定义的属性首先被读取。(可以在此属性中加入jdbc的配置文件db.properties),在sqlMapConfig.xml中就不需要对数据库连接参数进行硬编码了。
- settings全局参数设置
mybatis框架运行时可以调整一些运行参数,会影响mybatis运行行为,所以建议不要随便修改
比如:二级缓存,开启延时加载。。。
- typeAliases(别名) 重点掌握
<typeAliases>
<!--针对单个别名定义
type:类型的路径
alias:别名 -->
<typeAlias type="com.jary.mybatis.po.User" alias="user" />
<!--还可以进行批量别名定义
指定包名,mybatis自动扫描包中的po类 -->
<package name="com.jary.mybatis.po" />
</typeAliases>
上面的别名定义后,在mapper.xml中就可以这样使用了
user代替了输出结果类型com.jary.mybatis.po.User。
4.映射文件(mapper)
通过resource加载单个的映射文件
<mapper resource="mapper/UserMapper.xml" />
通过mapper接口加载单个mapper,要遵循一定的规范:
(1)前提是使用mapper代理开发(已经有4个规范)
(2)需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在同一目录下
<mapper class="com.jary.mybatis.mapper.UserMapper" />
通过批量加载mapper(推荐使用):实现条件是
要满足mapper接口加载映射文件和使用mapper代理开发同时满足
mybatis的一些细节剖析结束
mybatis的核心输入映射和输出映射开始:
输入映射
通过parameterType指定输入参数类型,类型可以是简单类型、hashmap、pojo的包装类型
1,传递pojo的包装对象
(1)需求
完成用户信息的综合查询,需要传入查询条件复杂(可能包括用户信息,商品信息,商品订单等),这样靠一个parameterType只能传入一个输入参数,所有需要pojo的包装类型来实现
(2)定义包装类型pojo
针对上面的需求,在包装类型的pojo中把这些复杂的查询条件包装进去,定义包装类UserQueryVo,把需要查询的条件全部定义在里面
上图中标注的用户查询条件使用的是User的扩展类(因为User类一般是由逆向工程自动生成的,不要进行修改,所有使用的扩展类来实现)
输出映射
1,resultType
使用resultType进行输出映射时,只有查询输出结果列名和pojo中的属性名一致才可以,映射成功
如果查询出来的列名和pojo中的属性名没有一个一致的,就不会创建pojo对象
如果查询出来的列名和pojo中的属性名有一个一致,就会创建pojo对象
输出pojo对象和pojo列表
不管是输出的pojo单个对象还是一个列表(list中包含pojo),在mapper.xml中resultType指定的类型是一样的
在mapper.java指定的方法返回值类型不一样:
(1)输出单个pojo对象,方法返回值是个单个对象类型
(2)输出pojo对象list,方法返回值就是list对象类型
在动态代理对象中,是根据mapper方法的返回值类型来确定是调用selectOne(返回单个对象)还是selectList(返回集合对象)
2,resultMap
使用resultMap进行映射时,查询结果列名和pojo的属性名不一致时,resultMap会对列名和pojo属性名进行映射,保证其成功映射
使用resultMap需要这二步:
(1)定义resultMap
(2)使用resultMap作为statement的输出映射类型