一、概述
1.MyBatis 是什么
一款半自动的ORM(对象关系映射)持久层框架,它内部封装了JDBC,MyBatis 可以使用 XML 或注解来配置和映射原生信息。
2.原理是什么
1.读取sqlmapconfig.xml获得输入流
2.创建sqlsessionfactorybuilder,获得sqlsessionfactory
3.通过opsession,获得sqlsession
4.获得mapper,代理对象
5.调用方法
6.释放资源
public static void main(String[] args) throws Exception {
// 配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 生成SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 打开回话
SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取代理类
EmpDao mapper = sqlSession.getMapper(EmpDao.class);
// 通过代理类调用查询方法
Emp empByEmpno = mapper.findEmpByEmpno(7369);
// 关闭会话
sqlSession.close();
}
3.优点
1.SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
(2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
(4)能够与Spring很好的集成;
(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
缺点:
1.SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
2.SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
4.二级缓存
分两个:一级缓存SqlSession级别缓存(本地缓存),默认开启,二级缓存mapper级别的
sqlSession缓存:
第一次执行select查询,会将查到的结果放入map中存起来。
第二次查询,如果select相同且参数一样,那么就从缓存中返回数据,不去查数据库,从而提高了效率
作用域是session级别的,如果删除了,或者关闭了,下次查询还是重数据库中查询。
mapper缓存:二级
存储结果也是map。作用域为mapper.xml(namespace)
默认没开启
第一次是调用mapper的sql查询数据库,查到数据会放入改对应的mapper二级缓存区域,
第二次调用,相同的sql就会调用二级缓存了。
二、入门使用
1.打开IDEA,创建一个maven项目。
2.导入依赖的jar包。(mysql版本根据自己安装版本)
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
3.创建一个实体类(bean/entity等)
import lombok.Data;
import java.io.Serializable;
/**
* 用户信息
*/
@Data
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
//姓名
private String name;
//手机号
private String phone;
//性别 0 女 1 男
private String sex;
//身份证号
private String idNumber;
//头像
private String avatar;
//状态 0:禁用,1:正常
private Integer status;
}
4.编写mapper映射文件(编写SQL)
<!-- StudentMapper.xml -->
<?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="test">
<select id="findAll" resultType="com.yogurt.po.Student">
SELECT * FROM student;
</select>
<insert id="insert" parameterType="com.yogurt.po.Student">
INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});
</insert>
<delete id="delete" parameterType="int">
DELETE FROM student WHERE id = #{id};
</delete>
</mapper>
5.编写数据源properties文件
db.url=jdbc:mysql://192.168.183.129:3306/yogurt?characterEncoding=utf8
db.user=root
db.password=root
db.driver=com.mysql.jdbc.Driver
6.编写全局配置文件(主要是配置数据源信息)
<?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>
<!-- 配置文件信息 -->
<properties resource="properties/db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 从配置文件中加载属性 -->
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 加载前面编写的SQL语句的文件 -->
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>
7.编写dao类
package com.yogurt.dao;
import com.yogurt.po.Student;
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;
import java.util.List;
public class StudentDao {
private SqlSessionFactory sqlSessionFactory;
public StudentDao(String configPath) throws IOException {
InputStream inputStream = Resources.getResourceAsStream(configPath);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public List<Student> findAll() {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<Student> studentList = sqlSession.selectList("findAll");
sqlSession.close();
return studentList;
}
public int addStudent(Student student) {
SqlSession sqlSession = sqlSessionFactory.openSession();
int rowsAffected = sqlSession.insert("insert", student);
sqlSession.commit();
sqlSession.close();
return rowsAffected;
}
public int deleteStudent(int id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
int rowsAffected = sqlSession.delete("delete",id);
sqlSession.commit();
sqlSession.close();
return rowsAffected;
}
}
8.创建controller,service,serviceimpl,编写业务代码
9.创建mapper接口和mapper.xml映射文件,编写SQL语句
mapper.xml的SQL语句中的占位符${}和#{}
一般会采用#{},#{}在mybatis中,最后会被解析为?,其实就是Jdbc的PreparedStatement中的?占位符,它有预编译的过程,会对输入参数进行类型解析(如果入参是String类型,设置参数时会自动加上引号),可以防止SQL注入,如果parameterType属性指定的入参类型是简单类型的话(简单类型指的是8种java原始类型再加一个String),#{}中的变量名可以任意,如果入参类型是pojo,比如是Student类
而${},一般会用在模糊查询的情景,比如SELECT * FROM student WHERE name like '%${name}%';
它的处理阶段在#{}之前,它不会做参数类型解析,而仅仅是做了字符串的拼接。
@TableField 取别名
resultType和parameterType
使用 resultType : 主要针对于从数据库中提取相应的数据出来.查数据
使用parameterType : 主要针对于 将信息存入到数据库中 如: insert 增加数据到数据库
mapper.xml完成增删改查操作
注意避免两个大坑:1.toString()2.==(等于),大于小于要用转义符,防止SQL注入
使用注解完成增删改查操作