最近工作要用MyBatis,今天特意花了点时间学习了一些相关的资料。由于之前开发一直用的是Hibernate,而且MyBatis和Hibernate都是ORM框架,所以理解似乎也不是很困难。
中文文档地址:http://mybatis.github.io/mybatis-3/zh/index.html
下面展示一个Test项目,参考了网上某些博客(下面的代码自己敲的,不是简单复制亲测可用)用maven构建项目,数据库用mysql5.6.24,MyBatis3.1.1.
第一步,最简单的例子
1、创建maven项目
2、pom中引入依赖jar包,mybatis和mysql的驱动包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
3、添加MyBatis的配置文件src/main/resources/mybatis-config.xml,主要定义了映射文件和sessionFactory的相关信息,和Hibernate的配置有点类似!
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
<!-- 配置别名 -->
<typeAliases>
<typeAlias type="com.tel.mybatis.model.Sysprop"/>
</typeAliases>
<!-- 配置sessionFactory需要的信息 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/databasename" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 映射文件 -->
<mappers>
<mapper resource="Sysprop.xml"/>
</mappers>
</configuration>
4、添加MyBatis的映射文件src/main/resources/Sysprop.xml,这里简单定义了一个根据id查询的sql
注:由于前面已经定义了Sysprop的别名,所以resultType不需要带包名
<?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.tel.mybatis.dao.ISyspropDAO">
<select id="get" parameterType="int" resultType="Sysprop">
select * from sysprop where id = #{id}
</select>
</mapper>
5、创建测试类,查询数据库(原理也很简单,定位映射文件-》构建SqlSessionFactory-》定位sql语句-》执行SQL-》得到结果)
SQL的定位是通过映射文件名+包名+sql的ID定位的
public class Test {
private static SqlSessionFactory sqlSessionFactory;
private static Reader reader;
static {
try {
reader = Resources.getResourceAsReader("mybatis-config.xml");
//加载配置文件构建,构建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSession() {
return sqlSessionFactory;
}
public static void main(String[] args) {
SqlSession session = sqlSessionFactory.openSession();
try {
//注意com.tel.mybatis.dao.ISyspropDAO是映射文件的包名,get是select语句的id,2是传入的参数
Sysprop sysprop = session.selectOne("com.tel.mybatis.dao.ISyspropDAO.get", 2);
System.out.println(sysprop.getName());
System.out.println(sysprop.getValue());
} finally {
session.close();
}
}
}
6、执行测试类,输出结果。
第二步、接口编程
前面是直接根据映射来执行sql,但是如果中间再搭建一层DAO层,代码会更清晰。
1、回到Sysprop.xml映射文件,namespace="com.tel.mybatis.dao.ISyspropDAO"这里没有用到,其实可以用来指定要被代理的DAO接口
2、创建com.tel.mybatis.dao.ISyspropDAO接口,这里定义了方法名get和映射文件sql对应的id
这里只需定义接口,不需要实现类(没看源码,应该是MyBatis代理实现)
public interface ISyspropDAO {
public Sysprop get(int id);
}
3、在Test测试类中调用DAO层方法
public static void queryByInterface() {
SqlSession session = sqlSessionFactory.openSession();
try {
ISyspropDAO dao = session.getMapper(ISyspropDAO.class);
Sysprop sysprop = dao.get(2);
System.out.println(sysprop.getName());
System.out.println(sysprop.getValue());
} finally {
session.close();
}
}
4、执行测试类,得到结果。
第三步、完善增删改查
前面是简单查询,这里完善一下增删改等
1、在映射文件Sysprop.xml中添加SQL
<select id="queryAll" resultType="Sysprop">
select * from sysprop
</select>
<insert id="save" parameterType="Sysprop" useGeneratedKeys="true" keyProperty="id" flushCache="true">
insert into sysprop(name, value) values(#{name},#{value})
</insert>
<update id="update" parameterType="Sysprop">
update sysprop set name = #{name},value = #{value} where id = #{id}
</update>
<delete id="delete" parameterType="int">
delete from sysprop where id = #{id}
</delete>
2、在DAO层接口ISyspropDAO定义方法
public interface ISyspropDAO {
public Sysprop get(int id);
public List<Sysprop> queryAll();
public int save(Sysprop sysprop);
public void update(Sysprop sysprop);
public void delete(int id);
}
3、调用DAO层接口方法,和查询类似。
第四步、遇到的几个问题
1、查询时缓存问题:映射文件中,<select>默认启动useCache的属性为true,所以对同一个session下的相同sql,会返回相同结果。由于mybatis中insert、update、delete都会刷新二级缓存,所以通过他们改变的数据后,select不会出现问题。但是,如果通过客户端添加、删除、修改数据,刷新页面,查询结果不同步。所以,可以设置useCache为false或flushCache为true,当然必须以实际情况而定。
2、代码中调用insert、update、delete后必须提交事务:session.commit();否则不会修改数据。
3、时间有限,关联查询、动态SQL没有涉及,以后再完善