Mybatis框架详解

Mybatis框架

一. 引言

1.为什么使用mybatis

目前使用开发遇到的问题

问题一:每一个操作对应的使用Dao中的方法,内一个方法中都需要连接数据库,这样我们连接数据库的代码就需要些好多次

问题二:如果我们做的是查询的操作,从rs中取值是一个比较麻烦而且影响开发效率的问题

解决方案:

1.提取DBUtil工具类即可

优点:不用再每一次写连接数据库操作的代码

缺点:传统的JDBC连接数据库的效率非常的慢

2.使用数据库连接池连接数据库

优点:连接数据库的速度比较快

缺点:没有办法实现SQL语句和java代码之间的解耦

3.使用mybatis框架

作用: 1) 解决了SQL语句和java代码之间的耦合

​ 2) 连接数据库的效率也比较快

​ 3) 取值问题就会变得非常的简单

2.什么是框架?

框架就是别人封装好的代码,我们直接拿来用就好
框架的体现形式就是jar包。我们自己写好的代码也可以打成jar包,别人也可以使用。

(jar包 API 源码)

3.什么是Mybatis框架

​ Mybatis 是apache的一个开源项目IBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为Mybatis.2013年11月迁移到Github

​ IBATIS一词来源于"Internet "和"abatis"的组合,是一个基于Java的持久层框架.

​ iBATIS提供的持久层框架包括SQL MAPs 和Data Access Objects(DAOs)。

Mybatis是一个半自动化的ORM框架

那什么又是ORM呢?

ORM : Object Relational Mapping (作用解决数据库发展和面向对象发展不一致的问题)

O : 面向对象

R : 关系型数据库 >> MySql ,Oracal

M : 映射

半自动化 : mybatis框架是需要我们自己动手写sql语句

Mybatis框架不依赖于服务器的,所以它有以下的优点。

优点:

A. 连接数据库速度快

B. 实现了SQL语句和JAVA代码之间的解耦

C. 数据库的查询取值非常方便

二. 环境搭建


了解了MyBatis框架,那就来试试如何去使用它吧!

步骤:

  1. 创建一个Maven项目

  2. 书写配置SqlConfig.xml文件

  3. 配置UserDao.xml文件

  4. 书写测试代码

     * 1.加载主配置文件
     * 2.创建SqlSessionFactory工厂
     * 3.使用SessionFactory工厂生产SqlSession对象
     * 4.执行方法
     * 5.释放资源 
    

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>org.example</groupId>
    <artifactId>mybatis_demo3</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>

        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

    </dependencies>

</project>

SqlConfig.xml配置文件: 配置Mybatis的环境

<?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>
  <!--    配置环境-->
    <environments default="development">
        <!--  配置mysql环境-->
        <environment id="development">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"/>
            <!--  配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--    配置连接数据库的4个基本信息-->
                < 标签内配置连接数据库的信息 >
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_db"/>
                <property name="username" value="root"/>
                <property name="password" value="123"/>
            </dataSource>
        </environment>
    </environments>    
   
    <!--  指定映射文件的位置
          进行mapper文件的扫描 >> resource:书写的是xml文件所在的目录
    -->
    <mappers>
        <mapper resource="cn/dao/UserDao.xml"></mapper>
    </mappers>
</configuration>

UserDao.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="cn.lmx.UserDao">
    <!--  eg:select
          List<User>  findAll();
          id : 方法名称
          resultType : 返回值类型
                查询返回的时候不是对象就是集合. 如果返回值是一个对选哪个,就写对象所在包的全路径 ; 如果返回值是一个集合,就写集合的泛型

    -->

    <!--查询所有信息-->
    <select id="findAll" resultType="cn.pojo.User">
        select * from user
    </select>
</mapper>    

测试代码:

package test;

import cn.dao.UserDao;
import cn.pojo.QueryUser;
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.After;
import org.junit.Before;
import org.junit.Test;
import cn.pojo.User;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * 1.加载主配置文件
 * 2.创建SqlSessionFactory工厂
 * 3.使用SessionFactory工厂生产SqlSession对象
 * 4.执行方法
 * 5.释放资源
 */
public class UserTest {
 
    /**
     * 查询所有信息
     * @throws IOException
     */
    @Test
    public void testUser() throws IOException {

         //1.加载/读取配置文件
        InputStream is = Resources.getResourceAsStream("SqlConfig.xml");
        //2.创建工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        //3.使用工厂生产对象
        SqlSession session = factory.openSession();
        //4.执行方法
        List<User> userList = dao.findAll();

        //遍历
        for (User user:userList
             ) {
            System.out.println(user);
        }
         //提交事务
        session.commit();
        //5.释放资源
        session.close();
        is.close();
    }
}

**注:**更多配置信息,参考mybatis官网

三. Mybatis框架环境搭建详解

1. jar包目录介绍

ant : 可以用ant编译java类,生成class文件,ant可以把相关层架构成包
asm : java文件解析包 .spring依赖这个包
cglib : 动态代理包,使得mybatis不需要编写实现类<将接口与xml关联起来了>
comments-logging : 日志包,.spring依赖这个包
javassist : 字节码解析助手,处理class文件
log4j : 也是日志包
mybatis : 是mybatis的核心
mysql-connector : 是mysql的驱动
ognl : ognl表达式
slf4j : 日志包
... ...

2. 配置详情

2.1 全局配置文件

<configuration>
  <!--    配置环境-->
    <environments default="development">
        <!--  配置mysql环境-->
        <environment id="development">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"/>
            <!--  配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--    配置连接数据库的4个基本信息-->
                < 标签内配置连接数据库的信息 >
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_db"/>
                <property name="username" value="root"/>
                <property name="password" value="123"/>
            </dataSource>
        </environment>
    </environments>  

---- environments default=“development”:
default 配置当前所使用的的环境,值必须是的id值

​ 可以有多个标签,声明可能使用的黄精,会被引用

---- transactionManager type=“JDBC”: 事务管理器类型

​ type属性可取值:

  1. JDBC 底层事务与JDBC原有事务管理相同

  2. MANAGED Mybatis不去管理事务,交给其他容器进行管理

---- dataSource type=“POOLED” :

POOLED : 使用连接池技术,访问频率比较高时使用.连接池的使用可以降低服务器的压力,提高连接对象重用性.

​ UNPOOLED : 不使用连接池技术.每次对数据库访问时打开数据库连接,访问结束后关闭数据库连接.

​ JNDI : java命名目录接口.数据库的连接可以依赖于其他技术活应用.

---- mapper:

​ resource = “cn/dao/UserDao.xml” 加载项目中的资源,目录寻找,中间是/

​ class=“cn.lmx.dao.UserDao”

​ url = “file:///E:/UserDao.xml” 加载互联网或读取本机的配置文件 >> file协议

---- package :

​ 首先会找到包下的所有的[接口],然后去找和接口的名字相同的xml进行扫描<若没有接口,则无法扫描>

2.2 引入本地dtd

http://mybatis.org/dtd/mybatis-3-config.dtd 加载慢,是因为网慢,因为每次都需要联网请求dtd【如果自身网路比较顺畅可以不考虑】

解决方法 : 引入本地DTD文件

步骤:
1.下载对应的DTD : 直接复制链接在网络下载即可
2.打开setting>>Languages&Frameworks>>Schemas and DTDs
3.引入本地DTD文件

四. Mybatis框架搭建优化

1.配置别名

给指定的实体类起别名:

<!--使用typeAliases配置别名, 它只能配置pojo中类的别名
        type: 实体类的全限定类名
        alias: 指定别名,当指定别名之后可以忽略大小
     -->
    <typeAliases>
        <typeAlias type="cn.pojo.User" alias="User"></typeAlias>
    </typeAliases>

包下得所有类起别名明 : 别名就是当前类的名称 首字母小写(忽略大小写)

eg: 在cn.pojo 下得实体类User的别名就是user

 <!--name : 包名 -->
<typeAliases>
	<package name="cn.pojo"></package>
 </typeAliases>

2. 引入properties配置文件

1.Mybatis也是支持属性文件的读取的
2.可以让代码的结构更加清晰

注意:configuration报错 >> 可能是标签书写顺序不对,这里报错不会影响编译结果的

在这里插入图片描述

jdbc.properties文件

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql:///mybatis_db
    username=root
    password=123
 <!-- 配置properties  配置数据库的连接信息
         可以在标签内配置连接数据库的信息,也可以通过属性引入外部信息配置文件信息
            resource属性:
                指定配置文件的位置,必须写在类路径下
        resource 用来引入外部的配置文件
     -->
    <!--1.标签内配置连接数据库的信息-->
    <!--<properties>
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306:/mybatis_db"/>
        <property name="username" value="root"/>
        <property name="password" value="123"/>
    </properties>-->
    <!--2.通过属性引入外部信息配置文件信息-->
    <properties resource="jdbc.properties" ></properties>

3. 配置settings开启log4j支持

3.1 日志文件的作用

  • 记录错误的信息到文件中
  • 有日志级别方便查看

3.2 log4j的五种级别

  1. FATAL 严重错误
  2. ERROR 错误
  3. WARN 警告
  4. INFO 普通信息
  5. DEBUG 调试信息

注:只会显示当前级别及以上的信息

3.3 开启log4j支持

先导入log4j文件,在进行相关配置

   <!--配置参数-->
    <settings>
        <!--控制台输出SQL-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

五. Mybatis的三种查询方式

位置:在创建dao接口的代理对象处

查询方式1 : sqlSession.selectList()

sqlSession.selectList() : 适合于结果集返回的是多条数据的时候 >> 返回一个结果集

eg:sqlSession.selectList(“cn.dao.UserDao.finAll”)

 public void init() throws IOException {
        //1.加载/读取配置文件
        is = Resources.getResourceAsStream("SqlConfig.xml");
        //2.创建工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        //3.使用工厂生产对象
        sqlSession = factory.openSession();
       
     
        //4.执行方法  >> 这里的UserDao 是xml文件
        List<User> userList = sqlSession.selectList("cn.dao.UserDao.finAll");  

        //遍历
        for (User user:userList
             ) {
            System.out.println(user);
        }
      	//提交事务
        session.commit();
        //5.释放资源
        session.close();
        is.close();
     

查询方式2 : sqlSession.selectOne


sqlSession.selectOne : 适用于最多返回是一条结果集数据 >> 返回一个对象

查询方式3 : sqlSession.selectMap()

**sqlSession.selectMap() : 返回一个Map集合 **

​ **作用:**希望可以通过数据库中的某一列快速的找到这一列对应的结果集 >> eg : map.get(3)

eg:sqlSession.selectMap(“cn.dao.UserDao.findAll”,“id”)

​ >>(“xml文件全类名.调用的方法” ,“列名(希望数据库的哪一列作用的key)”)

注 : 在map.get()时,不要强转

六. 参数传递操作

参数传递1 : 单个参数

用 #{param1}接收参数 >> select * from user where id=#{param1}

参数传递2 : 传入对象

用#{id},#{name}…来接收参数 >> select * from user where id=#{id} and name=#{name}

参数传递3 : Map集合

用#{a},#{b}…来接收参数 >> select * from user where id=#{a} and name=#{b} (注:a,b为map集合的键)

*除了用#还可以使用$,但是建议用# :

# : 底层是使用占位符 ? 
$ : 底层使用的是字符串的拼接  >> 在传的参数为字符串时,要用单引号将字符串引起来

七. mybatis中基于sqlSession的CRUD

pojo实体类:User

package cn.pojo;
/**
 * 实体类
 */

import java.util.Date;

public class User {
    private int id;//编号
    private String name;//姓名
    private String address;//地址
    private String sex;//性别
    private Date birthday;//生日



    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 getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

UserDao.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="cn.dao.UserDao"> //namespace可以为任意值,只有使用Mapper代理时,才会有特定写法(接口全类名)
    <!-- 查询所有用户信息-->
    <!-- id的名称就是sqlSession调用的方法名-->
    <select id="findAll" resultType="cn.pojo.User">
        select * from user1
    </select>

    <!--增加用户信息-->
    <insert id="addUser"  parameterType="cn.pojo.User">
        insert into user1 values (#{user.id},#{user.name},#{user.address},#{user.sex},#{user.birthday})
    </insert>

    <!--删除用户信息-->
    <delete id="delUser" parameterType="cn.pojo.User">
        delete from user1 where id=#{user.id}
    </delete>

    <!--修改用户信息-->
    <update id="updateUser" parameterType="cn.pojo.User">
        update user1 set name=#{user.name} , address=#{user.address} , sex=#{user.sex} where id=#{user.id}
    </update>
</mapper>

UserTest

package test;

import cn.dao.UserDao;
import cn.pojo.QueryUser;
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.After;
import org.junit.Before;
import org.junit.Test;
import cn.pojo.User;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

public class UserTest {
    private InputStream is;
    private SqlSession session;
    private UserDao dao;

    @Before
    public void init() throws IOException {
        //1.加载/读取配置文件
        is = Resources.getResourceAsStream("SqlConfig.xml");
        //2.创建工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        //3.使用工厂生产对象
        session = factory.openSession();
    }

    @After
    public void close() throws IOException {
        //提交事务  >> 只有提交了事务,数据才会保存到硬盘中
        /*  增删改操作写好后必须提交事务
        	提交事务方式 :
        			1.commit()手动提交
        			2.openSession(true)自动提交
        */
        session.commit();
        //6.释放资源
        session.close();
        is.close();
    }


    /**
     * 查询所有信息
     * @throws IOException
     */
    @Test
    public void testUser() throws IOException {

        //5.使用代理对象dao执行方法
        List<User> userList = session.selectOne("cn.dao.UserDao.findAll");

        //遍历
        for (User user:userList
             ) {
            System.out.println(user);
        }
    }

    /**
     * 模糊查询
     */
    @Test
    public void unclearFindTest(){
        List<User> users =session.selectOne("cn.dao.UserDao.   ** ");
    }


    /**
     * 增加用户信息
     */
    @Test
    public void addUserTest() throws IOException {
        QueryUser queryUser = new QueryUser();
            User user = new User();
            user.setName("三藏");
            user.setAddress("东土大唐");
            user.setSex("男");
            user.setBirthday(new Date());
            int i = session.insert("cn.dao.UserDao.addUser",user);
    }

    /**
     * 删除用户信息
     */
    @Test
    public void delUserTest(){
        User user = new User();
        user.setId(101);
		int i = session.delete("cn.dao.UserDao.delUser",user);
    }

    /**
     * 修改用户信息
     */
    @Test
    public void updateUserTest(){
        User user = new User();
        user.setId(2);
        user.setName("憨憨");
        user.setAddress("西天");
        user.setSex("男");
		int i = session.update("cn.dao.UserDao.updateUser",user);
    }
}

注 : 参数类型可以省略,它会根据接收的类型自动判断.

八. Mybatis中基于Mapper代理方式的CRUD

1.Mapper 的动态代理作用

目前使用SQLSession进行CRUD的缺点:
	1.没有办法实现多参数的传递
	2.书写的时候没有借口,后期的维护就比较的低
解决方案: Mapper动态代理方式,实现CURD

2.示意图

3. 代码演示

SqlConfig.xml

<!--  指定映射文件的位置,进行扫描-->
    <mappers>
        <mapper resource="cn/dao/UserDao.xml"></mapper>
    </mappers>

UserDao.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="cn.dao.UserDao">
    <!--id : id的名称和接口的名称必须保持一致-->
    <!-- 查询所有用户信息-->
    <select id="findAll" resultType="cn.pojo.User">
        select * from user1
    </select>
</mapper>

UserDao 接口:

import cn.pojo.User;

import java.util.List;

public interface UserDao {
    /**
     * 查询数据库所有信息
     */

    List<User> findAll();
}

UserTest:

    /**
     * 查询所有信息
     * @throws IOException
     */
    @Test
    public void testUser() throws IOException {
        //1.加载/读取配置文件
        InputStream is = Resources.getResourceAsStream("SqlConfig.xml");
        //2.创建工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        //3.使用工厂生产对象
        SqlSession session = factory.openSession();
        //4.创建dao接口的代理对象
        UserDao dao = session.getMapper(UserDao.class);

        //5.使用代理对象dao执行方法
        List<User> userList = dao.findAll();

        //遍历
        for (User user:userList
             ) {
            System.out.println(user);
        }
          //提交事务
        session.commit();
        //6.释放资源
        session.close();
        is.close();
    }

4. 好处

1 .可以面向接口进行开发

2.可以传多个参数了

public void testUser() throws IOException {
    //1.加载/读取配置文件
    InputStream is = Resources.getResourceAsStream("SqlConfig.xml");
    //2.创建工厂
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(is);
    //3.使用工厂生产对象
    SqlSession session = factory.openSession();
    //4.创建dao接口的代理对象
    UserDao dao = session.getMapper(UserDao.class);

    //5.使用代理对象dao执行方法
    List<User> userList = dao.findAll();

    //遍历
    for (User user:userList
         ) {
        System.out.println(user);
    }
      //提交事务
    session.commit();
    //6.释放资源
    session.close();
    is.close();
}

4.好处

  1. 可以面向接口进行开发
  2. 可以传多个参数了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值