黑马程序员技术交流社区
标题: 【石家庄校区】就业班_JavaEE_MyBatis [打印本页]
作者: 风中的消逝 时间: 2018-8-17 11:45
标题: 【石家庄校区】就业班_JavaEE_MyBatis
本帖最后由 小石姐姐 于 2018-8-30 20:23 编辑
【石家庄校区】就业班_JavaEE_MyBatis
一 概述
mybatis 半orm 持久层框架。
与hibernate区别:不能跨数据库,需要手写s q l
二 入门程序
1 导包 mybatis核心包以及lib的依赖包 因为要操作数据库 所以还要导数据库驱动包
2 编写po类 遵守po类的约定。
3 编写config文件 需要注意config文件书写有顺序要求。
<properties resource="db.properties">
加载属性文件
</properties>
<typealias>
为po类指定别名 简单类型mybatis已经帮我们默认指定了类型。 举个例子 int 别名: _int Integer 别名:int
如果是po类 则需要我们手动配置, 通常我们采用package方式来指定po类所属的package 。指定package扫描后,默认的别名是类名。
[Java] 纯文本查看 复制代码
<package name="cn.itheima.mybatis.po" />
</typealias>
<enviroments default=“”>
mybatis支持配置过个连接环境,通过defualt属性来指定当前选择哪个数据库环境。 default中的值要在下面的enviroment中存在。
<enviroment>
指定数据库连接信息和事物 如果与spring整合后,将由spring来管理,则不需要在配置了。
</enviroment>
</enviroments>
<mapper>
指定mapper文件 一般采用包扫描方式 采用包扫描的条件 1 同一个目录下;2 接口名和mapper映射文件名称要相同。
<package name="接口所在的包名">
还可以指定class即指定接口 通过指定接口的条件 1 在同一个目录下 2 接口名和mapper映射文件名称要相同。
<mapper class=“接口类”/>
还可以直接指定mapper映射文件 没有什么要求条件
<mapper resource=“文件”/>
</mapper>
4 编写mapper接口,即dao层接口。在mybatis中一般叫Mapper。 通常使用代理方式,则不需要编写实现类,只需要些接口。
不过要使用代理方式,则在mapper配置文件中的配置需要特殊指定。
namespace mapper的namespace要配置接口的全路径名称
select 的id statement的id要与接口中的方法名一样
parameterType parametertype要与接口中方法的参数 类型一致
resultType resultType要与接口中方法的返回值类型一致
这4个方面要与接口一一对应。
5 编写mapper配置文件,并且要与maper接口放在同一个目录下并且与接口同名 。 因为只有放在同一个目录下并且名称相同 才能在config配置文件中 通过package来扫描。
[Java] 纯文本查看 复制代码
<package name="cn.itheima.mybatis.po" />
</typealias>
<enviroments default=“”>
获取insert的主键 如果是自增长 则可以使用mys q l的last_insert_id()方法来获取最近一次insert或者update操作的主键ID
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey>
下面可以通过uuid来产生一个id uuid()返回的是带字母的字符串 也可以使用uuid_short()方法 该方法返回的是一个long类型
[AppleScript] 纯文本查看 复制代码
<selectKey keyProperty="id" resultType="string" order="BEFORE">
select uuid()
</selectKey>
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
下面这种方式也可以实现返回主键 useGeneratedKeys="true" keyProperty="id" useGeneratedKeys只支持自增长的情形。
当批量插入时,只能使用该种方式,不能使用select last_insert_id()。 因为select last_insert_id()批量插入时,只能取到第一条记录的id。
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
[Java] 纯文本查看 复制代码
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
类型别名也可以放在s q lsessionfactory中进行配置
三 Mapper动态代理方式开发
Mapper接口开发需要遵循以下规范:
1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个s q l 的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个s q l的resultType的类型相同
四 输入映射
简单数据类型 pojo类型 pojo的包装类型(pojo包装类型指的是pojo中包含其它pojo类对象)
五 输出映射
简单数据类型 pojo类型 集合 resultmap
六 动态s q l
当parametertype为pojo对象时,有可能会有多个综合查询条件,需要通过动态s q l进行拼接s q l。
1 if条件判断 where能用来只能去掉and
[Java] 纯文本查看 复制代码
<select id="findUser" parameterType="com.itheima.mybatis.po.User" resultType="com.itheima.mybatis.po.User">
select * from `user`
<where>
<if test="username!=null and username!=''">
and username like #{username}
</if>
<if test="sex!=null and sex!=''">
and sex = #{sex}
</if>
</where>
</select>
2 foreach 实现循环
实现 and id in (1,2,3,4)
<foreach collection="ids" item="id" separator="," open=" and id in (" colse=")">
#{id} // 表示循环体
</foreach>
//collection表示要遍历的集合 item表示从集合取出的元素 open表示在循环拼接的字符串前面加的内容 colse表示在循环拼接的字符串后面加的内容 separator表示循环元素之间的分隔符
实现 insert into user(username,sex,birthday,address) values(x,x,x,x),(x,x,x,x) ,... 批量插入
要求mybatis版本在3.3.1以上 可以通过foreach来实现批量插入。
[Java] 纯文本查看 复制代码
<insert id=“” parameterType="" useGeneratedKeys="true" keyProperty="id">
insert into user(username,sex,birthday,address) values
<foreach collection="userList" item="user" separator=",">
(#{user.username},#{user.birthday},#{user.sex},#{user.address})
</foreach>
</insert>
3s q l片段
定义s q l片段
[Java] 纯文本查看 复制代码
<s q l id="query_user_where">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</s q l>
使用include引用
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<include refid="query_user_where"/>
</where>
</select>
做update时,set标签能用来智能去掉,
七 关联查询
有二种方式
1 提供po进行对多个表的字段进行封装,采用resulttype进行指定返回类型。
2 在mappper映射文件中提供resultMap来进行封装
返回resulttype的二种情况:
一对一情况下:
1 先在po类中添加关联对象
2[Java] 纯文本查看 复制代码
<resultMap type="com.itheima.mybatis.po.Order" id="order_user_resultmap">
<id property="id" column="id"/>
<result property="userId" column="userid"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
<!-- 一对一映射 property中指定order中的user对象 一对一采用Javatype指定类型-->
<association property="user" javaType="com.itheima.mybatis.po.User">
<id property="id" column="userid"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
</association>
</resultMap>
一对多情况下:
1 先在po类中添加关联对象集合
2 [Java] 纯文本查看 复制代码
<resultMap type="com.itheima.mybatis.po.User" id="user_order_resultmap">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!-- 一对多 property中指定user中的orders集合对象 一对多采用ofType指定类型-->
<collection property="orders" ofType="com.itheima.mybatis.po.Order">
<id property="id" column="oid"/>
<result property="createtime" column="createtime"/>
<result property="number" column="number"/>
</collection>
</resultMap>
需要注意采用resultmap时,s q l中需要对关联查询的多张表的id主键都需要进行查询。并在配置文件中显示指定。
八 整合spring
整合思路
1、s q lSessionFactory对象应该放到spring容器中作为单例存在。
2、Mapper代理,应该从spring容器中直接获得mapper的代理对象。
3、数据库的连接以及数据库连接池事务管理都交给spring容器来完成。
九 补充
mys q l 自动提交
oracle 不自动提交
jdbc自动提交
hibernate mybatis 默认对增删改 都开启了事物操作 , 所以我们需要手动提交事物。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |