Mybatis
ssm框架:配置文件的。最好的方式:看官方文档
1、简介
1.1、什么是Mybatis
- MyBatis 是一款优秀的持久层框架.
- 它支持定制化 SQL、存储过程以及高级映射。
- MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。
- MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和JavaPOJO (Plain Old JavaObjects,普通老式Java对象)为数据库中的记录。
- MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并E改名为MyBatis.
- 2013年11月迁移到Github。
如何获取MyBatis ?
- Maven仓库
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency>
- GitHub:https://github.com/mybatis/mybatis-3/releases
- 中文文档:https://mybatis.net.cn/
1.2、持久化
数据持久化.
- 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
- 内存:断电即失.
- 数据库(Jdbc), io文件持久化。
- 生活:冷藏,罐头。
为什么需要需要持久化?.
- 有一些对象,不能让他丢掉。
- 内存太贵了
1.3、持久层
Dao层,Service层,Controller层…
- 完成持久化工作的代码块.
- 层界限十分明显。
1.4、为什么需要Mybatis?
- 帮助程序猿将数据存入到数据库中。.
- 方便.
- 传统的JDBC代码太复杂了。简化。框架。自动化。.
- 不用Mybatis也可以。更容易上手。技术没有高低之分
- 有点:
o 简单易学
o 灵活
o sql和代码的分离,提高了可维护性。
o 提供映射标签,支持对象与数据库的orm字段关系映射
o 提供对象关系映射标签,支持对象关系组建维护
o 提供xml标签,支持编写动态sql.
最重要的一点:学习使用的人多
2、第一个Mybatis程序
思路:搭建环境–》导入Mybatis–>编写代码–》测试!
2.1、搭建环境
搭建数据库
CREATE DATABASE mybatis;
USE ‘mybatis;
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,‘李四’,‘123890’)
新建项目
1.新建一个maven普通项目
2.删除src目录
3.导入maven依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
2.2、创建一个模块
- 编写mybatis的核心配置文件
<!-- 环境:配置mybatis的环境 -->
<environments default="development">
<!-- 环境变量:可以配置多个环境变量,比如使用多数据源时,就需要配置多个环境变量 -->
<environment id="development">
<!-- 事务管理器 -->
<transactionManager type="JDBC"/>
<!-- 数据源 -->
<dataSource type="">
<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="111111"/>
</dataSource>
</environment>
</environments>
- 编写mybatis工具类
package com.syj.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 {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
2.3、编写代码
- 实体类
package com.syj.entily;
import lombok.*;
@Data
@ToString
public class User {
private int id;
private String name;
private String pwd;
}
- Dao接口
package com.syj.dao;
import com.syj.entily.User;
import java.util.List;
public interface UserDao {
List<User> getUserList();
}
- 接口实现类由原来的UserDaoImpl转换为一个Mapper配置文件
<?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.syj.dao.UserDao">
<select id="getUserList" resultType="com.syj.entily.User">
select * from user
</select>
</mapper>
2.4、测试
junit测试
遇到的问题
1.配置文件没有注册
2.绑定接口错误
3.方法名不对
4.返回类型不对
5.Maven导出资源问题
3、CRUD
1、 namespace
namespace中的包名要和Dao/Mapper接口的包名一致!
2、 select
选择,查询语句;
- .id:就是对应的namespace中的方法名;
- .resultType: Sql语句执行的返回值!.
- parameterType : 参数类型!
1.编写接口
//根据Id查询用户
User getUser(User user)
2.编写对应的Mapper中的Sql语句
<select id="getuserById" parameterType="int" resultType="com. kuang. pojo.user">
select * from mybatis.user where id = #{id}
</select>
3.测试
@Test
public void getuserById(
Sqlsession sqlsession = Mybatisutils.getsqlsession ();
usermapper mapper = sqlSession. getMapper (userMapper.class);
User user = mapper. getuserById (1);
system.out.println (user);
sqlSession.close();
}
3、Insert
4、Update
5、Delete
注意:
- 增删改需要提交事务!
6、分析错误
- .标签不要匹配错resource 定mapper,需要使用路径!
- .程序配置文件必须符合规范!
- NullPointerException,没有注册到资源!
- 输出的xml文件中存在中文乱码问题!.
- maven资源没有导出问题!
7、万能Map
8、思考题
模糊查询怎么写?
4、配置解析
1、核心配置文件
2、环境配置(environments)
3、属性(Properties)
4、类型别名typeAilases
5、设置
6、其他配置
7、映射器Mappers
8、生命周期和作用域
这里面每一个mapper,就代表一个具体业务!
5、解决属性名和字段名不一致的问题
5.1、问题
5.1、ResultMap
6、日志
6.1、日志工厂
6.2、Log4j
1.导入log4j的包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2.log4j.properties
### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.Threshold = DEBUG org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{
yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{
yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{
yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
7、分页
7.2、RowBounds分页
不再使用SQL实现分页
7.3、分页插件
8、使用注解开发
81、面向接口编程
Mybatis详细执行流程
8.3、CRUD
9、Lombok
Project Lombok是一个java库,它可以自动插入您的编辑器和构建工具,为您的java增添趣味。永远不要再编写另一个getter或equals方法,只要有一个注释,你的类就有了一个功能齐全的构建器。自动化日志变量等等。
使用步骤
1.在idea中安装Lombok插件
2.在项目中导入Lombokjar包
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
3.在实体类加上注解即可
@NonNull
@Cleanup
@Getter/@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor
@Data
@Value
@SneakyThrows
@Synchronized
@Log
@Data:无参构造, get, set, tostring, hashcode, equals
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter @Setter
10、多对一处理(关联查询)
多对一:
- 多个学生,对应一个老师
- 对于学生这边而言,关联…多个学生,关联一个老师 【多对一】
- 对于老师而言,集合,一个老师,有很多学生【一对多】
测试环境搭建
1.导入Lombok
2.新建实体类Teacher,Studnet
3.建立mapper接口
4.建立mapper.xml文件
5.在核心配注册我们的Mapper接口或者文件【方式很 随心选择】
6.测试查询是否成功
按照查询嵌套处理(子查询)
实体类
@Data
public class Teacher{
private int id;
privite String name;
}
@Data
public class Student{
private int id;
privite String name;
//学生需要关联一个老师
privite Teacher teacher;
}
按照结果嵌套处理(联表查询)
回顾Mysql多对一查询方式
- 子查询
- 联表查询
11、一对多处理
比如:一个老师拥有很多学生
对于老师而言,就是一对多
实体类
@Data
public class Student{
private int id;
privite String name;
private int tid;
}
@Data
public class Teacher{
private int id;
privite String name;
//一个老师拥有多个学生
privite List<Student> Students
}
按照结果嵌套处理
按照查询嵌套处理
小结
1.关联:association 多对一
2.集合:collection 一对多
3.javaType & ofType
- JavaType用来指定实体类中属性的类型
- ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!
注意点
.保证SQL的可读性,尽量保证通俗易懂
.注意一对多和多对一中,属性名和字段的问题!
.如果问题不好排查错误,可以使用日志,建议使用Log4j
面试高频.
Mysql引擎
.InnoDB底层原理
索引
.索引优化!
12、动态SQL
什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句
利用动态SQL这一特性可以彻底摆脱这种痛苦。
搭建环境
UUID
IF
Choose(when,otherwise)
trim(where,set)
所谓的动态SQL, 本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码
if
where, set, choose , when
Foreach
SQL片段
有的时候,我们可能会将一些功能的部分抽取出来,方便复用!
1.使用SQL标签抽取公共的部分
2.在需要使用的地方使用Include标签引用即可
注意事项:
- .最好基于单表来定义SQL片段!
- .不要存在where标签
动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了
建议:.
现在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可!
13、缓存
13.1、简介
1.什么是缓存[Cache ]?
০存在内存中的临时数据。
০将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
2.为什么使用缓存?
০减少和数据库的交互次数,减少系统开销,提高系统效率。
3.什么样的数据能使用缓存?
০经常查询并且不经常改变的数据。
13.2、Mybatis缓存
- MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。.
- MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存。
o 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)。
o 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。。
o 为了提高扩展性, MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
13.3、一级缓存
- 一级缓存也叫本地缓存:。
o 与数据库同一次会话期间查询到的数据会放在本地缓存中。。
o 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;加粗样式
测试步骤:
1.开启日志!
2.测试在一个Sesion中查询两次相同记录
3.查看日志输出
缓存失效的情况:
1.查询不同的东西
2.增删改操作,可能会改变原来的数据,所以必定会刷新缓存!
3.查询不同的Mapper.xml
4.手动清理缓存!
小结:
- 一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!
- 一级缓存就是一个Map.
13.4、二级缓存
- 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存.
- 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;.
- 工作机制。
o 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;。
o 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;。
o 新的会话查询信息,就可以从二级缓存中获取内容;。
o 不同的mapper查出的数据会放在自己对应的缓存(map)中;
小结:.
- 只要开启了二级缓存,在同一个Mapper下就有效.
- 所有的数据都会先放在一级缓存中;.
- 只有当会话提交,或者关闭的时候,才会提交到二级缓冲中!
缓存原理
13.6、自定义缓存ehcache
要在程序中使用ehcache,先要导包!
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.0</version>
</dependency>
ehcache.xml
在这里插入代码片
已Redis数据库来做缓存! K-V