
一、引言
1.1 什么是框架?
1.2 什么是ORM框架?
1.3 使用JDBC完成ORM操作的缺点?
二、MyBatis框架
2.1 概念
2.2 访问与下载
三、构建Maven项目
3.1 新建项目
使用IDEA打开已创建的文件夹目录 |

|
|
3.2 选择Maven目录
选择Maven项目 |

|
|
3.3 GAV坐标
GAV坐标 |

|
|
四、MyBatis入门案例【重点
】
4.1 pom.xml中引入MyBatis核心依赖
<?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>com.qf</groupId>
<artifactId>mybatis-02</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
4.2 创建db.properties配置文件
jdbc.url=jdbc:mysql://localhost:3306/java2002?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root
jdbc.driver=com.mysql.cj.jdbc.Driver
4.3 创建log4j.properties配置文件
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4.4 创建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">
<!-- mybatis的主配置文件 -->
<configuration>
<!-- 配置外部文件 -->
<properties resource="db.properties"></properties>
<!-- 配置别名 -->
<typeAliases>
<!-- <typeAlias type="com.qf.entity.User" alias="user"></typeAlias>-->
<package name="com.qf.entity"/>
</typeAliases>
<!-- 配置环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 配置数据源(连接池) -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
4.5 建表
create table t_user(
id int primary key auto_increment,
name varchar(50),
password varchar(50)
)default charset = utf8;
INSERT INTO t_user(NAME,PASSWORD) VALUES("jack","123");
INSERT INTO t_user(NAME,PASSWORD) VALUES("tom","456");
INSERT INTO t_user(NAME,PASSWORD) VALUES("rose","789");
4.6 定义实体类
package com.qf.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class User implements Serializable {
private Integer id;
private String name;
private String password;
}
4.7 定义DAO接口
package com.qf.dao;
import com.qf.entity.User;
public interface UserDao {
public List<User> findAll();
}
4.8 编写Mapper.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">
<!--namespace = 所需实现的接口全限定名-->
<mapper namespace="com.qf.dao.UserDao">
<!--配置查询所有-->
<!--id = 所需重写的接口抽象方法名,resultType = 查询后所需返回的对象类型-->
<select id="findAll" resultType="user">
select * from t_user
</select>
</mapper>
4.9 注册Mapper
<!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
<!--<mapper resource="com/qf/dao/UserDao.xml"/>-->
<!--<mapper class="com.qf.dao.UserDao"/>-->
<package name="com.qf.dao"/>
</mappers>
测试
package com.qf.demo;
import com.qf.dao.UserDao;
import com.qf.entity.User;
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 org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class MybatisTest {
//查询所有
@Test
public void testfindAll()throws Exception {
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
UserDao userDao = session.getMapper(UserDao.class);
//5.使用代理对象执行方法
List<User> users = userDao.findAll();
for(User user : users){
System.out.println(user);
}
//6.释放资源
session.close();
in.close();
}
}
五、MyBatis的CRUD操作【重点
】
7.1 在Dao添加方法
package com.qf.dao;
import com.qf.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.HashMap;
import java.util.List;
public interface UserDao {
public List<User> findAll();
public User findById(@Param("id") Integer id);
public void add(User user);
public void update(User user);
public void delete(String id);
//模糊查询1
public List<User> findByUserName1(String username);
//模糊查询2
public List<User> findByUserName2(String username);
//模糊查询3
public List<User> findByUserName3(String username);
//获取总记录数
public Integer getTotalCount();
//获取分页数据
public List<User> findPageData(HashMap<String,Integer> hashMap);
}
7.2 在Mapper.xml中添加对应的方法
<delete id="deleteUser" parameterType="int">
DELETE FROM t_users
WHERE id = #{id} <!--只有一个参数时,#{任意书写}-->
</delete>
7.3 测试
package com.qf.demo;
import com.qf.dao.UserDao;
import com.qf.entity.User;
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 org.junit.Test;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
public class Demo {
//查询所有
@Test
public void testfindAll()throws Exception {
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
UserDao userDao = session.getMapper(UserDao.class);
//5.使用代理对象执行方法
List<User> users = userDao.findAll();
for(User user : users){
System.out.println(user);
}
//6.释放资源
session.close();
in.close();
}
//查询单个
@Test
public void testfindById()throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
//---------------------------------------------
UserDao userDao = session.getMapper(UserDao.class);
//5.使用代理对象执行方法
User user = userDao.findById(1);
System.out.println(user);
//---------------------------------------------
session.close();
in.close();
}
//添加
@Test
public void testadd()throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
//---------------------------------------------
UserDao userDao = session.getMapper(UserDao.class);
User user = new User();
user.setName("张三");
user.setPassword("123");
userDao.add(user);
System.out.println(user.getId());
//提交
session.commit();
//---------------------------------------------
session.close();
in.close();
}
//修改
@Test
public void testupdate()throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
//---------------------------------------------
UserDao userDao = session.getMapper(UserDao.class);
User user = userDao.findById(4);
//user.setId(5);
user.setName("李四");
user.setPassword("456");
userDao.update(user);
//提交
session.commit();
//---------------------------------------------
session.close();
in.close();
}
//删除
@Test
public void testdelete()throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
//---------------------------------------------
UserDao userDao = session.getMapper(UserDao.class);
userDao.delete("4");
//提交
session.commit();
//---------------------------------------------
session.close();
in.close();
}
//模糊查询
@Test
public void testfindByUserName()throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
//---------------------------------------------
String name = "张";
UserDao userDao = session.getMapper(UserDao.class);
//List<User> users = userDao.findByUserName1(name);
//List<User> users = userDao.findByUserName2("%" + name + "%");
List<User> users = userDao.findByUserName3(name);
for(User user : users){
System.out.println(user);
}
//提交
session.commit();
//---------------------------------------------
session.close();
in.close();
}
//查询总记录数
@Test
public void testgetTotalCount()throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
//---------------------------------------------
UserDao userDao = session.getMapper(UserDao.class);
System.out.println(userDao.getTotalCount());
//提交
session.commit();
//---------------------------------------------
session.close();
in.close();
}
//查询分页数据
@Test
public void testfindPageData()throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession session = factory.openSession();
//---------------------------------------------
UserDao userDao = session.getMapper(UserDao.class);
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("first",0);
hashMap.put("second",3);
List<User> users = userDao.findPageData(hashMap);
for(User user : users){
System.out.println(user);
}
//提交
session.commit();
//---------------------------------------------
session.close();
in.close();
}
}
六、Druid连接池
6.1 概念
6.2基准测试结果对比
JDBC-Conn Pool |
1 Thread |
2 threads |
5 threads |
10 threads |
20 threads |
50 threads |
Druid |
898 |
1,191 |
1,324 |
1,362 |
1,325 |
1,459 |
tomcat-jdbc |
1,269 |
1,378 |
2,029 |
2,103 |
1,879 |
2,025 |
DBCP |
2,324 |
5,055 |
5,446 |
5,471 |
5,524 |
5,415 |
BoneCP |
3,738 |
3,150 |
3,194 |
5,681 |
11,018 |
23,125 |
jboss-datasource |
4,377 |
2,988 |
3,680 |
3,980 |
32,708 |
37,742 |
C3P0 |
10,841 |
13,637 |
10,682 |
11,055 |
14,497 |
20,351 |
Proxool |
16,337 |
16,187 |
18,310(Ex) |
25,945 |
33,706(Ex) |
39,501 (Ex) |
6.3 测试结论
- Druid 是性能最好的数据库连接池,tomcat-jdbc 和 druid 性能接近。
- Proxool 在激烈并发时会抛异常,不适用。
- C3P0 和 Proxool 都相当慢,影响 sql 执行效率。
- BoneCP 性能并不优越,采用 LinkedTransferQueue 并没有能够获得性能提升。
- 除了 bonecp,其他的在 JDK 7 上跑得比 JDK 6 上快。
- jboss-datasource 虽然稳定,但性能很糟糕。
6.4 配置pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
6.5 创建DruidDataSourceFactory
package com.qf.utils;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
public class MyDruidDataSourceFactory extends PooledDataSourceFactory {
public MyDruidDataSourceFactory() {
this.dataSource = new DruidDataSource();//替换数据源
}
}
6.6修改mybatis-config.xml
<!--连接池-->
<dataSource type="com.qf.utils.MyDruidDataSourceFactory">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
注意:< property name="属性名" />属性名必须与com.alibaba.druid.pool.DruidAbstractDataSource中一致。
七、PageHelper
7.1 概念
7.2 访问与下载
7.3 开发步骤
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.11</version>
</dependency>
<configuration>
<typeAliases></typeAliases>
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"/>
<property name="reasonable" value="true"/>
<property name="supportMethodsArguments" value="true"/>
</plugin>
</plugins>
<environments>...</environments>
</configuration>
//查询分页
@Test
public void testfindByPage()throws Exception {
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工厂生产SqlSession对象
SqlSession session = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
UserDao userDao = session.getMapper(UserDao.class);
//5.使用代理对象执行方法
PageHelper.startPage(1,2);//设置当前页和每页显示记录数
List<User> users = userDao.findAll();
PageInfo<User> userPageInfo = new PageInfo<>(users);//封装到PageInfo对象中
System.out.println(userPageInfo);
//6.释放资源
session.close();
in.close();
}
7.4 PageInfo对象
PageInfo结构图 |

|
|
7.5 注意事项