前言
公司新项目要换框架,采用BootStrap+Spring Mvc+Mybatis+PostgreSql,持久层由jdbcTemplate换成Mybatis还真是有点不习惯。虽然之前也用过一点Mybatis,但是也仅仅限于简单用过。趁着这次机会,把Mybatis好好学一下,下面就简单介绍一下如何使用Mybatis。请读者千万不要把这篇博客当成教程,因为这只是学习过程中的一点收获。
Mybatis
官网上说,Mybatis是支持定制化SQL、存储过程和高级映射的优秀的持久层框架,它几乎避免了所有JDBC代码、手动设置参数和获取结果集。Mybatis使用简单的XML配置,将接口和Java的POJO对象映射成数据库中的记录。
上面的介绍虽然只有两句话,但是信息量确实非常大。首先Mybatis是一个持久层框架,类似于Hibernate,它的前身是ibatis,当然ibatis我也不知道是个什么东东,不过用起来应该差不多。用过Hibernate的都知道,Hibernate是太重量级了,虽然很厉害,但是灵活性差很多,而且不容易移植,Mybatis就属于轻量级,配置简单,用起来也简单。
说它避免了JDBC代码、手动设置参数和获取结果集,确实是真的,JDBC的连接过程想必大家都了解过了,如果还不太清楚,请先移步《看JDBC轻松连接数据库,你值得拥有》,看完之后就发现,如果单纯用JDBC连接数据库,步骤实在太多了,所以这些框架改进的第一步就先是把JDBC这部分给封装了。在配置Mybatis的配置文件时,只需要把数据库连接信息配置上就可以了,比如驱动、数据库、用户名和密码等。至于不用手动设置参数,其实是不用在Java代码中进行设置。在新增一条数据时,如果表单数据不是只对应一个实体的话,就在Action中定义各个扩展属性,然后添加getter和setter方法,接着把该属性设置为实体的某个属性,接着使用添加方法入库。在Mybatis中直接在配置文件中配置好相应的数据库字段为参数,就不用在java类中设置属性了。获取结果集也一样,可以在XML中设置好结果集,然后返回时直接把该结果集作为返回类型就好了。
最后一句话也是强调了,Mybatis主要还是靠着它强大的配置文件来完成工作的。另外在XML配置中,Mybatis可以智能的将SQL语句中多余的and或者or条件去掉。
Spring+Mybatis框架搭建
创建的步骤不难,关键在于Spring和Mybatis的集成,其实也类似于Spring和Hibernate的集成,就是说让Spring来管理Mybatis。
1、创建Web项目
2、引入Spring的jar包,引入Spring的配置文件
3、引入Mybatis的jar包,引入Mybatis的配置文件
4、Spring和Mybatis的集成
首先得创建一个实体,例如创建一个User实体:
package com.entity;
public class User {
private Long id;
private String name;
private String password;
private String phone;
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
然后创建该实体的映射文件UserMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.manager.data.StudentMapper">
<resultMap type="User" id="userResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="password" column="password"/>
<result property="phone" column="phone"/>
<result property="email" column="email"/>
</resultMap>
<!-- 根据主键id查询用户 -->
<select id="queryUserById" parameterType="String" resultType="User" resultMap="userResult">
select * from user where id=#{id}
</select>
</mapper>
然后在Dao层为这个Mapper创建接口,接口中的方法,是要和mapper的xml文件中的select的id对应,以示这个接口要使用mapper的xml文件中的queryUserById这个select语句。
public interface UserMapper{
public User queryUserById(String id);
}
接下来配置Mybatis的配置文件mybatis-config.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias alias="User" type="com.entity"/>
</typeAliases>
<mappers>
<mapper resource="config/mapper/UserMapper.xml" />
</mappers>
</configuration>
集成的话,就是让Spring来管理Mybatis,需要改一下Spring的配置文件:
<context:property-placeholder location="classpath:jdbc.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="dataSource" ref="dataSource" />
</bean>
<!— mapper bean -->
<bean id="userMapper" class="org.mybatis.spring.MapperFactoryBean">
<property name="mapperInterface" value="com.dao.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
当然,mapper bean也可以不配在配置文件中,可以直接使用@Repository注解来完成。
Mybatis的映射文件
Mybatis的映射文件也就是mapper.xml,在映射文件中可以配置SQL语句和结果集。映射文件既可以配置简单的增删改查,同样也可以配置复杂的存储过程,或者操作具有关联关系的表结构。下面先介绍一下简单的增删改查:
增加一条数据:
<insert id="addUser" parameterType="User"
useGeneratedKeys="true" keyProperty="id">
insert into user(userName,userAge,userAddress)
values(#{userName},#{userAge},#{userAddress})
</insert>
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
<update id="updateUser" parameterType="User" >
update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id=#{id}
</update>
<resultMap type="User" id="resultListUser">
<id column="id" property="id" />
<result column="userName" property="userName" />
<result column="userAge" property="userAge" />
<result column="userAddress" property="userAddress" />
</resultMap>
<select id="selectUsers" parameterType="string" resultMap="resultListUser">
select * from user where userName like #{userName}
</select>
<select id="dynamicIfTest" parameterType="Blog" resultType="Blog">这句话使用if判断条件,判断参数如果不为空,则给SQL语句添加查询条件。
select * from t_blog where 1 = 1
<if test="title != null">
and title = #{title}
</if>
<if test="content != null">
and content = #{content}
</if>
<if test="owner != null">
and owner = #{owner}
</if>
</select>
<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">这句话则是使用的when条件进行查询,类似于Java中的case,当when中的条件符合时,在SQL语句后加上and条件,如果when条件都不符合,就直接执行otherwise中的SQL语句。
select * from t_blog where 1 = 1
<choose>
<when test="title != null">
and title = #{title}
</when>
<when test="content != null">
and content = #{content}
</when>
<otherwise>
and owner = "owner1"
</otherwise>
</choose>
</select>
<select id="dynamicWhereTest" parameterType="Blog" resultType="Blog">这句话是采用的where标签,给SQL语句添加where条件,从而完成where子句,同样也采用了if标签进行参数是否为空的判断。
select * from t_blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="content != null">
and content = #{content}
</if>
<if test="owner != null">
and owner = #{owner}
</if>
</where>
</select>
<update id="dynamicSetTest" parameterType="Blog">这句话是更新数据时,采用set标签给参数赋值,代替了SQL语句中的set关键字。
update t_blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="content != null">
content = #{content},
</if>
<if test="owner != null">
owner = #{owner}
</if>
</set>
where id = #{id}
</update>
总结
Mybatis作为一个优秀的持久层框架,确实也挺优秀。它通过强大的映射文件,代替了SQL语句中的某些关键字,而且也省略了在Java类中参数判断是否为空的过程。作为配置文件,它是可配置的,如果项目需要更改数据库,只需要更改映射文件中的部分SQL语句就行,不需要重新编译Java类,比把SQL语句写在类中方便了很多。另外,它还可以设置SQL语句的模板,可以将SQL语句中公用的部分抽出来,作为一个单独的语句,可以加到自定义的SQL语句中,使得操作更面向对象。