mybatis是之前公司用的持久层框架,现如今在用hibernate,mybatis具有易使用、轻量级、SQL定制的特点,相对hibernate来说。
Mybatis主要由DAO(data access object)接口和映射mapper文件组成,它们之间是映射关系;
接口是Interface,主要定义了操作DB的方法,但没有实现;
mapper文件一般是xml,主要对应特定DAO interface中的方法,方法执行的SQL写在这里;
那么该如何将interface和映射文件对应起来呢?这里就需要在配置文件中配置了。
来来来,首先要有数据源dataSource,这里用apache的dbcp连接池来连接mysql
<!--引入数据库相关参数的属性值 ${url}-->
<context:property-placeholder location="classpath:dataSource.properties" />
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<beans:property name="driverClassName" value="${db.driver}" />
<beans:property name="url" value="${db.url}" />
<beans:property name="username" value="${db.username}" />
<beans:property name="password" value="${db.password}" />
</beans:bean>
其次,要有一个sqlSessionFactory,它生成SqlSession,用来和数据库进行会话(crud)。它有几个属性:dataSource(数据源)、configLocation(mybatis的全局配置文件)、mapperLocation(映射DAO接口的文件,即含有SQL语句的xml)
<beans:bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource"></beans:property>
<beans:property name="configLocation" value="classpath:mybatis-config.xml"></beans:property>
<beans:property name="mapperLocations" value="classpath:mapper/*.xml"></beans:property>
</beans:bean>
ok,分别看一下mybatis全局配置文件mybatis-config.xml和mapper/*.xml,注意这两个文件在classpath路径下,我放在了src/main/resource下。
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>
<!-- 配置全局属性 -->
<settings>
<!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 使用列别名替换列名 默认:true -->
<setting name="useColumnLabel" value="true" />
<!-- 开启驼峰命名转换:Table{create_time} -> Entity{createTime} -->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
</configuration>
mapper/*.xml:
这里是BookDao.xml(建议一个DAO 接口对应一个mapper.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="mybatis.demo.dao.BookDao">
<select id="queryById" resultType="mybatis.demo.entity.Book" parameterType="long">
SELECT
id,
reader,
isbn,
title,
author,
description
FROM
book
WHERE
id= #{id}
</select>
<select id="queryAll" resultType="mybatis.demo.entity.Book">
SELECT
id,
reader,
isbn,
title,
author,
description
FROM
book
ORDER BY
id
LIMIT #{offset}, #{limit}
</select>
</mapper>
讲到这里,就可以来看一下sql映射文件(上边这个xml)是如何和DAO里的方法一一对应起来的。
还记得吗,前边配置了sqlSessionFactory,ok,它有一个属性是mapperLocations,我需要将DAO interface的方法映射到BookDao.xml中,这里需要新增一个配置:
<beans:bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<beans:property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></beans:property>
<beans:property name="basePackage" value="mybatis.demo.dao"></beans:property>
</beans:bean>
映射扫描配置bean:
指定使用哪一个sqlsessionFactory生成sqlSession(包含了BookDao.xml哦);另一个重要的是basePackage属性,指定要扫描哪一个package作为接口文件,ok,看一下这个包下的接口文件:
package mybatis.demo.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import mybatis.demo.entity.Book;
public interface BookDao {
Book queryById(Long id);
List<Book> queryAll(@Param("offset") int offset, @Param("limit") int limit);
}
可以看出来,只需要定义一个interface,里边包含了需要操作数据库的方法名,后边就是在BookDao.xml中一一映射这些方法了
再回到BookDao.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="mybatis.demo.dao.BookDao">
<select id="queryById" resultType="mybatis.demo.entity.Book" parameterType="long">
SELECT
id,
reader,
isbn,
title,
author,
description
FROM
book
WHERE
id= #{id}
</select>
<select id="queryAll" resultType="mybatis.demo.entity.Book">
SELECT
id,
reader,
isbn,
title,
author,
description
FROM
book
ORDER BY
id
LIMIT #{offset}, #{limit}
</select>
</mapper>
这里介绍一下mapper.xml的构成:
<mapper namespace="mybatis.demo.dao.BookDao">
</mapper>
namespace指定该mapper是映射的哪一个DAO,这里y映射的dao接口是mybatis.demo.dao.BookDao;
<select id="queryById" resultType="mybatis.demo.entity.Book" parameterType="long">
</select>
id指定映射dao中的哪一个方法,这里是BookDao中的queryById方法,resultType指定返回的类型,这里是Book.class;parameterType指定传入参数的类型;这里是long类型;
具体sql是写在里边的:
<mapper namespace="mybatis.demo.dao.BookDao">
<select id="queryById" resultType="mybatis.demo.entity.Book" parameterType="long">
SELECT
id,
reader,
isbn,
title,
author,
description
FROM
book
WHERE
id= #{id}
</select>
</mapper>
看一下Book.class这个entity:
package mybatis.demo.entity;
public class Book {
private long id;
private String reader;
private String isbn;
private String title;
private String author;
private String description;
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
public String getReader(){
return reader;
}
public void setReader(String reader){
this.reader = reader;
}
public String getIsbn(){
return isbn;
}
public void setIsbn(String isbn){
this.isbn = isbn;
}
public String getTitle(){
return title;
}
public void setTitle(String title){
this.title = title;
}
public String getAuthor(){
return author;
}
public void setAuthor(String author){
this.author = author;
}
public String getDescription(){
return description;
}
public void setDescription(String description){
this.description = description;
}
}
由于mybatis-config.xml这个全局配置文件里开启了驼峰标志,所以假如数据库里的字段是product_id,那么对应到entity里就是productId,这里注意table字段和entity字段要一致。
好了,到这里基本把mybatis的主要特性介绍完了,我觉得和hibernate的主要区别在于:
1)Dao层接口没有实现类了,只需有映射文件即可
2)可以随意定制sql
3)使用简单,配置不复杂
上边只是重点讲了下mybatis的特性及如何配置,实践中我是用springMVC+maven搭建的项目,并提供了jsp用来显示mybatis查询结果,还涉及一些小细节(譬如maven管理的依赖(commons-log没有时run报错);BookDao.xml中resultType在没有配置alias条件下必须是全路径下的Book.class;配置文件mybatis-config.xml的location),都是在run peoject过程中逐渐解决的。这里也应了那句话,先把项目搭建起来,不可能一次性就把一个project搭建的完美无瑕,很多问题都是碰到了才尝试去解决。整个项目已放到github上,感兴趣的童鞋可以去下载查阅mybatisDemo in Github