# MybatisStudy
**Repository Path**: ringo-tyl/mybatis-study
## Basic Information
- **Project Name**: MybatisStudy
- **Description**: Mybatis学习
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2021-10-11
- **Last Updated**: 2024-10-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 还原系统配置步骤:
1、下载Git
2、IDEA和Git关联
3、去仓库拉工程
4、配置Maven
5、修改主题颜色
6、修改字体大小
7、IDEA下载lombok插件
8、数据库
9、自动导包
10、快捷键调为eclipse
# 一、Mybatis 3的学习


## 1.1 什么是Mybatis
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
官网:https://mybatis.org/mybatis-3/zh/index.html
用来学习最新的API
中文网:http://www.mybatis.cn/
用来查看使用技巧
## 1.2 Mybatis的历史
原是apache的一个开源项目iBatis,2010年6月这个项目由apache迁移到了google code,随着开发团队转投Google code旗下,ibatis3.x正式更名为Mybatis,代码于2013年11月迁移到Github。
## 1.3 Mybatis的优势
1. 基于sql语句编程,使用灵活,sql与程序代码的解耦
2. 与JDBC相比减少50%代码,减少大量冗余代码,不需要手动开关连接
3. 只要支持jdbc的数据库都支持Mybatis
4. 与spring集成
5. 支持面向对象编程,对象与ORM表映射
# 二、Mybaits环境搭建
## 2.1 创建数据库和表
```sql
/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.5.54 : Database - mybatis
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`mybatis` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `mybatis`;
/*Table structure for table `users` */
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`u_id` BIGINT(18) NOT NULL AUTO_INCREMENT,
`u_name` VARCHAR(30) NOT NULL COMMENT '用户名',
`u_pass` VARCHAR(100) NOT NULL COMMENT '密码',
PRIMARY KEY (`u_id`)
) ENGINE=INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*Data for the table `users` */
insert into `users`(`u_id`,`u_name`,`u_pass`) values (1,'张三','9033241'),(2,'李四','3333241'),(3,'王五','12156241'),(4,'赵六','1111'),(5,'铁蛋','23233241');
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
```
## 2.2 创建Maven工程

## 2.3 IDEA自带数据库管理工具

## 2.4 配置Maven

## 2.5 创建表映射类PO
```java
package com.xxgc.mybatis.po;
/* alt + insert 生成构造函数 */
public class User {
private long uId;
private String uName;
private String uPass;
public long getuId() {
return uId;
}
public void setuId(long uId) {
this.uId = uId;
}
public String getuName() {
return uName;
}
public void setuName(String uName) {
this.uName = uName;
}
public String getuPass() {
return uPass;
}
public void setuPass(String uPass) {
this.uPass = uPass;
}
}
```
## 2.6 创建Mybaits配置文件
```xml
```
## 2.7 创建一个工具类来获取SqlSession
```java
package com.xxgc.mybatis.util;
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;
//Mybaits工具类,用来获取sqlSession
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//以下三步通过配置文件来获取sqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
/* ctrl + alt + f 提取/抽取 全局变量 */
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e){
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
/* ctrl + alt + v 自动生成返回结果 */
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
}
```
## 2.8 创建Dao层接口
```java
package com.xxgc.mybatis.dao;
import com.xxgc.User;
import java.util.List;
//用户表Dao层接口
public interface UserDao {
//查询所有用户
List selectAllUsers();
}
```
## 2.9 创建映射文件
```xml
```
```java
@Test
public void test(){
//调用工具类 得到sqlSession
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//加载dao层映射
UserDao mapper = sqlSession.getMapper(UserDao.class);
//通过调用接口执行语句
List users = mapper.selectAllUsers();
//循环打印内容
for (User user : users) {
System.out.println("user = " + user);
}
//手动关闭sqlsession(学到了spring过后就不需要了)
sqlSession.close();
}
```
添加Mapper映射
```xml
```
开启驼峰命名
```xml
```
### 工程环境目录结构
http://www.shijiayi.top/article/268.html?t=1634010066341
# 三、Mybatis增删改查
## 3.1 select
select标签属性
- id 相应dao层方法
- parameterType 传入参数类型
- resultType 返回对象
```xml
```
## 3.2 insert
需要提交事务
```java
sqlSession.commit();
```
```xml
insert into users(u_name,u_pass) value (#{uName},#{uPass});
```
## 3.3 update
需要提交事务
```
sqlSession.commit();
```
```xml
update users set u_name = #{uName},u_pass = #{uPass} where u_id = #{uId};
```
## 3.4 delete
需要提交事务
```
sqlSession.commit();
```
```xml
delete from users where u_id = #{uId};
```
## 3.5 特殊使用
在参数不确定的情况下,可以使用Map集合来进行参数传递
```java
//特殊的参数传递
int addUserByMap(Map map);
```
```xml
insert into users(u_name,u_pass) value (#{myName},#{myPass});
```
```java
Map map = new HashMap();
map.put("myName","阿强");
map.put("myPass","156165156");
int i = mapper.addUserByMap(map);
```
### 模糊查询
like查询有点特殊需要用到CONCA()函数
```xml
```
# 三、常用配置
## 3.1 mybatis环境配置
```xml
```
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;
**不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。**
## 3.2 MyBatis自动扫描Bean类
```xml
```
## 3.3 映射器(mappers)
既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 `file:///` 形式的 URL),或类名和包名等。例如:
```xml
```
## 3.4 MyBatis生命周期

#### SqlSessionFactoryBuilder
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。
因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
#### SqlSessionFactory
相当于一个饮料工厂,用于生产SqlSession。
被创建后在应该在程序运行期间一直存在(使用静态单例模式)。
#### SqlSession
使用后必须关闭。(饮料瓶有限,不归还无法继续生产。饮料瓶数量等于mysql最大连接数)
作用于最好是在方法层面。
## 3.5 ResultMap(结果集/结果图)
创建表
```sql
CREATE TABLE `money` (
`m_id` bigint(18) NOT NULL AUTO_INCREMENT COMMENT '金额表id',
`m_user_id` bigint(18) NOT NULL COMMENT '用户id',
`m_money` int(11) NOT NULL DEFAULT '0' COMMENT '金额',
`m_type` varchar(200) NOT NULL DEFAULT '人民币' COMMENT '钱的类型',
PRIMARY KEY (`m_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
```
创建触发器
```sql
DELIMITER $$
CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `mybatis`.`usermoney` AFTER INSERT
ON `mybatis`.`users`
FOR EACH ROW BEGIN
INSERT INTO `money`(`m_user_id`,`m_money`,`m_type`)
VALUES
(new.u_id,0,'人民币'),
(new.u_id,0,'美元'),
(new.u_id,0,'英镑');
END$$
DELIMITER ;
```
创建扩展类
```java
package com.xxgc.mybatis.po.extend;
//User实体类的扩展
public class UserEx {
private String name;
private int money;
private String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
```
```xml
```
## 3.6 Log4j日志框架
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件...等;
我们也可以控制每一条日志的输出格式,定义每一条日志信息的级别。
可以通过一个配置文件(log4j.properties)来灵活地进行配置,而不需要修改应用的代码。
### Maven包查询
**如果访问不了需要修改DNS为 114.114.114.114 8.8.8.8**
(https://mvnrepository.com/)

### log4j.properties
```properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=WARN,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%p][%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C://logs/error.log
log4j.appender.file.Append = true
#输出门槛
log4j.appender.file.Threshold=WARM
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd HH:mm:ss}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
```
mybatis配置
```xml
```
常见的日志等级
ERROR、WARN、INFO、DEBUG
- ERROR 为严重错误 主要是程序的错误
- WARN 为一般警告,比如session丢失
- INFO 为一般要显示的信息,比如登录登出
- DEBUG 为程序的调试信息
### 简单使用
```java
private Logger logger = Logger.getLogger(类名.class);
```
```java
logger.debug("调试日志");
logger.info("信息日志");
logger.warn("警告日志");
logger.error("错误日志");
```
# 四、分页
## 4.1 limit
```sql
select * from users limt 5 #从0到5
select * from users limit 1,5 #从第一条到第五条
```
## 4.2 PageHelper分页插件
官网地址:https://pagehelper.github.io/
### 添加依赖
```xml
com.github.pagehelper
pagehelper
5.2.0
```
### Mybatis配置插件
typeAliases 之后
environments 之前
```xml
```
### 使用
```java
@Test
public void test2(){
//调用工具类 得到sqlSession
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//加载dao层映射
MoneyDao mapper = sqlSession.getMapper(MoneyDao.class);
//分页第一步 调用接口之前开启分页
PageHelper.startPage(1,5);
List userExes = mapper.selectUserMoneyPage();
//分页第二步,对拿到的数据进行处理
PageInfo userExPageInfo = new PageInfo(userExes);
logger.info("总条数"+userExPageInfo.getTotal());
for (UserEx userEx : userExPageInfo.getList()) {
System.out.println("userEx = " + userEx);
}
//手动关闭sqlsession(学到了spring过后就不需要了)
sqlSession.close();
}
```
# 五、常用插件
## 5.1、Lombok
```xml
org.projectlombok
lombok
1.18.12
provided
```
进行简单配置

下载IDEA的Lombok的插件支持

### 使用
```java
package com.xxgc.mybatis.po;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/* alt + insert 生成构造函数 */
@Setter
@Getter
//of={"uName","uPass"} 只想要这两个字段
//exclude={"uPass"} 排除字段
@ToString(exclude={"uPass"})
public class User {
private long uId;
private String uName;
private String uPass;
}
```
## 5.2 TableGo 偷懒工具
可以生成数据库文档
官网:http://www.tablego.cn/
# 六、注解增删改查
## 6.1 简单使用
需要在Dao层接口上添加 @Select @Insert @Update @Delete
需要在mybatis-config.xml中配置
```xml
```
## 6.2 Select查询
在进行多表联合查询的时候,遇到字段不匹配可以使用
```java
@Results(id = "UserExMap", value = {
@Result(column = "数据库字段名",property = "类属性名"),
@Result(column = "m_money",property = "money"),
@Result(column = "m_type",property = "type")
})
```
注意:只需要配置一次,如果还需要使用的地方用
```java
@ResultMap("UserExMap")
```
## 6.3 使用注解进行sql拼接
### 方法一
```java
//type 类名 method方法名
@SelectProvider(type = UserProvider.class,method = "selectUser")
List selectUserByAttr(@Param("uId") int uId, @Param("uName")String uName);
/*内部内*/
class UserProvider{
/*自定义的方法*/
public String selectUser(Map map){
String sql = "select * from users where 1 = 1 ";
if(map.get("uId") != null){
sql += "and u_id = #{uId} ";
}
if(map.get("uName") != null && map.get("uName") != ""){
sql += "and u_name = #{uName} ";
}
return sql;
}
}
```
### 方法二
```java
@Select({
""
})
List selectUserByAttr2(@Param("uId") int uId, @Param("uName")String uName);
```
# 七、 Mybatis处理表关联关系
## 7.1 一对一关系的处理
```xml
```
```java
List selectMoneyAndUser();
```
```java
package com.xxgc.mybatis.po;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
//Money表的映射
@Setter
@Getter
@ToString
public class Money {
private long mId;
private long mUserId;
private int mMoney;
private String mType;
//一笔钱对应一个用户
private User user;
}
```
## 7.2 一对多关系处理
```xml
```
```java
//查询用户顺便查询用户的Money
List selectUserAndMoney();
```
```java
package com.xxgc.mybatis.po;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.List;
/* alt + insert 生成构造函数 */
@Setter
@Getter
//of={"uName","uPass"} 只想要这两个字段
//exclude={"uPass"} 排除字段
@ToString(exclude={"uPass"})
public class User {
private long uId;
private String uName;
private String uPass;
private List moneyList;
}
```
# 八、Sql条件查询
创建news表
```sql
CREATE TABLE `news` (
`n_id` bigint(18) NOT NULL AUTO_INCREMENT COMMENT '新闻id',
`n_title` varchar(300) NOT NULL COMMENT '新闻标题',
`n_content` varchar(1000) NOT NULL COMMENT '新闻内容',
`n_author` varchar(30) NOT NULL COMMENT '作者',
PRIMARY KEY (`n_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='新闻表'
```
## 8.1 if标签
```xml
```
判断一个属性值是否为空,来拼接sql语句
## 8.2 where标签
```xml
```
用来代替传统sql语句中的where关键词,它可以在有条件的时候自动追加,没有条件的时候自动取消,可以把第一个条件的and给删除掉。
## 8.3 choose、when、otherwise标签
```xml
and 数据库字段 = #{属性}
and n_content = #{nContent}
and n_author = "张三"
```
它有点像 Java 中的 switch 语句,当有一个when执行的时候,下面的otherwise就不会执行。
**使用场景:当查询某些数据的时候,需要控制权限,什么条件都不给还是得追加一个条件。**
## 8.4 sql、include标签
```xml
SELECT * FROM `news`
```
可以把重复的sql语句(可以加标签)放到这个sql标签里面,写上id
```xml
```
在下面需要使用到的地方只需要写include
## 8.5 set标签
```xml
`n_title` = #{nTitle},
`n_content` = #{nContent},
`n_author` = #{nAuthor}
```
当在做更新的时候,不知道是哪个字段进行的更新,需要使用到if判断,但是使用if判断过后会有逗号的拼接问题,可以使用标签解决。
## 8.6 foreach标签
```xml
```
# 九、Mybatis缓存
### 什么是缓存?
缓存是一种数据和处理中心的一个中间件,从缓存查询可以提高效率,可以最大程度使用性能。
### 为什么使用缓存?
减少和数据库的交互次数,减少系统开销,提高系统效率。
### 什么样的数据能使用缓存?
经常查询并且不容易发生改变的数据。
### mybatis缓存
- MyBatis包含一个非常强大的查询缓存特性,它可以非常方便的定制和配置缓存,缓存可以极大的提升查询效率。
- Mybatis框架默认定义了两级缓存:**一级缓存和二级缓存**
默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
二级缓存需要手动开启和配置,他是基于namespace级别的缓存
为了提高扩展,Mybatis定义了缓存接口Cache。我们可以通过实现Cache接口来定义二级缓存
## 9.1 一级缓存
一级缓存也叫本地缓存:
与数据库在一次会话期间查询到的数据会放到缓存中。
以后如果需要获取相同数据,会直接从缓存中拿,没必要再去查询数据库。
注意:
必须保证多次查询中间,不能有任何的增删改操作,否则缓存数据会清空。
```java
//手动清理缓存
sqlSession.clearCache();
```
## 9.2 二级缓存
### 二级缓存使用
1、要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:
```xml
```
配置缓存
```xml
```
eviction 配置缓存策略
- `LRU` – 最近最少使用:移除最长时间不被使用的对象。
- `FIFO` – 先进先出:按对象进入缓存的顺序来移除它们。
- `SOFT` – 软引用:基于垃圾回收器状态和软引用规则移除对象。
- `WEAK` – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
flushInterval 刷新间隔
size 缓存可用空间
readOnly 只读 会返回相同实例(因为这些实例是不可修改的)
readOnly 查询出来的实例是可以修改的,但是如果为false两个实例不相同。
### 二级缓存总结:
业务逻辑层去拿数据的时候,会先看二级缓存里面有没有东西,如果有就返回,如果没有就查询,并把查询结果返回给二级缓存。
## 9.3 Mybaits缓存插件 ehcache
```xml
org.mybatis.caches
mybatis-ehcache
1.2.1
```
```xml
```
创建一个配置文件ehcache.xml
```xml
```
2、开启全局缓存
```xml
```
# 附录
## 1.IDEA常用快捷键
```
alt + insert 生成构造函数
```
```
ctrl + alt + f 提取/抽取 全局变量
```
```
ctrl + alt + v 自动生成返回结果
```
```
ctrl + alt + t 常用包裹代码生成
```
```
iter 生成foreach循环
```
## 2.IDEA配置自动导包
