一.原生的jdbc 存在的问题?
1.数据库的频繁的创建和关闭 浪费数据库的资源 影响操作的效率
使用数据的连接池
2.sql语句是硬编码,如果需求更换了 需要修改sql,需要重新编译,系统不移维护/扩展
将sql语句,统一的配置在文件中,修改sql就不需要修改java代码了
3.通过PreparedStatement向占位符设置参数,存在硬编码(参数的位置与参数的问题)
将sql中的占位符对应的参数配置在 配置文件中 能够自动的注入(输入映射)
4. 遍历查询结果集存在硬编码
自动进行sql查询结果的映射(输出映射)
二:mybatis的架构
Mybatis介绍
ibatis是Apache的一个开源项目,2010年迁移到了GoogleCode,改名叫mybatis
目前mybatis在Gethub上托管
Mybatis是一个优秀的持久层框架,他对jdbc做了封装,开发者只需要关注sql本身,而不需要花精力去做一些重复的繁琐的硬编码的操作【注册驱动/创建Connection/创建statement,手动的设置参数/手动的封装结果集】
Mybatis 的架构流程
三:.mybatis的入门程序
1.需求
实现用户的查询
更具id查询【单条记录】
更具用户名模糊查询【多条记录】
用户的添加 【返回添加记录的主键】
用户的修改
用户的删除
2.导入mybatis的jar包
mybatis-3.2.7.pdf 操作手册
mybatis-3.2.7.jar 核心jar包
lib\mybatis的依赖包
3.建立配置文件
mybatis.config.xml
4.建立实体类pojo 和 对应的映射文件
映射文件规范:
建议命名规则:表名+mapper.xml
早期ibatis:表名.xml
5.创建会话工厂【MybatisSessionFactory】
6.编写测试类
四:mybatis开发dao的两种方式
1.原始的dao开发方式(dao接口和dao的实现类)
2.mapper代理的方式(你只需要写接口 实现类有代理去实现)
Mapper代理的规范【重点】
程序员只需要写接口 dao接口的实现对象有mybatis自动生成代理对象
Mapper.xml 和 mapper.java【接口】 的规范
Mapper.xml映射文件【相当于User.xml】
1.mapper映射哇年的命名方式 建议:表名Mapper.xml
2.资源文件中创建mapper包存放这些mapper.xml
3.namespace指定为mapper接口的全限定名
4.把映射文件加载到主配置文件中
mapper.java接口
1.mybatis提出了mapper接口 相当于dao接口
2.mapper接口的命名规范建议:表名Mapper
Mapper.xml开发的规范
1.namespace指定为mapper接口的全限定名
此步骤的目的是:通过mapper.xml和mapper.java建立关系
2.mapper.xml中的id就是mapper.java中的方法名
3.mapper.xml中的parameterType就是mapper.java 中的参数类型
4.mapper.xml中的resultType就是mapper.java 中的返回值类型
Mybatis和hibernate区别
企业开发的技术选型
Mybatis:入门简单,程序容易上手开发。Mybatis需要程序员自己编写sql语句
是一个不完全的ORM框架,对sql修改和优化非常容易实现
Mybatis适合开发需求更换比较平凡的系统 如:互联网项目
Hibernate:入门比较吃力,使用hibernate不太容易实现高性能的开发。
Hibernate不用写SQL语句,是一个完全的ORM框架
Hibernate适合需求固定,对象模型固定的项目 如:企业的OA系统
Mybatis-config.xml详解
Mybatis-config.xml中配置的内容顺序如下:
Properties(属性) //配置一些属性 如引入jdbc的配置文件
Settings(全局配置参数) //ibatis早期开发 使用它配置性能参数 最大连接数/等待时间…….
typeAliases(类型别名) *****
typeHandlers(类型处理器) //java类型和jdbc进行映射
objectFactory (对象工厂)
plugins (插件)
environments 环境集合属性对象
environment 环境子属性对象
transactionManager 事物管理器
dataSource 数据源
mappers (映射器)******
五:输入映射与输出映射
通过parameterType完成输入映射 通过resultType和resultMap完成输出映射
1.parameterType 输入映射
parameterType 传递基本数据类型
parameterType 传递pojo类型
parameterType 传递pojo的包装类型
定义一个pojo包装类型。
1.定义一个扩展类继承pojo类型 里面既有扩展类型 又有基础类型
2.顶一个包装类型 提供把基础类型与扩展类型的属性 并get/set
2.resultType 输出的映射
指定输出结果的类型(pojo基本数据类型) 将sql查询的结果映射为java对象
注意:sql查询的列名要与resultType指定的pojo的属性相同,属性方可映射成功
3.resultMap 输出的映射
如果查询的列名和对战要映射的pojo的属性名不一致
使用resultMap将列名与pojo的属性做一一的对应关系
六:动态sql
Mybatis重点是对sql的灵活解析和处理
需求:自定义查询条件 【更具用户的名字/性别】
1用来查询对应的数据
2用来查询对应的条数
If/where
Sql片段
通过sql片段将通用的SQL语句抽取出来,单独定义,在其他的语句中可以直接引用写好的sql片段 从而达到sql片段的重用
常用的地方:where条件 查询的列
foreach
需求:更具多个id查询用户信息
一对一查询【多对一】
需求:
查询订单级联查询用户信息【用户的姓名/性别】
SQL语句
SELECTorders.*,user.username,user.sex
FROMorders,USER
WHEREorders.user_id=user.id
1.使用resultType实现
【以为返回的值不能使用一个对应的pojo类型来接收,那么只能使用扩展类
创建OrderCustom继承orders,添加用户的姓名/性别字段
创建扩展类型的经验:继承sql查询字段多的po类扩展少的字段】
代码的实现 Mapper.xml <!-- 查询订单级联查询用户信息【用户的姓名/性别】 --> <select id="findOrdersUser" resultType="orderCustom"> SELECT orders.*,user.username,user.sex FROM orders,USER WHERE orders.user_id=user.id </select> Mapper.java List<OrderCustom> findOrdersUser(); |
2.使用resultMap实现
【先在orders中创建一个user对象】
代码的实现 Mapper.xml <select id="findOrdersUserMap" resultMap="ordersMap"> SELECT orders.*,user.username,user.sex FROM orders,USER WHERE orders.user_id=user.id </select> Mapper.java List<Orders> findOrdersUserMap();
ResultMap <!-- resultMap:配置pojo与查询列的 对应的映射关系 --> <resultMap type="orders" id="ordersMap"> <!-- 完成订单信息的映射配置 id:订单的唯一标示 主键 --> <id column="id" property="id" /> <!-- 普通字段的映射 --> <result column="user_id" property="user_id" /> <result column="numbers" property="numbers"/> <result column="createtitle" property="createtitle"/> <result column="note" property="note"/> <!-- 完成关联信息的映射 association:用于将关联信息映射到指定的pojo中 property:将关联的信息映射到orders的那个属性中 javaType:关联信息映射到orders属性的类型 po.user --> <association property="user" javaType="user"> <!-- id:关联的唯一标示 property:要映射到User的哪个属性中 --> <id property="id" column="user_id" /> <result column="username" property="username"/> <result column="sex" property="sex"/> </association> </resultMap> |
开发中如何选取:
ResultType:要定义pojo 保证sql查询的列和pojo的属性对应,
这种方法超级简单,所有在应用中非常广泛
ResultMap:使用association完成一对一的映射 需要配置resultMap过程复杂
如果想使用延迟加载,只呢使用resultMap实现
为了方便对管理信息进行解析,我们的resultMap会将属性封装到对象中。
一对多查询
需求:
查询所有订单信息及订单明细信息以及用户信息
【在orders类中创建一个List<Orderdetail> orderdetails;】
Mapper.xml <!-- 查询所有订单信息以及用户信息及订单明细信息 --> <select id="findOrdersUserOrderdetailMap" resultMap="ordersMap2"> SELECT orders.*, user.username,user.sex, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num FROM orders,USER,orderdetail WHERE orders.user_id=user.id AND orderdetail.orders_id=orders.id </select> Mapper.java List<Orders> findOrdersUserOrderdetailMap();
resultMap <!-- resultMap 继承上面写好的map--> <resultMap type="orders" id="ordersMap2" extends="ordersMap"> <!-- 映射订单信息 extends--> <!-- 映射用户信息 extends--> <!-- 映射订单明细信息 --> <!-- property:将关联的信息映射到orders的哪个属性中 ofType:集合中pojo的类型 --> <collection property="orderdetails" ofType="orderdetail"> <!-- id 关联信息的唯一标示 --> <id column="orderdetail_id" property="id"/> <result column="items_num" property="items_num"/> <result column="items_id" property="items_id"/> </collection> </resultMap> |
一对多查询(复杂的)
需求
查询用户信息 关联查询订单及订单详情中的商品信息
Sql:
SELECTorders.*,
user.username,user.sex,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
items.name items_name,
items.pic items_pic
FROMorders,USER,orderdetail,items
WHEREorders.user_id=user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id=items.id
ResultMap进行映射
Pojo的定义
在user.java中添加 private List<Orders> orderlist;
在 orders.java 中添加 privateList<Orderdetail> orderdetails;
在Orderdetail.java 中添加 private Items items;
代码实现 Mapper.xml <!-- 查询用户信息 关联查询订单及订单详情中的商品信息 --> <select id="findUserOrdersDetail" resultMap="ordersMap3"> SELECT orders.*, user.username,user.sex, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, items.name items_name, items.pic items_pic FROM orders,USER,orderdetail,items WHERE orders.user_id=user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id=items.id </select> Mapper.java List<User> findUserOrdersDetail();
ResultMap !-- 查询用户信息 关联查询订单/订单详情/商品 --> <resultMap type="user" id="ordersMap3"> <!-- 用户信息映射 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <!-- 订单的映射 --> <collection property="orderlist" ofType="orders"> <id column="id" property="id"/> <result column="user_id" property="user_id"/> <result column="numbers" property="numbers"/> <result column="createtitle" property="createtitle"/> <result column="note" property="note"/> <!-- 订单详情的映射 --> <collection property="orderdetails" ofType="orderdetail"> <id column="orderdetail_id" property="id"/> <result column="items_id" property="items_id"/> <result column="items_num" property="items_num"/> <!-- 商品详情的映射 --> <association property="items" javaType="items"> <id column="items_id" property="id"/> <result column="items_name" property="name"/> <result column="items_pic" property="pic"/> </association> </collection> </collection> </resultMap> |