2021年10月7日

 

001

Author:Exchanges

Version:9.0.2

一、引言


1.1 什么是框架?

软件的半成品,解决了软件开发过程当中的普适性问题,从而简化了开发步骤,提供了开发的效率。

1.2 什么是ORM框架?

1.3 使用JDBC完成ORM操作的缺点?

  • 存在大量的冗余代码。

  • 手工创建 Connection、Statement 等。

  • 手工将结果集封装成实体对象。

  • 查询效率低,没有对数据访问进行过优化(Not Cache)。

二、MyBatis框架


2.1 概念

  • MyBatis本是Apache软件基金会的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了Google Code,并且改名为MyBatis 。2013年11月迁移到Github。

  • MyBatis是一个优秀的基于Java的持久层框架,支持自定义SQL,存储过程和高级映射。

  • MyBatis对原有JDBC操作进行了封装,几乎消除了所有JDBC代码,使开发者只需关注 SQL 本身。

  • MyBatis可以使用简单的XML或Annotation来配置执行SQL,并自动完成ORM操作,将执行结果返回。

2.2 访问与下载

官方网站:http://www.mybatis.org/mybatis-3/

下载地址:https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.5.1

三、构建Maven项目


3.1 新建项目

使用IDEA打开已创建的文件夹目录
002

3.2 选择Maven目录

选择Maven项目
003

3.3 GAV坐标

GAV坐标
image-20191230174727813

四、MyBatis入门案例【重点


4.1 pom.xml中引入MyBatis核心依赖

在pom.xml中引入相关依赖

<?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配置文件

在resources目录下创建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配置文件

在resources目录下创建log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# 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
级别描述
ALL LEVEL 打开所有日志记录开关;是最低等级的,用于打开所有日志记录。
DEBUG 输出调试信息;指出细粒度信息事件对调试应用程序是非常有帮助的。
INFO 输出提示信息;消息在粗粒度级别上突出强调应用程序的运行过程。
WARN 输出警告信息;表明会出现潜在错误的情形。
ERROR 输出错误信息;指出虽然发生错误事件,但仍然不影响系统的继续运行。
FATAL 输出致命错误;指出每个严重的错误事件将会导致应用程序的退出。
OFF LEVEL 关闭所有日志记录开关;是最高等级的,用于关闭所有日志记录。

4.4 创建mybatis-config.xml配置文件

在resources目录下创建并配置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 定义实体类

定义所需CURD操作的实体类

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接口

根据所需DAO定义接口、以及方法

package com.qf.dao;

import com.qf.entity.User;

public interface UserDao {
   
   public List<User> findAll();

}

4.8 编写Mapper.xml

在resources目录中下创建与Dao对应的路径和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

将Mapper.xml注册到mybatis-config.xml中

<!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
   <!--<mapper resource="com/qf/dao/UserDao.xml"/>-->
   <!--<mapper class="com.qf.dao.UserDao"/>-->
   <package name="com.qf.dao"/>
</mappers>

测试

在\src\test\java目录下创建测试类进行测试

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添加方法

在src\main\java\com\qf\dao\UserDao.java中添加方法

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中添加对应的方法

在\src\main\resources\com\qf\dao\UserDao.xml中写对应的sql

<?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.qf.dao.UserDao">

   <!--配置查询所有-->
   <select id="findAll" resultType="user">
      select * from t_user
   </select>

   <!-- 查询单个对象 -->
   <select id="findById" resultType="com.qf.entity.User">
      select * from t_user where id = #{id}
   </select>


   <insert id="add">

       <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
          select last_insert_id();
       </selectKey>

      insert into t_user(name,password) values( #{name},#{password} )

   </insert>

   <update id="update">
      update t_user set name = #{name} where id = #{id}
   </update>

   <delete id="delete">
      delete from t_user where id = #{id}
   </delete>

   <!-- 模糊查询1 -->
   <select id="findByUserName1" resultType="user">
      SELECT * FROM t_user
      WHERE name LIKE concat('%',#{name},'%') <!-- 拼接'%' -->
   </select>

   <!-- 模糊查询2 -->
   <select id="findByUserName2" resultType="com.qf.entity.User">
      select * from t_user where name like #{name}
   </select>

   <!-- 模糊查询3 -->
   <select id="findByUserName3" resultType="com.qf.entity.User">
      select * from t_user where name like "%"'${value}'"%"
   </select>

   <!-- 查询总记录数 -->
   <select id="getTotalCount" resultType="java.lang.Integer">
      select count(id) from t_user
   </select>

   <!-- 查询总记录数 -->
   <select id="findPageData" resultType="com.qf.entity.User">
      select * from t_user limit #{first},#{second}
   </select>

</mapper>

7.3 测试

在\src\test\java目录下测试类中添加方法进行测试

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 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();
  }

   //查询单个
   @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.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.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.close();
       in.close();
  }

}

六、Druid连接池


6.1 概念

Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和 SQL 解析器组成。该项目主要是为了扩展 JDBC 的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计 SQL 信息、SQL 性能收集、SQL 注入检查、SQL 翻译等,程序员可以通过定制来实现自己需要的功能。

6.2基准测试结果对比

JDBC-Conn Pool1 Thread2 threads5 threads10 threads20 threads50 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 测试结论

6.4 配置pom.xml

引入Druid依赖

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.1.21</version>
</dependency>

6.5 创建DruidDataSourceFactory

在\src\main\java\com\qf\utils目录创建MyDruidDataSourceFactory来替换数据源

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

修改mybatis-config.xml中连接池的相关配置,指定Druid数据源

<!--连接池-->
<dataSource type="com.qf.utils.MyDruidDataSourceFactory">
   <property name="driverClassName" value="${jdbc.driver}"/>
   <property name="url" 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 概念

PageHelper是适用于MyBatis框架的一个分页插件,使用方式极为便捷,支持任何复杂的单表、多表分页查询操作。

7.2 访问与下载

官方网站:https://pagehelper.github.io/

下载地址:https://github.com/pagehelper/Mybatis-PageHelper

7.3 开发步骤

1.在pom.xml中引入PageHelper依赖。

<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper</artifactId>
   <version>5.1.11</version>
</dependency>

2.在MyBatis-config.xml中添加< plugins >

<configuration>
<typeAliases></typeAliases>
       
  <plugins>
      <!-- com.github.pagehelper为PageHelper类所在包名 -->
       <plugin interceptor="com.github.pagehelper.PageInterceptor">
           <property name="reasonable" value="true"/>
           <property name="supportMethodsArguments" value="true"/>
       </plugin>
   </plugins>
 
<environments>...</environments>
</configuration>

3.在测试类中添加方法进行测试

//查询分页
   @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对象中包含了分页操作中的所有相关数据。

PageInfo结构图
image-20200116145234073

7.5 注意事项



posted @ 2021-10-07 21:36  张三疯321  阅读(45)  评论(0)    收藏  举报