Mybatis
mybais 一级和二级缓存
💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙💙
MyBatis是当前主流的Java持久层框架之一
MyBatis框架也被称为ORM(Object/ Relational Mapping,对象关系映射)框架。所谓ORM
Hibernate也是一个持久层框架
Hibernate和mybatis 区别
面试也会问
(1)Hibernate:一个全表映射的框架。通常开发者只需定义好持久化对象到数据库表的映射关系,就可以通过Hibernate提供的方法完成持久层操作。开发者并不需要熟练地掌握SQL语句的编写,Hibernate会根据制定的存储逻辑自动生成对应的SQL,并调用JDBC接口来执行,所以其开发效率会高于MyBatis。然而Hibernate自身存在着一些缺点,例如它在多表关联时,对SQL查询的支持较差;更新数据时,需要发送所有字段;不支持存储过程;不能通过优化SQL来优化性能等。这些问题导致其只适合在场景不太复杂且对性能要求不高的项目中使用。
(2)MyBatis:一个半自动映射的框架。这里所谓的“半自动”是相对于Hibernate全表映射而言的,MyBatis需要手动匹配提供POJO、SQL和映射关系,而Hibernate只需提供POJO和映射关系即可。与Hibernate相比,虽然使用MyBatis手动编写SQL要比使用Hibernate的工作量大,但MyBatis可以配置动态SQL并优化SQL,可以通过配置决定SQL的映射规则,它还支持存储过程等。对于一些复杂的和需要优化性能的项目来说,显然使用MyBatis更加合适
持久层
持久层可以将业务数据存储到磁盘,具备长期存储能力,只要磁盘不损坏(大部分的重要数据都会有相关的备份机制),在断电或者其他情况下,重新开启系统仍然可以读取这些数据
mybatis 三大特点
- 不屏蔽SQL,意味着可以更精确地定位SQL语句,可以对其进行优化和改造
- 提供强大、灵活的映射机制,方便Java开发者使用。提供动态SQL的功能
- 提供了使用Mapper的接口编程,只需一个接口和一个XML就能构建映射器,进一步简化了用户的工作
MyBatis的核心组件
SqlSessionFactoryBuilder
根据配置或者代码生成SqlSessionFactory,采用分步构建的Builder模式
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactory
SqlSessionFactory(工厂接口):生成SqlSession,使用工厂模式
//获取SqlSession连接
public static SqlSession getSession() {
// 数据源 执行器 DefaultSqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
SqlMapper
SqlMapper(映射器):由Java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则。负责发送SQL去执行,并返回结果。
<mapper namespace="com.wu.mapper.UserMapper">
</mapper>
搭建mybatis
新建maven 工程
数据库
CREATE TABLE `user` (
`id` int NOT NULL,
`name` varchar(255) DEFAULT NULL,
`createdate` date DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
从上到下
package com.wu.entity;
import java.io.Serializable;
import java.util.Date;
/***
* @Author 徐庶 QQ:1092002729
* @Slogan 致敬大师,致敬未来的你
*/
public class User implements Serializable {
private Integer id ;
private String name ;
//为了展示手动映射的作用,多加个e
private Date createdate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreatedate() {
return createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", createdate=" + createdate +
'}';
}
}
UserMapper
/***
* @Author
* @Slogan
*/
public interface UserMapper {
}
App
public class App {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
//将XML配置文件构建为Configuration配置类
InputStream inputStream = Resources.getResourceAsStream(resource);
// 通过加载配置文件流构建一个SqlSessionFactory DefaultSqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession连接
public static SqlSession getSession() {
// 数据源 执行器 DefaultSqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true);
return sqlSession;
}
}
UserMapper.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="com.wu.mapper.UserMapper">
<!-- 二级缓存-->
<!-- 手动映射-->
<!-- Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?-->
<resultMap id="result" type="com.wu.entity.User" >
<!-- column是数据库表的列名 , property是对应实体类的属性名 -->
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="createdate" jdbcType="DATE" property="createdate"></result>
</resultMap>
</mapper>
db.properties
mysql.driverClass=com.mysql.cj.jdbc.Driver
mysql.jdbcUrl=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimeZone=UTC
mysql.user= root
mysql.password= 123456
//自己改自己的配置
log4j.properties
### Logger - 日志写出器,供程序员输出日志信息 ###
# log4j.rootLogger=[级别:OFF、 FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL],[输出源:可以配置多个,用","分开]
log4j.rootLogger=INFO,CONSOLE
### 配置上面指定的"CONSOLE" ###
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.Threshold=TRACE
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH:mm:ss,SSS}][%C{1}:%L] %m%n
log4j.logger.com.wu.mapper=TRACE
mybatis-config.xml
<?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 扫描属性文件.properties -->
<properties resource="db.properties"></properties>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启日志功能-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- <plugins>
<plugin interceptor="com.tuling.plugins.ExamplePlugin" ></plugin>
</plugins>-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--// mybatis内置了JNDI、POOLED、UNPOOLED三种类型的数据源,其中POOLED对应的实现为org.apache.ibatis.datasource.pooled.PooledDataSource,它是mybatis自带实现的一个同步、线程安全的数据库连接池 一般在生产中,我们会使用c3p0或者druid连接池-->
<dataSource type="POOLED">
<property name="driver" value="${mysql.driverClass}"/>
<property name="url" value="${mysql.jdbcUrl}"/>
<property name="username" value="${mysql.user}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappper/UserMapper.xml"></mapper>
</mappers>
</configuration>
测试类自己新建就可以
加个pom 文件吧,数据库版本选择自己版本的依赖,我的是8.0.23的
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
</dependencies>
</project>
测试增删改查
UserMapper.java
//查询用户
List<User> selectUser();
//添加一个用户
int addUser(User user);
//修改一个用户
int updateUser(User user);
//根据id删除用户
int deleteUser(int id);
UserMapper.xml
<select id="selectUser" resultMap="result">
select * from user
</select>
<insert id="addUser" parameterType="com.wu.entity.User" >
insert into user (id,name,createdate) values (#{id},#{name},#{createdate})
</insert>
<update id="updateUser">
update user set name=#{name} where id = #{id}
</update>
<delete id="deleteUser">
delete from user where id=#{id}
</delete>
测试类
@Test
public void test(){
SqlSession session = App.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user : users) {
System.out.println(user.toString());
}
}
剩下自己去测试
对了增加删除和修改记得提交事务
session.commit();