简述
ORM持久层框架,动态sql,逆向工程
优点
1、目前最主流的持久层框架为hibernate与mybatis,而且国内目前情况使用Mybatis的公司比hibernate要多。
2、Hibernate学习门槛不低,要精通门槛更高。门槛高在怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate缓存与数据加载策略方面需要你的经验和能力都很强才行。国内目前前的情况精通hibernate技术大牛非常少。
3、sql优化方面,Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。当然了,Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。说得更深入一些,如果有个查询要关联多张表,比如5张表,10张表时,而且,我们要取的字段只是其中几张表的部分字段。这时用hibernate时就会显得非常力不从心。就算用hibernate的sqlquery,后续的维护工作也会让人发狂。
应用场景
解决jdbc存在的问题
频繁创建数据库连接,耗费数据库资源
查询语句硬编码
查询参数硬编码
遍历resultSet麻烦
配置环境
1、jar包:两个
2、映射文件
各个pojo类的映射文件
3、配置文件
在SqlMapConfig.xml配置mapper
映射文件解析
<select id=”getUserByid” parameterType=”int” resultType=”pojo 类包名”> ,包含入参数据类型,返回结果数据类型
1、sql语句
#{}:点位符,相当于jdbc的?
${}:字符串拼接指令,有百分号 ‘%${value}%’ ,入参为普通类型只能写value,对象类型则写它的属性名
2、子标签 selectKey,解决级联操作
属性
keyProperty :pojo类主属性
resultType :主键数据类型
order:何时返回
</select>
Web层测试编码步骤
1、创建SqlSessionFactoryBuilder类
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder
2、创建输入流
inputStream = Resoutces.getResourceAsStream(“核心配置文件名”)
3、通过输入流创建的SqlSessionFactory
ssfb.build(inputStream)
4、创建SqlSession对象
sqlSession = sqlSessionFactory.openSession
5、查询
sqlSession .selcetOne(“命名空间.方法(id名)”,传入参数)
6、提交事务(不想写的话在openSession里写true)
sqlSession.commit()
7、释放资源
sqlSession.close
架构图
动态代理
1、实质:映射文件代替dao层实现类,不用自己写实现类
2、编写规则
1、namespace是接口的全路径名
2、接口方法必须与sql id一致
3、接口的入参与parameterType类型一致
4、接口的返回值必须与resultType类型一致
SqlMapConfig.xml配置信息
properties属性
1、<!-- 加载规则,首先加载标签内部属性,再加载外部文件,名称相同时,会替换相同名称的内容 -->
<properties resource="jdbc.properties">
<property name="jdbc.username" value="root1"/>
<property name="jdbc.password" value="root"/>
</properties>
2、jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
自定义别名
<typeAliases>
<!-- 单个别名定义 -->
<!-- <typeAlias type="com.itheima.mybatis.pojo.User" alias="user"/> -->
<!-- 别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名为类名,不区分大小写-->
<package name="com.itheima.mybatis.pojo"/>
</typeAliases>
mappers
<mappers>
1、第一种方式,加载 resource
<mapper resource="mapper/user.xml"/>
2、第二种方式,class扫描器要求:
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
<mapper class="com.itheima.mybatis.mapper.UserMapper"/>
3、第三种方式,包扫描器要求(推荐使用此方式):
1、映射文件与接口同一目录下
2、映射文件名必需与接口文件名称一致
<package name="com.itheima.mybatis.mapper"/>
</mappers>
parameterType输入类型
1、传递简单类型
2、传递pojo对象
Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。
3、传递pojo包装对象
映射文件与sql
1、resultType:如果要返回数据集合,只需设定为每一个元素的数据类型
2、包装的pojo取值通过 "."来获取
<select id="getUserByQueryVo" parameterType="queryvo" resultType="com.itheima.mybatis.pojo.User">
SELECT * FROM USER WHERE username LIKE '%${user.username}%'
</select>
resultType输出类型
1、输出简单类型
<select id="getUserCount" resultType="int">
SELECT COUNT(1) FROM USER
</select>
2、输出pojo对象
3、输出pojo列表
输出resultMap
1、resultMap入门
type:映射成的pojo类型
id:resultMap唯一标识
2、例子:
<resultMap type="order" id="orderMap">
<!-- id标签用于绑定主键 -->
<!-- <id property="id" column="id"/> -->
<!-- 使用result绑定普通字段 -->
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</resultMap>
<!-- 使用resultMap -->
<select id="getOrderListResultMap" resultMap="orderMap">
SELECT * FROM `order`
</select>
动态sql
1、If
<select id="getUserByWhere" parameterType="user" resultType="com.itheima.mybatis.pojo.User">
SELECT * FROM USER where 1 = 1
<if test="id != null">
and id = #{id}
</if>
<if test="username != null and username != ''">
and username LIKE '%${username}%'
</if>
</select>
2、Where
<select id="getUserByWhere2" parameterType="user"
resultType="com.itheima.mybatis.pojo.User">
SELECT
*
FROM USER
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="username != null and username != ''">
and username LIKE '%${username}%'
</if>
</where>
</select>
3、Foreach
<select id="getUserByIds" parameterType="queryvo"
resultType="com.itheima.mybatis.pojo.User">
SELECT
*
FROM USER
<where>
<!-- id IN(1,10,25,30,34) -->
<!-- foreach循环标签
collection:要遍历的集合,来源入参
open:循环开始前的sql
separator:分隔符
close:循环结束拼接的sql
-->
<foreach item="uid" collection="ids" open="id IN(" separator=","
close=")">
#{uid}
</foreach> </where>
</select>
4、Sql片段
1、定义
<!-- sql片段 定义,id:片段唯一标识 -->
<sql id="user_column">
`id`,`username`,`birthday`,`sex`,`address`,`uuid2`
</sql>
2、使用
SELECT
<!-- sql片段的使用:include:引入sql片段,refid引入片段id -->
<include refid="user_column" />
FROM USER
关联查询
1、一对一关联
使用resultType
新建OrderUser的pojo,继承自Order。
修改order的映射文件,新增查询方法getOrderUser。
<select id="getOrderUser" resultType="orderuser">
SELECT
o.`id`,
o.`user_id` userId,
o.`number`,
o.`createtime`,
o.`note`,
u.`username`,
u.`address`
FROM `order` o
LEFT JOIN `user` u
ON u.id = o.`user_id`
</select>
使用resultMap
改造order的pojo
修改order的映射文件
<resultMap type="order" id="order_user_map">
<!-- id标签用于绑定主键 -->
<id property="id" column="id"/>
<!-- 使用result绑定普通字段 -->
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/
<!-- association:配置一对一关联
property:绑定的用户属性
javaType:属性数据类型,支持别名
-->
<association property="user" javaType="com.itheima.mybatis.pojo.User">
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
<result property="sex" column="sex"/>
</association>
</resultMap>
2、一对多关联
改造user的pojo
修改user的映射文件
<!-- 一对多关联查询 -->
<resultMap type="user" id="user_order_map">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="birthday" column="birthday" />
<result property="address" column="address" />
<result property="sex" column="sex" />
<result property="uuid2" column="uuid2" />
<!-- collection:配置一对多关系
property:用户下的order属性
ofType:property的数据类型,支持别名
-->
<collection property="orders" ofType="order">
<!-- id标签用于绑定主键 -->
<id property="id" column="oid"/>
<!-- 使用result绑定普通字段 -->
<result property="userId" column="id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
</collection>
</resultMap>
<!-- 一对多关联查询 -->
<select id="getUserOrder" resultMap="user_order_map">
SELECT
u.`id`,
u.`username`,
u.`birthday`,
u.`sex`,
u.`address`,
u.`uuid2`,
o.`id` oid,
o.`number`,
o.`createtime`
FROM `user` u
LEFT JOIN `order` o
ON o.`user_id` = u.`id`
</select>
Mybatis逆向工程
优点:自动生成sql语句
配置mapper生成的详细信息注意的点:
1、 添加要生成的数据库表
2、 po文件所在包路径
3、 mapper文件所在包路径