第一章 基础
一 基础
1 使用mybatis好处:
i. 使用数据库连接池管理数据库连接
ii. 将sql语句配置到xml配置中,即使sql变化,不需要对java代码重新编译
iii. 将sql语句及占位符号和参数全部配置在xml中
2 mybatis框架
3 SqlMapConfig.xml
配置mybatis的运行环境,数据源、事务等。
加载映射文件(如userMapper.xml)。
4 userMapper.xml
主要是写sql语句,进而对数据库进行操作,包括基本的增删改查。其中主要参数有:
parameterType: 在映射文件中通过parameterType指定输入参数的类型。建议使用自定义的pojo类型。
resultType: 在映射文件中通过resultType指定输出结果的类型。查询出来的列名和pojo对象名称一致才能映射成功。
resultMap:如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。
resultMap 使用方式:
1、 先定义一个resultMap
2、 使用resultMap作为statement的输出映射类型
<!-- 定义resultMap
将SELECT id id_,username username_ FROM USER 和User类中的属性作一个映射关系
type:resultMap最终映射的java对象类型,可以使用别名
id:对resultMap的唯一标识
-->
<resultMap type="user" id="userResultMap">
<!-- id表示查询结果集中唯一标识
column:查询出来的列名
property:type指定的pojo类型中的属性名
最终resultMap对column和property作一个映射关系 (对应关系)
-->
<id column="id_" property="id"/>
<!--
result:对普通名映射定义
column:查询出来的列名
property:type指定的pojo类型中的属性名
最终resultMap对column和property作一个映射关系 (对应关系)
-->
<result column="username_" property="username"/>
</resultMap>
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
SELECT id id_,username username_ FROM USER WHERE id=#{value}
</select>
#{}和${}区别:
#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,${}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE id=#{value}
</select>
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>
5 hibernate 和 mybatis 区别
hibernate:是一个标准ORM框架(对象关系映射),不需要程序写sql,sql语句自动生成了。
对sql语句进行优化、修改比较困难的。适用需求变化不多的项目。
mybatis:需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。
二 mybatis开发dao的方法
1 sqlSession使用范围
SqlSessionFactoryBuilder:
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,不需要使用单例管理。
SqlSessionFactory:
通过SqlSessionFactory创建SqlSession,使用单例模式管理(一旦创建,使用一个实例)。
SqlSession:
SqlSession是一个面向用户(程序员)的接口。
SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)。
SqlSession是线程不安全的,最好在方法体内,定义成局部变量使用。
2 mapper代理方法
需要遵循一些规范:
1、在mapper.xml中namespace等于mapper接口地址
<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址
-->
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
2、mapper.java接口中的方法名和mapper.xml中statement的id一致
3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
// 代码片段
// mapper.java
public interface UserMapper {
//根据id查询用户信息
public User findUserById(int id) throws Exception;
}
// userMapper.xml
<select id="findUserById" parameterType="int" resultType="user">
SELECT * FROM USER WHERE id=#{value}
</select>
// 测试代码
@Test
public void testFindUserById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper的方法
User user = userMapper.findUserById(1);
System.out.println(user);
}
3 SqlMapConfig.xml
配置内容如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
properties
可以将数据库连接参数单独配置在一个db.properties文件中,用properties属性引用过来;
MyBatis 将按照下面的顺序来加载属性:
在 properties 元素体内定义的属性首先被读取。
然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
最后读取parameterType传递的属性,它会覆盖已读取的同名属性。
settings全局参数配置
mybatis框架在运行时可以调整一些运行参数。比如:开启二级缓存、开启延迟加载。
typeAliases
别名,有时候mapper.xml中路径名较长,可以用这个标签来起别名。
<!-- 别名定义 -->
<typeAliases>
<!-- 针对单个别名定义-->
<!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
<!-- 批量别名定义
指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)
-->
<package name="cn.itcast.mybatis.po"/>
</typeAliases>
typeHandlers
mybatis中通过typeHandlers完成jdbc类型和java类型的转换。
通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义。
mappers(映射配置)
1、通过resource加载单个映射文件
2、通过mapper接口加载单个mapper
3、批量加载mapper(推荐使用)
<mappers>
<!--通过resource方法一次加载一个映射文件 -->
<mapper resource="mapper/UserMapper.xml"/>
<!-- 通过mapper接口加载单个 映射文件
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中上边规范的前提是:使用的是mapper代理方法
-->
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
<!-- 批量加载mapper
指定mapper接口的包名,mybatis自动扫描包下边所有mapper接口进行加载
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
上边规范的前提是:使用的是mapper代理方法
-->
<package name="cn.itcast.mybatis.mapper"/>
</mappers>
4 动态 SQL
对sql进行灵活拼接、组装。
sql片段:
将上面动态sql判断代码抽取出来,组成一个片段,其它的statement中就可以引用sql片段。
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and user.sex = #{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and user.username LIKE '%${userCustom.username}%'
</if>
<if test="ids!=null">
<!-- 使用 foreach遍历传入ids
collection:指定输入 对象中集合属性
item:每个遍历生成对象中
open:开始遍历时拼接的串
close:结束遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
-->
<!-- 使用实现下边的sql拼接:
AND (id=1 OR id=10 OR id=16)
-->
<foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
<!-- 每个遍历需要拼接的串 -->
id=#{user_id}
</foreach>
<!-- 实现 “ and id IN(1,10,16)”拼接 -->
<!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
每个遍历需要拼接的串
#{user_id}
</foreach> -->
</if>
</if>
</sql>
<select id="findUserList" parameterType="cn.itcast.mybatis.po.UserQueryVo"
resultType="cn.itcast.mybatis.po.UserCustom">
SELECT * FROM USER
<!--
where可以自动去掉条件中的第一个and
-->
<where>
<!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
<include refid="query_user_where"></include>
<!-- 在这里还要引用其它的sql片段 -->
</where>
</select>
foreach :向sql传递数组或List,mybatis使用foreach解析,如上面代码中的foreach。