目录
- 1、简介
-
- 1.1、什么是 MyBatis?
- 1.2、持久化
- 1.3、持久层
- 1.4、为什么要MyBtis?
- 2、第一个MyBatis程序
-
- 2.1、搭建环境
- 2.2、创建一个模块
- 2.3、编写代码
- 2.4、测试
- 3、CRUD
-
- 3.1、namespace
- 3.2、select
- 3.3、insert
- 3.4、update
- 3.5、delete
-
- 3.6、分析错误
- 3.7、万能的Map
- 3.8、思考题
- 4、配置解析
-
- 4.1.核心配置文件
- 4.2、配置环境(environments)
- 4.3、属性(properties)
- 4.4、类型别名(typeAliases)
- 4.5、设置
- 4.6.其他配置(仅理解)
- 4.7、映射器(mappers)
- 4.8.生命周期和作用域
- 5、ResultMap结果集映射
-
- 5.1.属性名与字段名不一致
- 5.2、resultMap
- 6、日志
-
- 6.1、日志工厂
- 6.2、Log4j
- 7、分页
-
- 7.1、使用Limit分页
- 7.2、RowBounds分页
- 7.3、分页插件
- 8用注释开发
-
- 8.面向接口编程
- 8.2.使用注释开发
- 8.3、CRUD
- 9、Lombok
- 10、多对一处理
-
- 10.1、测试环境建设
- 10.2.按查询嵌套处理
- 10.3.根据结果进行嵌套处理
- 一对多处理
-
- 11.1、环境搭建
- 11.2.根据结果进行嵌套处理
- 11.3.按查询嵌套处理
- 11.4、小结
- 12、动态 SQL
-
- 12.1、搭建环境
- 12.1、IF
- 12.2、choose (when, otherwise)
- 12.3、trim (where,set)
- 12.4、SQL片段
- 12.5、Foreach
- 13、缓存 (了解)
-
- 13.1、简介
- 13.2、Mybatis缓存
- 13.3、一级缓存
- 13.4、二级缓存
- 13.5、缓存原理
- 13.6定义缓存-ehcache
1、简介
1.1、什么是 MyBatis?
MyBatis 是优秀的,它支持自定义 SQL、存储过程和高级映射。MyBatis 几乎所有的免除 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 通过简单 XML 或注释配置和映射原始类型 Java POJO(Plain Old Java Objects,普通老式 Java 对象)是数据库中的记录。
如何获得Mybatis?
- maven仓库
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.10</version> </dependency>
- github:https://github.com/mybatis/mybatis-3/releases
- 中文文档:MyBatis文档
- 提供给外部使用的接口API,开发人员通过这些本地开发人员API操作数据库。接口层一接到调用请求,就会调用数据处理层来完成具体的数据处理。
- 负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。其主要目的是根据调用请求完成数据库操作。
- 负责最基本的功能支持,包括连接管理、事务管理、配置加载和缓存处理西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
1.2、持久化
- 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
- 内存:
- 数据库(jdbc),IO文件持久化。 (生活:冷藏、罐头)
- 有一些对象不能让它丢掉。
- 内存太贵了
1.3、持久层
- 完成持久化工作的代码块
- 层界限十分明显
1.4、为什么要MyBtis?
- 传统JDBC代码太复杂,简化,自动化
- 方便
- 帮助程序猿将数据存到数据库中
- 不用MyBtis也可以,更容易上手
- 简单易学
- 灵活 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射。
- 提供对象关系映射标签,支持对象关系组建维护。
- 提供xml标签,支持编写动态sql。
2、第一个MyBatis程序
2.1、搭建环境
1.搭建数据库
create table user (
id int(20) not null primary key,
name varchar(30) default null,
pwd varchar(30) default null
)engine=innodb default charset='utf8';
insert into user (id,name,pwd) values
(1,'张三','123456'),
(2,'李四','123456'),
(3,'王五','123456');
2.新建项目
- 新建一个普通的maven项目
- 删除src目录
- 导入maven依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
2.2、创建一个模块
https://mybatis.org/mybatis-3/zh/configuration.html#environments
<?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>
<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/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--每一个Mapper.xml都需要在Mybatis核心配置文件中注册!-->
<mappers>
<mapper resource="com/kuang/dao/UserMapper.xml"/>
</mappers>
</configuration>
每一个基于mybatis的工具类都是一个SQLSessionFactory为核心的。SQLSessionFactory的实例可以通过SQLSessionFactoryBuilder获得。而SQLSessionFactoryBuilder则可以从XML配置文件或一个预定制的Configuration的实例构建出SQLSessionFactory实例。
package com.kuang.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;
//sqlSessionFactory --> sqlSession
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//使用Mybatis第一步,获取sqlSessionFactory对象。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//既然有了sqlSessionFactory,顾名思义,我们就可以从中获得sqlSession的实例了。
//sqlSession 完全包含了面向数据库执行SQL命令的所有方法。
public static SqlSession getsqlSession(){
return sqlSessionFactory.openSession();
}
}
2.3、编写代码
package com.yangguo.pojo;
public class User {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
public interface UserDao {
//查询全部用户。
List<User> getUserList();
}
<?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">
<!--namespace绑定一个Dao/Mapper接口,相当于实现这个接口,即UserDaoImpl id就是Dao接口的方法名 -->
<mapper namespace="com.yangguo.dao.UserDao">
<!--相当于实现Dao中的getUserList方法-->
<select id="getUserList" resultType="com.yangguo.pojo.User">
select *
from user
</select>
</mapper>
2.4、测试
org.apache.ibatis.binding.BindingException: Type interface com.yangguo.dao.UserDao is not known to the MapperRegistry
核心配置文件中注册mappers
- junit测试
@Test
public void test(){
//第一步:获得SqlSession对象。
SqlSession sqlSession = MybatisUtils.getsqlSession();
//方式一:getMapper
UserMapper userDao = sqlSession.getMapper(UserMapper.class);
List<User> userList = userDao.getUserList();
//方式二:(过时了,不推荐使用)
//List<User> userList = sqlSession.selectList("com.kuang.dao.UserDao.getUserList");
for (User user : userList) {
System.out.println(user);
}
//关闭Session
sqlSession.close();
}
IDEA自动补全返回类型及变量快捷键: ctrl+alt+v
maven由于他的约定大于配置,我们之后可以能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
错误:Error querying database. Cause: java.sql.SQLException: The server time zone value ‘�й���ʱ��’ is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
解决:jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF8&
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
- 配置文件没有注册。
- 绑定接口错误。
- 方法名不对。
- 返回类型不对。
- Maven导出资源问题。pom.xml中的build中配置resources。
3、CRUD
3.1、namespace
namespace中的包名要和Dao/Mapper接口中的包名一致
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.study.dao.UserMapper">
3.2、select
- id:就是对应的namespace中的方法名
- resultType:Sql语句执行的返回值
- parameterType:参数类型
/** * 根据ID查询用户 * @param id * @return */
User getUserById(int id);
<select id="getUserById" parameterType="int" resultType="com.yang.pojo.User">
select *
from mybatis.user
where id = #{id}
</select>
@Test
public void getUserById() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(1);
System.out.println(user.toString());
sqlSession.close();
}
3.3、insert
/** * 插入一个user * @param user * @return */
int addUser(User user);
<!--对象中的属性可以直接取出来-->
<insert id="addUser" parameterType="com.yang.pojo.User">
insert into mybatis.user(id, name, pwd)
values (#{id}, #{name}, #{pwd})
</insert>
@Test
public void addUser() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int row = userMapper.addUser(new User(4, "赵六", "123456"));
if (row > 0) System.out.println("插入成功");
//提交事务
sqlSession.commit();
sqlSession.close();
}
3.4、update
//修改用户。
int updateUser(User user);
<update id="updateUser" parameterType="com.kuang.pojo.User" >
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
</update>
@Test
public void updateUser(){
SqlSession sqlSession = MybatisUtils.getsqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser(new User(4,"诺克萨斯","666666"));
sqlSession.commit();
sqlSession.close();
}
3.5、delete
//删除一个用户。
int deleteUser(int id);
<delete id="deleteUser" parameterType="int" >
delete from mybatis.user where id = #{id};
</delete>
@Test
public void deleteUser(){
SqlSession sqlSession = MybatisUtils.getsqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(4);
sqlSession.commit();
sqlSession.close();
}
- 增删改需要提交事务
- 读错要从后往前读
3.6、分析错误
- 标签不要匹配错!
- resource 绑定mapper,需要使用路径!
- 程序配置文件必须符合规范!
- NullPointerException,没有注册到资源!
- 输出的xml文件中存在中文乱码问题!
- maven资源没有导出问题!
3.7、万能的Map
假设我们的实体类或者数据库中的表、字段或者参数过多,我们应当考虑使用Map。
/** * 万能的Map * @param map * @return */
int addUser2(Map<String,Object> map);
<!--userId、userName、userPwd其实是map中的key,也就是说传递map中的key-->
<insert id="addUser2" parameterType="map"<