mybatis-9.28
环境:
JDK1.8
MySQL5.7
maven 3.6.1
IDEA
回顾:
- JDBC
- MySQL
- Java基础
- Maven
- Junit
SSM框架:配置文件的。最好的方式就是看官网文档
1、简介
1.1什么是mybatis
- Mybatis是一款优秀的持久层框架
- 它支持定制化SQL,存储过程以及高级映射
- Mybatis避免了JDBC和手动设置参数以及获取结果集。Mybatis使用简单的XML或者注解来配置和映射原生类型、接口和Java的POJO为数据库中的记录
- MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code code/2346604),并且改名为MyBatis 。2013年11月迁移到Github。
如何获得Mybatis?
- Maven仓库
- GitHub
- 中文文档
1.2持久化
数据持久化
- 数据持久化就是将持久状态和瞬时状态转化的过程
- 内存:断电即失
- 数据库(jdbc),io文件持久化。
为什么需要持久化
- 有一些对象,不能丢掉
- 内存太贵了
1.3持久层
Dao层,Service层,Controller层。。。
- 完成持久化工作的代码块
- 层是界限十分明显的
1.4为什么需要Mybatis
传统JDBC代码太复杂。简化。框架。自动化
2、第一个Mybatis程序
思路:搭建环境—>导入Mybatis—>编写代码—>测试
2.1搭建环境
搭建数据库
新建项目
思路
搭建环境 -- 导入mybatis -- 编写代码 -- 进行测试
新建普通maven项目
删除src,当做父工程
导入maven依赖
<!--导入依赖-->
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
2.2创建一个模块
编写Mybatis核心配置文件
<!--mybatis的核心配置文件-->
<configuration>
<!--配置环境-->
<environments default="development">
<!--配置mysql的环境-->
<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/mybatisdesign?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
编写Mybatis的工具类 ```java //SqlSessionFactory —> SqlSession public class MybatisUtils {
//提升作用域 public static SqlSessionFactory sqlSessionFactory;
static{
try {
//使用Mybatis第一步:获取SqlSessionFactory
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//既然有了SqlSessionFactory,我们就可以使用SqlSession的实例了 //SqlSession完全包含了面向数据库执行SQL的所有方法
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
<a name="a750c17c"></a>
## 2.3、编写代码
<a name="5407ca53"></a>
### 1.实体类
(???lombock是个啥??)
```java
package com.zmy.pojo;
public class User {
private int id;
private String name;
private String password;
public User() {
}
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2.Dao接口
public interface UserDao {
List<User> getUserList();
}
3.接口实现类
由原来的Implement实现类转为了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">
<!--namespace绑定的是对应的Dao/Mapper接口-->
<mapper namespace="com.zmy.dao.UserDao">
<!--select查询语句-->
<select id="getUserList" resultType="com.zmy.pojo.User">
select * from user;
</select>
</mapper>
2.4、测试
Type interface com.zmy.dao.UserMapper is not known to the MapperRegistry
注意一点:maven的资源过滤问题(约定大于配置)
xml配置文件不存在,或者无法导出生效。解决方案:
<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>
tips:在resource目录中新建层级目录用\隔开
junit测试
public class UserMapperTest {
@Test
public void test(){
//第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行SQL 方式一:getMapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}
}
3、问题总结
- 配置文件没有注册
- 绑定接口错误
- 方法名不对
- 返回类型不对
- 目录建造方式不对\ .
- maven导出资源不对
4、CRUD
1、namespace
namespace中的包名要和Dao/Mapper接口的报名一致
2、select
选择,查询语句
id 对应namespace中的方法名
resultType SQL语句执行的返回值!:对应的实体类pojo的全限定类名
parameterType 参数类型
- 编写接口
//根据id查询用户
User getUserById(int id);
- 编写对应的mapper中的SQL语句
<select id="getUserById" parameterType="int" resultType="com.zmy.pojo.User">
select * from mybatis.user where id = #{id};
</select>
测试
@Test
public void testGetUserById(){
//第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行SQL 方式一:getMapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserById(2);
System.out.println(user);
//关闭SqlSession
sqlSession.close();
}
3、insert(增删改提交事务)
<insert id="addUser" parameterType="com.zmy.pojo.User">
insert into mybatis.user (id,name,password) values (#{id},#{name},#{password});
</insert>
4、update
<update id="updateUser" parameterType="com.zmy.pojo.User">
update mybatis.user set name = #{name}, password = #{password} where id = #{id} ;
</update>
5、delete
<delete id="delUser" parameterType="int">
delete from mybatis.user where id = #{id};
</delete>
6、分析错误
- 标签匹配
- namespace绑定. resource绑定/
- 程序配合文件规范
- 空指针异常 没有注册到资源 SqlsessionFactory
- maven资源没有导出 build
7、万能map
int addU(Map<String,Object> map);
<insert id="addU" parameterType="map">
insert into mybatis.user (id, name, password) values (#{userId},#{userName},#{userPassword});
</insert>
@Test
public void testAdd2(){
//第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行SQL 方式一:getMapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Object> map = new HashMap<String, Object>();
map.put("userId",5);
map.put("userName","yyds");
mapper.addU(map);
//提交事务
sqlSession.commit();
//关闭SqlSession
sqlSession.close();
}
8、模糊查询
5、配置解析
1、核心配置文件
mybatis-config.xml
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
2、环境配置(environments)
3、属性(properties)
我们可以通过properties属性来实现引用配置文件
这些属性可以在外部进行配置,并可以进行动态替换,既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【db.properties】
- 编写一个配置文件【db.properties】
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username = root
password = 123456
- 在核心配置文件中引入
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="1231156"/>
</properties>
- 可以直接引入外部文件
- 可以在其中加入属性配置
- 同一字段优先使用配置文件的!
4、类型别名(typeAliases)
- 类型别名可为 Java 类型设置一个缩写名字。
- 它仅用于 XML 配置,意在降低冗余的全限定类名书写
<typeAliases>
<typeAlias type="com.zmy.pojo.User" alias="user"/>
</typeAliases>
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean
<typeAliases>
<package name="com.zmy.pojo"/>
</typeAliases>
也可以注解
@Alias("user")
public class User {
5、设置(settings)
官方文档
6、其他配置
- 类型处理器(typeHandlers)
- 对象工厂(objectFactory)
插件(plugins)
- mybatis-generator-core
- mybatis-plus
- 通用mapper
7、映射器(mappers)
MapperRegistry:注册绑定我们的Mapper文件
方式一:[推荐使用]
<mappers>
<mapper resource="com/zmy/dao/UserMapper.xml"/>
</mappers>
方式二:使用class文件绑定注册
<mappers>
<mapper class="com.zmy.dao.UserMapper"/>
</mappers>
- 注意点
- 接口与Mapper配置文件同名
- 接口与Mapper配置文件在同一个包下
方式三:使用包扫描
<mappers>
<package name="com.zmy.dao"/>
</mappers>
8、生命周期和作用域
6、结果集映射(ResultMap)
解决字段名和属性名不一致的问题 resultType==ResultMap
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
7、日志工厂
[ ] 代替sout和debug
STDOUT_LOGGING
LOG4J
1、LOG4J
- 导入log4j包 (maven依赖)
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency
resoure—-log4j.properties
配置log4j的实现 settings中配置
简单使用
再要使用Log4J的类中,导入包 import org.aphace。log4j.logger
日志对象,参数为当前类的class
static Logger logger = Logger.getLogger(UserDaoTest.class);
- 日志级别
8、分页
- 减少数据的处理量
8.1、使用Limit分页
select * from user limit 0,4;
使用mybatis实现分页,核心SQL
- 接口Dao
//分页
List<User> getUserByLimit(Map<String, Integer> map);
- mapper.xml
<select id="getUserByLimit" parameterType="map" resultType="user">
select * from mybatis.user limit #{startIndex},#{pageSize};
</select>
测试
@Test
public void limit(){
//第一步:获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行SQL 方式一:getMapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Integer> map = new HashMap();
map.put("startIndex",0);
map.put("pageSize",2);
List<User> userList = mapper.getUserByLimit(map);
for (User user : userList) {
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}
9、注解开发
9.1、面向接口编程
解耦
在一个[面向对象](https://baike.baidu.com/item/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1)的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对[系统设计](https://baike.baidu.com/item/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1)人员来讲就不那么重要了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。
关于接口的理解。
接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
接口的本身反映了系统设计人员对系统的抽象理解。
接口应有两类:
- 第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
- 第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
一个体有可能有多个抽象面。抽象体与抽象面是有区别的。
三个面向区别
- 面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法
- 面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现
- 接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题。更多的体现就是对系统整体的架构
9.2、使用注解开发
- ### mybatis执行流程
10、Lombock
使用步骤:
- idea安装插件 lombock
- 在项目中导入lombock的jar包
11、多对一
- 按照查询嵌套处理
- 按照结果嵌套处理
<select id="getStudent" resultMap="StudentTeacher">
select s.id sid,s.name sname,t.name tname
from student s , teacher t
where s.tid = t.id;
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
12、一对多
- 按照查询嵌套处理
- 按照结果嵌套处理
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid,s.name sname,t.name tname,t.id tid
from student s , teacher t
where s.tid = t.id and t.id = #{tid};
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<colletion property="student" ofType="Student">
<result property="name" column="sname"/>
<result property="id" column="sid"/>
</colletion>
</resultMap>
小结
- associaation 【多对一】
- collection 【一对多】
JavaType & ofType
- JavaType 用来指定实体类中的类型
- ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型
注意点:
- 保证 sql 的可读性
- 注意多对多的,属性和字段名匹配问题
- 标签
慢SQL
面试高频
- MySQL引擎
- InnoDB底层原理
- 索引
- 索引优化
13、动态SQL
什么是动态SQL:根据不同的条件生成不同的SQL语句
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
if
choose (when, otherwise)
trim (where, set)
foreach
搭建环境
if
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>