1. 简介
本文档的目的在于在掌握JDBC原理和操作的基础上,快速属性Mybatis的常用属性和操作过程。方便自己查看和初学者学习。
Mybatis是一款持久层框架。其中文文档对其使用进行了详尽的描述。MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
简单来说,Mybatis使得开发人员可以避免编写复杂的JDBC操作,同时,最重要的一点是:使得SQL语句和代码分离开。这样方便我们对持久化部分的调试。
Mybatis的核心实例是SqlSessionFactory 。通常采用从xml文件中构建出SqlSessionFactoryBuilder 实例对象,通过该对象的build方法来获取SqlSessionFactory实例。build方法的参数为文件的输入流(即配置的xml文件)。
获取了SqlSessionFactoryBuilder 实例之后,通过openSession方法就可以获取SQLSession实例,SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。过程大致如下:
2. 第一次使用Mybatis
从数据库中查出用户的信息。
2.1 配置相关文件
使用Maven构建项目,在pom.xml中加入依赖。
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<!--选择你需要的版本号-->
<version>x.x.x</version>
</dependency>
在模块下的resources文件夹下创建Mybatis的配置文件,mybatis-config.xml
。主要涉及到数据库相关的内容。
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--核心配置文件-->
<configuration>
<!-- 配置多个环境,默认是开发环境 -->
<environments default="development">
<environment id="development">
<!-- 事务方式 : JDBC的事物-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 配置属性-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="你的用户名"/>
<property name="password" value="你的密码"/>
</dataSource>
</environment>
</environments>
</configuration>
2.2 使用SqlSessionFactory获得SQLSession
由于这部分的代码相对固定,通常作为工具类使用。
package com.yindarui.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisUtils {
// 来自官方指南
public static SqlSessionFactory sqlSessionFactory = null;
static {
// 获取地址
String resource = "mybatis-config.xml";
try {
// 获取sql 的输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 获取SQLSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
// SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
public static SqlSession getSQLSession() {
return sqlSessionFactory.openSession();
}
}
2.3 创建实体类:
package com.yindarui.POJO;
public class User {
private int id;
private String name;
private String password;
public User() {
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setPassword(String password) {
this.password = password;
}
}
2.4 编写持久化层内容:
主要涉及到两个文件,一个是mapper接口,一个是Mapper的xml文件。注意,每编写一个mapper都要在Mybatis的配置文件中注册该mapper。
操作接口:
package com.yindarui.Dao;
import com.yindarui.POJO.User;
import java.util.List;
public interface UserMapper {
List<User> gertUserList();
}
在mybatis-config.xml文件中注册mapper:注意要写项目下的路径。
<mappers>
<mapper resource="com/yindarui/Dao/UserMapper.xml"></mapper>
</mappers>
配置文件:注意返回的实体类要写全限定名。
<?xml version="1.0" encoding="UTF8" ?>
<!--
一个语句既可以通过 XML 定义,也可以通过注解定义。
我们先看看 XML 定义语句的方式:
事实上 MyBatis 提供的所有特性都可以利用基于 XML 的映射语言来实现,这使得 MyBatis 在过去的数年间得以流行。
使用配置文件来编写SQL语句,使得sql语句的维护的代码的维护分离
-->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间,需要绑定一个对应的接口(Mapper,即Javaweb中的Dao)-->
<mapper namespace="com.yindarui.Dao.UserMapper">
<!--编写你的sql-->
<!--
select 标签的属性:
方法名:
id即为你接口中定义的方法;
参数列表:必须指定全限定名
parameterType: 参数值类型
parameterMap: 参数集合类型
返回值:必须指定全限定名
resultType: 返回值类型
resultMap: 返回集合类型
-->
<select id="gertUserList" resultType="com.yindarui.POJO.User">
select * from mybatis.user
</select>
</mapper>
2.5 编写测试类:
package com.yindarui.Dao;
import com.yindarui.POJO.User;
import com.yindarui.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserMapperTest {
@Test
public void test() {
// 获取SQLSession对象
SqlSession sqlSession = MyBatisUtils.getSQLSession();
// 加载class文件
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 注意:Type interface com.yindarui.Dao.UserMapper is not known to the MapperRegistry.
// 每个Mapper.xml都必须在Mybatis的核心配置文件中注册
List<User> users = mapper.gertUserList();
for (User item : users) {
System.out.println(item.getId()+"的名称是"+item.getName()+". 您的密码为:"+item.getPassword());
}
sqlSession.close();
}
}
2.6 结果
1的名称是yinrui. 您的密码为:123456
2的名称是zhangsan. 您的密码为:123456
3. 更多的功能
如果你已经完成了配置和工具类的编写,那么Mybatis的开发就会变得非常简单,你只需要:
- 编写对应的实体类
- 编写mapper接口
- 注册mapper接口
- 为mapper接口编写配置文件
- 编写类调用mapper指定的方法
3.1 插入数据:将数据封装对象插入
注意事务的提交:
1. Dao代码
mapper java文件:
package com.yindarui.Dao.emp;
import com.yindarui.POJO.Emp;
/**
*
*/
public interface EmpMapper {
int addEmpRec(Emp emp);
}
mapper xml文件:
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yindarui.Dao.emp.EmpMapper">
<insert id="addEmpRec" parameterType="com.yindarui.POJO.Emp">
insert into mybatis.emp values(#{id}, #{name}, #{job});
</insert>
</mapper>
2. Mapper注册:
<mappers>
<mapper resource="com/yindarui/Dao/emp/EmpMapper.xml"></mapper>
</mappers>
3. 测试:
package com.yindarui.Dao;
import com.yindarui.Dao.emp.EmpMapper;
import com.yindarui.POJO.Emp;
import com.yindarui.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class EmpMapperTest {
@Test
public void test() {
SqlSession sqlSession = MyBatisUtils.getSQLSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = new Emp();
emp.setId(2);
emp.setName("张三");
emp.setJob("程序员");
int i = mapper.addEmpRec(emp);
if (i != 1) System.out.println("插入失败");
else System.out.println("插入成功");
// 增删改需要提交事务
sqlSession.commit();
sqlSession.close();
}
}
4. 使用Map
之前我们提到的在mapper的xml文件中,我们可以指定parameterType,采取的传参方法是构造一个对象。即每次我们修改值的时候,都需要实例化对象,并传递对象。这样的操作效率不高。
我们面临的问题是:传递多个参数,涉及到多个不同类型的参数。对于同类型的参数,可以使用list或者数组。对于不同类型的,使用map的方式传递,其中字段名称为key,待修改的值为value。
模块构架:
下面我们利用map来更新user表中的信息。
4.1 Dao层:
mapper.java文件
package com.yindarui.Dao.user;
import com.yindarui.POJO.User;
import java.util.List;
import java.util.Map;
public interface UserMapper {
List<User> gertUserList();
User getInfo(int id);
int updateUser(Map<String, Object> map);
}
xml文件:
<?xml version="1.0" encoding="UTF8" ?>
<mapper namespace="com.yindarui.Dao.user.UserMapper">
<!--编写你的sql-->
<update id="updateUser" parameterType="map">
update user set password = #{pw}, name = #{userName} where id = #{id}
</update>
</mapper>
4.2 注册mapper
在mybatis-config.xml文件中注册mapper:如果你已经注册了,请忽略。
<mappers>
<mapper resource="com/yindarui/Dao/user/UserMapper.xml"></mapper>
</mappers>
4.3 测试类
package com.yindarui.Dao;
import com.yindarui.Dao.user.UserMapper;
import com.yindarui.POJO.User;
import com.yindarui.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class UserMapperTest {
@Test
public void testMap() {
SqlSession sqlSession = MyBatisUtils.getSQLSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap();
map.put("id",1);
map.put("pw", 2332343);
map.put("userName","yindarui");
int i = mapper.updateUser(map);
if (i == 1) System.out.println("修改成功");
else System.out.println("修改失败");
sqlSession.commit();
sqlSession.close();
}
}
5. 存在问题:
5.1 找不到mapper
org.apache.ibatis.binding.BindingException: Type interface com.yindarui.Dao.emp.EmpMapper is not known to the MapperRegistry.
你的mapper没有在mybatis-config.xml中注册。
5.2 找不到资源
如果你采用的是junit来测试,那么请你查看你的target文件夹中有没有输出完成的文件,如果没有,请在maven的pom文件中加入:
<!--为了提供资源的路径,防止资源导出错误-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>**/*.properties</includes>
<includes>**/*.xml</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>**/*.properties</includes>
<includes>**/*.xml</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>