mybatis是一个轻量级并且开源的数据持久化技术框架,其是基于JDBC对其进行封装,将对数据库的连接,驱动等繁琐的过程都被简化了,我们只需要重点关注SQL的实现和映射就可以了。
使用步骤
mybatis的初步使用,要先创建一个工厂建造者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
然后用工厂建造者创建出SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
这里的参数in代表的是mybatis的核心配置文件的字节流文件。
注:传入核心配置文件,默认从classPath下读取。(classpath是编译后产生的bin目录下的文件)
利用工厂对象创建出SqlSession 对象
SqlSession session = factory.openSession();
最主要的就是得到SqlSession对象,并通过此来进行对SQL的操作
在每次使用mybatis时进行的准备工作,基本步骤完全一致,避免代码冗余可以将此过程封装成一个工具类,代码如下:
public class MybatisUtil {
//SqlSessionFactory一旦创建,就要一直存在,所以只需要在第一次运行时创建出来对象就可以
private static SqlSessionFactory factory = null;
static {//保证在方法前执行
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
try {
//读取mybatis的核心配置文件
factory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
//定义连接方法
public static SqlSession getSession() {
SqlSession sqlSession = null;
if(factory != null) {
sqlSession = factory.openSession();
}
return sqlSession;
}
}
SQL映射器(写SQL语句的xml文件),其内容包括:版本信息和SQL语句等
获取映射器
获取mapper文件的两种方式:
(1)根据名字获取
//在用session对象的selectList()方法(查找的方法),在配置文件中找相对应的SQL语句,通过SQL映射(完全限定名+映射的ID)
//查找的SQL语句返回的是多个数据,这里用集合来接收
List<Website> list = session.selectList("com.feng.mybatisDemon.mapper.WebsiteMapper.findAll");
(2)根据xml文件+接口的方式
一个xml文件对应一个映射器接口,并且xml文件(映射器)中的每一个SQL都是对应接口中的一个方法(SQL的id和方法名一致,参数也一致)
这种方式,接口的实现类不需要自己写,而是mybatis已经通过动态代理的方式写好了,我们自己只需要通过sqlsesion对象的getMapper()方法直接使用就好(此方案传入的是接口的class对象)。
在映射器中,只需给SQL传一个参数,若为Java本来就有的类型,就不需要设置ParameterType,但是需要设置resultType(结果集的类型)。
在映射器中,若要使用模糊查询,传统的拼接方法需要用户自行手动进行拼接%,用SQL自带的concat()方法能够避免此现象。
concat(A,B,C) ==> 代表字符串A,B,C进行拼接,拼接成一个字符串ABC。
通过此函数,用户就只需要提供一个关键字即可。
传入多个参数
(1)通过注解@Param()
//法一:通过注解的方式
List<Website> findWebBetweenAge(@Param("paramBegin") int begin, @Param("paramEnd") int end);
<select id="findWebBetweenAge" resultType="com.feng.entity.Website">
select * from website
where age between #{paramBegin} and #{paramEnd}
</select>
注:<mapper> 是映射器的根节点,所有的SQL都必须在这个结点之间。
<mapper>的属性:namespace->设置当前映射器的命名空间(包名+文件名字)
(2)使用自定义JavaBean封装多个参数
public List<xxxCondition> selectxxxCondition(xxxCondition condition);
<!-- 使用自定义JavaBean封装多个参数-->
<select id="selectEarthquakeListByCondition" resultType="com.feng.entity.Earthquake" parameterType="com.feng.mapper.EarthquakeCondition">
select * from copy_earthquake where id between #{idBegin} AND #{idEnd}
</select>
自己定义一个condition类,可以实现区间范围或者其他条件下对于某一个实体类对象在数据库中映射的查找。
动态SQL
当需要有分组或者多条件查询时,SQL语句会非常麻烦,而动态SQL能够很好地解决这个问题,它能够用少量的代码实现需要大量代码才能实现的功能
(1)<if>标签
用于判断,如果条件成立才会执行下面的SQL语句,条件不成立就不执行,test属性内写判断条件
<select id="findWebByInfo" resultType="***" parameterType="***">
select * from website where country = #{country}
<!-- 判断名字-->
<if test="name != null and name !=''">
AND name LIKE concat('%',#{name},'%')
</if>
<!-- 判断url-->
<if test="url != null and url != ''">
AND url LIKE concat('%',#{url},'%')
</if>
<!-- 判断age-->
<if test="age > 0">
AND age =#{age}
</if>
</select>
(2)<choose>标签
这个标签下有多个<when>标签,如果when中的条件成立就会执行,不成立就不会执行,这个标签就像switch,有多重条件分支时使用。且通常和<where>标签一起使用
<!-- 用choose标签行层一组判断-->
<select id="findWebByInfo2" resultType="**" parameterType="**">
select * from website
<!-- where 标签标识mybatis自动处理where,就不需要手动在外面写where了-->
<where>
<choose>
<!-- 判断名字-->
<when test="name != null and name !=''">
AND name LIKE concat('%',#{name},'%')
</when>
<!-- 判断url-->
<when test="url != null and url != ''">
AND url LIKE concat('%',#{url},'%')
</when>
<!-- 判断age-->
<when test="age > 0">
AND age =#{age}
</when>
<!-- 若上面的when都不符合,就会最后判断这个-->
<otherwise>
AND country = #{country}
</otherwise>
</choose>
</where>
(3)<set>标签。
此标签用于修改数据
<!-- 动态更新-->
<update id="updateWebsiteInfo">
UPDATE website
<set>
<if test="name != null and name !=''">
name = #{name},
</if>
<!-- 判断url-->
<if test="url != null and url != ''">
url = #{url},
</if>
<!-- 判断age-->
<if test="age > 0">
age = #{age}
</if>
</set>
WHERE id = #{id}
</update>
(4)<foreach>标签
若在SQL语句中涉及到了in,表示条件是一个区间范围,这个时候就需要在mapper中使用此标签;其中的属性为:
collection==>在不同情况下,与不同的选择值,若参数为同一类型且是单参数,属性值为list和array;若是多参数,就需要将参数封装成一个Map,且属性值是key
item==>在遍历元素时,元素的别名
separator==>在元素遍历时,用什么来做分割
open/close==>表示该语句以什么字符打开,以什么字符关闭
<select id="findAllByCountry" resultType="com.feng.entity.Website">
SELECT * FROM website
WHERE country IN
<foreach collection="list" item="country" separator="," open="(" close=")">
#{country}
</foreach>
</select>