1. 基本学习
MyBatis的执行流程·:
- mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的信息
- mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂
- 通过SqlSessionFactory,可以创建SqlSession(即会话,Mybatis是通过SqlSession来操作数据库的)
- SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)
- Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型
2. 环境配置
IDEA Maven项目
数据库环境: MySQL
MyBatisMaven三维坐标1
2
3
4
5
6<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
3. demo编写
测试代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class UserDaoImpl implements UserDao1 {
// 此处选用namespace为"user",选用此处方法需将UserMapper.xml文件中namespace改过来
public User findUserById(int id) throws Exception {
String resource = "mybatis-config1.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------
User user = session.selectOne("user.findUserById",id); //参数一:namespace.id
//--------------
session.close();
return user;
}
}
Mapper映射配置文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<!--<mapper namespace="user">-->
<mapper namespace="user">
<select id="findAllUsers" resultType="com.yza.demo1.entity.User">
SELECT * FROM USER
</select>
<select id="insertUser" parameterType="com.yza.demo1.entity.User">
INSERT INTO USER(id,userName,password,age) VALUES(#{id},#{userName},#{password},#{age})
</select>
<select id="deleteUserById" parameterType="int" >
DELETE FROM USER WHERE id=#{id}
</select>
<select id="updateUserPassword" parameterType="com.yza.demo1.entity.User">
UPDATE USER SET password=#{password} WHERE id=#{id}
</select>
<select id="findUserById" parameterType="int" resultType="com.yza.demo1.entity.User">
SELECT * FROM USER WHERE id=#{id}
</select>
</mapper>
Mapper接口1
2
3
4
5
6
7
8public interface UserDao1 {
public User findUserById(int id) throws Exception;
public List<User> findAllUsers() throws Exception;
public void insertUser(User user) throws Exception;
public void deleteUserById(int id) throws Exception;
public void updateUserPassword(User user) throws Exception;
}
4. 升级版–Mapper代理开发模式
- Mapper代理的开发方式,程序员只需要编写mapper接口(相当于dao接口),不需再编写dao实现类(Mybatis会自动的为mapper接口生成动态代理实现类)
- 要实现mapper代理的开发方式,需要遵循一些开发规范(接口的包名,类名,参数,返回值分别对应着映射文件的namespace,id,parameterType,resultType)
- mapper接口的全限定名要和mapper映射文件的namespace的值相同
- mapper接口的方法名称要和mapper映射文件中的statement的id相同
- mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致
- mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致
UserMapper映射文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<?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属性,设置为Mapper接口的全路径名-->
<mapper namespace="com.yza.demo1.dao.UserDao">
<select id="findAllUsers" resultType="com.yza.demo1.entity.User">
SELECT * FROM USER
</select>
<select id="insertUser" parameterType="com.yza.demo1.entity.User">
INSERT INTO USER(id,userName,password,age) VALUES(#{id},#{userName},#{password},#{age})
</select>
<select id="deleteUserById" parameterType="int" >
DELETE FROM USER WHERE id=#{id}
</select>
<select id="updateUserPassword" parameterType="com.yza.demo1.entity.User">
UPDATE USER SET password=#{password} WHERE id=#{id}
</select>
<select id="findUserById" parameterType="int" resultType="com.yza.demo1.entity.User">
SELECT * FROM USER WHERE id=#{id}
</select>
</mapper>
Mapper接口1
2
3
4
5
6
7public interface UserMapper {
public User findUserById(int id);
public List<User> findUserAll();
public void insertUser(User user);
public void deleteUserById(int id);
public void updateUserPassword(User user);
}
报错1
报错具体信息1
2### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for user.findUserById
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for user.findUserById
本质原因–mapper文件的namespace和DaoImpl路径不一致
mapper文件1
2
3
4
5
6
7<!-- mapper标签要指定namespace属性,不然会报错,可看做包名 -->
<mapper namespace="com.yza.demo1.dao.UserDao">
<!--<mapper namespace="user">-->
<select id="findUserById" parameterType="int" resultType="com.yza.demo1.entity.User">
select * from user where id=#{id}
</select>
</mapper>
DaoImpl方法–>此处namespace为”user”1
2
3
4
5
6
7
8
9
10
11
12
13
14public class UserDaoImpl implements UserDao {
public User findUserById(int id) throws Exception {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
//---------------
User user = session.selectOne("user.findUserById",id); //参数一:namespace.id
//--------------
session.close();
return user;
}
}
总结:
- namespace:必须与UserDao的全路径想匹配,这样才能使的接口与sql文件一一对应
报错2
- 使用Java和MyBatis时遇到的数据无法插入问题
解决办法–>手动commit
session关闭前不会自动提交
- 手动commit、close,两次导入数据库,报错
解决办法:关闭是必须的,就不再提交commit
1 | public static void main(String[] args) throws Exception { |
附录:
MyBatisUtil工具类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.*;
import java.io.InputStream;
public class SqlSessionFactoryUtil {
private static SqlSessionFactory sqlSessionFactory;
/**
* 初始化sqlSessionFactory
*/
static {
getSqlSessionFactory();
}
/**
* 获取SqlSessionFactory
* @return
*/
public static SqlSessionFactory getSqlSessionFactory() {
if(sqlSessionFactory==null) {
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch(Exception e) {
e.printStackTrace();
}
}
return sqlSessionFactory;
}
/**
* 获取SqlSession
* @return
*/
public static SqlSession openSession() {
return sqlSessionFactory.openSession();
}
/**
* 关闭SqlSession
* @param sqlSession
*/
public static void clSSoseSession(SqlSession sqlSession) {
if(sqlSession != null) {
sqlSession.close();
}
}
}