MyBatis框架入门(一)

本文介绍了MyBatis框架的基础知识,包括三层架构、框架概念。详细讲述了JDBC的缺陷,如代码繁琐、资源管理麻烦,然后引出MyBatis框架的优势,如简化数据库操作,提供sql映射和Data Access Objects。通过一个入门案例,展示了如何创建实体类、配置文件、使用SqlSession接口进行数据库交互,强调了SqlSessionFactoryBuilder和SqlSession的重要角色。最后,对比了传统DAO与MyBatis动态代理的使用方式。
摘要由CSDN通过智能技术生成

目录

1.框架概述

1.1 三层架构

1.2 框架

2.Mybatis框架概述

2.1 JDBC的缺陷

2.2 Mybatis框架概述

3.Mybatis的入门案例

4.Mybatis中主要类的介绍

4.1 Resources类

4.2 SqlSessionFactoryBuilder类

4.3 SqlSessionFactory接口

4.4 SqlSession接口

5.关于入门案例的修改

5.1 传统dao的使用方式

5.2 使用Mybatis的动态代理


1.框架概述

1.1 三层架构

   三层架构包括界面层、业务逻辑层、数据访问层。

        ①界面层(表示层,视图层):主要功能是接受用户的数据,显示请求的处理结果。(jsp、

          html、servlet)

        ②业务逻辑层:接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取

          数据。

        ③数据访问层(持久层):与数据库打交道。主要实现对数据的增、删、改、查,将存储在数据

          库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。

   三层对应的包

        ①界面层:controller包(XXXServlet类)

        ②业务逻辑层:service包(XXXService类)

        ③数据访问层:dao包(XXXDao类)

   三层中类的交互

        用户使用界面层--->业务逻辑层--->数据访问层--->数据库

   三层对应的处理框架

        界面层---servlet类---springmvc框架

        业务逻辑层---service类---spring框架

        数据访问层---dao类---mybatis框架

1.2 框架

   框架是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例件交互的方法,也可以将框架看成是可被应用开发者定制的应用骨架、模板。简单地说,框架其实是半成品软件,就是一组组件,供你使用来完成你自己的系统。框架是安全的、可复用的、不断升级的软件。

   框架中定义好了一些基础功能,可以在项目中加入自己的功能,而自己加入的功能也可以利用框架中写好的功能。

   框架特点

        ①框架一般不是全能的,不能做所有事情;

        ②框架是针对某一领域有效,特长在某一方面,比如mybatis做数据库操作强,但不擅长做其

          他的;

        ③框架是一个软件

2.Mybatis框架概述

2.1 JDBC的缺陷

   ①代码比较多,开发效率低;

   ②需要关注Connection、Statement、ResultSet对象的创建和销毁;

   ③对ResultSet查询的结果,需要自己封装为List;

   ④重复的代码比较多;

   ⑤业务代码和数据库的操作混在一起。

2.2 Mybatis框架概述

   mybatis框架,早期叫做ibatis,其源代码在github上。

   mybatis是MyBatis SQL Mapper Framework for Java(sql映射框架),包括:

        ①sql maper:sql映射。可以吧数据库表中的一行数据映射为一个java对象,即一行数据可以

          看作是一个java对象,操作这个对象,就相当于操作表中的数据。

        ②Data Access Objects(Daos):数据访问,对数据库执行增删改查。

   mybatis提供的功能

        ①提供了创建Connection、Statement、ResultSet的能力,不需要开发人员创建这些对象。

        ②提供了执行sql语句的能力,不用开发人员执行sql语句。

        ③提供了循环sql,把sql的结果转为java对象、List集合的能力。

                在JDBC中只能:

                        while (rs.next()) {
                                Student stu = new Student();
                                stu.setId(rs.getInt("id"));
                                stu.setName(rs.getString("name"));
                                stu.setAge(rs.getInt("age"));
                                //从数据库取出数据转为 Student 对象,封装到 List 集合
                                stuList.add(stu);
                         }

        ④提供了关闭资源的能力,不用自己手动关闭Connection、Statement、ResultSet。

   流程:开发人员提供sql语句---mybatis处理执行sql语句---开发人员得到List集合或Java对象(表中的数据)

   总结:mybatis是一个sql映射框架,提法对数据库的操作能力,相当于增强的JDBC。使用mybatis可以让开发人员集中精力写sql语句就可以了,不用关心Connection、Statement、ResultSet的创建、销毁以及sql语句的执行。

3.Mybatis的入门案例

   1.创建mysql数据库和表。数据库名springdb;表名student。

   2.新建一个maven项目,骨架选择maven-archetype-quickstart即可。在pom.xml文件中加入mybatis、mysql驱动的依赖。

<!--mybatis依赖-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.1</version>
</dependency>
<!--sql驱动依赖-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.9</version>
</dependency>

   3.创建实体类,Student类,用来保存表中的一行数据。实体类的包名叫domain或者entity

package com.bjpowernode.domain;
//推荐和表名一样,容易记忆
public class Student {
    //定义属性,目前要求是属性名和列名一样。
    private Integer id;
    private String name;
    private String email;
    private Integer age;

    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 String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

   4.创建数据访问层的dao接口,定义操作数据库的方法。包名叫做dao

package com.bjpowernode.dao;

import com.bjpowernode.domain.Student;
import java.util.List;
//接口操作Student表
public interface StudentDao {

    //查询Student表的所有数据
    public List<Student> selectStudents();

    //插入方法
    //参数:student,表示要插入到数据库的数据
    //返回值:int    表示执行insert操作后的影响数据库的行数(成功添加了几行数据 )
    public int insertStudent(Student student);
}

   5.创建一个mybatis使用的配置文件,叫做sql映射文件,用来写sql语句的。一般一个表一个sql映射文件,这个文件是xml文件。该文件写在dao接口所在的目录中(dao文件夹),文件名称和dao接口名称保持一致。StudentDao.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.bjpowernode.dao.StudentDao">
    <select id="selectStudents" resultType="com.bjpowernode.domain.Student">
       select id,name,email,age from student order by id
    </select>

    <!--
        select:表示查询操作。
        id:你要执行的sql语法的唯一标识,mybatis会使用这个id的值来找到要执行的sql语句
            可以自定义,但是要求你使用接口中的方法名称。

        resultType:表示结果类型的,是sql语句执行后得到ResultSet,遍历这个ResultSet得到java对象的类型。
                    值写的类型的全限定名称

    -->
    <select id="insertStudent">
        insert into student values (#{id},#{name},#{email},#{age})
    </select>
</mapper>
<!--
     sql映射文件(sql mapper):写sql语句的,mybatis会执行这些sql
     1.指定约束文件
          <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

       mybatis-3-mapper.dtd是约束文件的名称,扩展名是dtd的。

     2.约束文件的作用:限制,检查在当前文件中出现的标签、属性必须符合mybatis的要求

     3.mapper:是当前文件的根标签,必须的。
       namespace:叫做命名空间,唯一值的,可以是自定义的字符串。
                  要求使用dao接口的全限定名称

     4.在当前文件中可以使用特定的标签,表示数据库的特定操作。
        <select>:表示执行查询,select语句
        <update>:表示更新数据库的操作,就是在<update>标签中写的是update语句
        <insert>:表示插入,放的是insert语句
        <delete>:表示删除,执行的是delete语句
-->

   6.创建mybatis的主配置文件一个项目就一个主配置文件,主配置文件提供了数据库的连接信息和sql映射文件的位置信息。写在resources文件夹中。mybatis.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>
    <!--settings:控制mybatis全局行为-->
    <settings>
        <!--设置mybatis输出日志-->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>
    <!--
         环境配置:数据库的连接信息
         default:必须和某个environment的id值一样。
                  告诉mybatis使用哪个数据库的连接信息,也就是访问哪个数据库。
    -->
    <environments default="mydev">
        <!--
            environment:一个数据库信息的配置,环境
            id:一个唯一值,自定义,表示环境的名称。
        -->
        <environment id="mydev">
            <!--
                 transactionManager:mybatis的事务类型
                 type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理)
            -->
            <transactionManager type="JDBC"/>
            <!--
                 dataSource:表示数据源,连接数据库的
                 type:表示数据源的类型,POOLED表示使用连接池
            -->
            <dataSource type="POOLED">
                <!--
                    driver,url,username,password是固定的,不能自定义。
                -->
                <!--数据库的驱动类名-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--连接数据库的url字符串-->
                <property name="url" value="jdbc:mysql://localhost:3306/springdb"/>
                <!--访问数据库的用户名-->
                <property name="username" value="root"/>
                <!--密码-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

        <!--表示线上的库,是项目真实使用的库-->
        <environment id="online">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--sql mapper(sql映射文件)的位置-->
    <mappers>
        <!--
            一个mapper标签指定一个文件的位置。
            从类路径开始的路径信息。 target/classes(类路径)
        -->
        <mapper resource="com/bjpowernode/dao/StudentDao.xml"/>
        <!--<mapper resource="com/bjpowernode/dao/SchoolDao.xml"/>-->
    </mappers>
</configuration>

<!--
     mybatis的主配置文件:主要定义了数据库的配置信息,sql映射文件的位置

     1.约束文件
        <!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

       mybatis-3-config.dtd:约束文件的名称

     2.configuration 根标签
-->

   7.创建使用mybatis类,通过mybatis访问数据库。

package com.bjpowernode;

import com.bjpowernode.domain.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 MyApp {
    public static void main(String[] args) throws IOException {
        //访问mybatis,读取student数据
        //1.定义mybatis主配置文件的名称,从类路径的跟开始(target/classess)
        String config = "mybatis.xml";
        //2.读取这个config表示的文件
        InputStream in  = Resources.getResourceAsStream(config);
        //3.创建了SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //4.创建SqlSessionFactory对象
        SqlSessionFactory factory = builder.build(in);
        //5.[重要]获取SqlSession对象,从SqlSessionFactory中获取SqlSession
        SqlSession sqlSession = factory.openSession();
        //6.[重要]指定要执行的sql语句的标识。  sql映射文件中的namespace + "." + 标签的id值
        String sqiId = "com.bjpowernode.dao.StudentDao" + "." + "selectStudents";
        //7.执行sql语句,通过sqlId找到语句
        List<Student> studentList = sqlSession.selectList(sqiId);
        //8.输出结果
        //studentList.forEach( stu -> System.out.println(stu));
        for (Student stu:studentList){
            System.out.println(stu);
        }
        //9.关闭SqlSession对象
        sqlSession.close();
    }
}
public class TestMybatis {
    //测试方法,测试功能
    @Test
    public void testInsert() throws IOException {
        //访问mybatis,读取student数据
        //1.定义mybatis主配置文件的名称,从类路径的跟开始(target/classess)
        String config = "mybatis.xml";
        //2.读取这个config表示的文件
        InputStream in  = Resources.getResourceAsStream(config);
        //3.创建了SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //4.创建SqlSessionFactory对象
        SqlSessionFactory factory = builder.build(in);
        //5.[重要]获取SqlSession对象,从SqlSessionFactory中获取SqlSession
        //SqlSession sqlSession = factory.openSession();
        SqlSession sqlSession = factory.openSession(true);//自动提交事务
        //6.[重要]指定要执行的sql语句的标识。  sql映射文件中的namespace + "." + 标签的id值
        String sqiId = "com.bjpowernode.dao.StudentDao" + "." + "insertStudent";
        //7.执行sql语句,通过sqlId找到语句
        Student student = new Student();
        student.setId(1005);
        student.setName("关羽");
        student.setEmail("guanyu@163.com");
        student.setAge(20);
        int num = sqlSession.insert(sqiId,student);
        //mybatis默认不是自动提交事务的,所以在insert,update,delete后要手工提交事务
        //sqlSession.commit();
        //8.输出结果
        System.out.println("执行insert结果:" + num);
        //9.关闭SqlSession对象
        sqlSession.close();
    }
}

   8.创建一个工具类来实现前半部分重复的代码。

package com.bjpowernode.utils;

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;

public class MyBatisUtils {

    private static SqlSessionFactory factory = null;

    static {
        String config = "mybatis.xml";
        try {
            InputStream in = Resources.getResourceAsStream(config);
            //创建SqlSessionFactory对象,使用SqlSessionFactoryBuilder
            factory = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取SqlSession的方法
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = null;
        if(factory != null){
            sqlSession = factory.openSession();//非自动提交事务
        }
        return sqlSession;
    }
}

   9.利用工具类来实现查询功能。

public class MyApp2 {
    public static void main(String[] args) throws IOException {
        //[重要]获取SqlSession对象,从SqlSessionFactory中获取SqlSession
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //[重要]指定要执行的sql语句的标识。  sql映射文件中的namespace + "." + 标签的id值
        String sqiId = "com.bjpowernode.dao.StudentDao" + "." + "selectStudents";
        //执行sql语句,通过sqlId找到语句
        List<Student> studentList = sqlSession.selectList(sqiId);
        //输出结果
        //studentList.forEach( stu -> System.out.println(stu));
        for (Student stu:studentList){
            System.out.println(stu);
        }
        //9.关闭SqlSession对象
        sqlSession.close();
    }
}

   在该例子中并没有使用到dao接口,这个接口不是必须的,但是在我们之后的开发中都是利用这个接口中的方法来访问数据库,进行增删改查操作。 

4.Mybatis中主要类的介绍

4.1 Resources类

   Resources是mybatis中的一个类,负责读取主配置文件

        InputStream in = Resources.getResourceAsStream("mybatis.xml");

4.2 SqlSessionFactoryBuilder类

   负责创建SqlSessionFactory对象

        SqlSessionFactoryBuilder builder  = new SqlSessionFactoryBuilder();

        //创建SqlSessionFactory对象

        SqlSessionFactory factory = builder.build(in);

4.3 SqlSessionFactory接口

   重量级对象,程序创建一个该对象耗时比较长,使用资源比较多。在整个项目中,这个对象有一个就够了,因此可以利用工具类中的静态代码块来创建。

   SqlSessionFactory:接口。接口实现类:DefaultSqlSessionFactory。

   SqlSessionFactory作用: 获取SqlSession对象

        SqlSession sqlSession = factory.openSession();

   关于openSession()方法说明:

        1. openSession() :无参数的,获取是非自动提交事务的SqlSession对象

        2. openSession(boolean):

                openSession(true)  获取自动提交事务的SqlSession. 

                openSession(false)  非自动提交事务的SqlSession对象

4.4 SqlSession接口

   定义了操作数据的方法,例如selectOne()   selectList()   insert()   update()   delete()   commit()   rollback()。

   SqlSession接口的实现类DefaultSqlSession。

   使用要求: SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,使用openSession()获取SqlSession对象。在执行完sql语句后,需要关闭它,执行SqlSession.close()。这样能保证他的使用是线程安全的。

5.关于入门案例的修改

5.1 传统dao的使用方式

   1.dao接口:

package com.bjpowernode.dao;

import com.bjpowernode.domain.Student;

import java.util.List;

public interface StudentDao {
    List<Student> selectStudents();
    int insertStudent(Student student);
}

   2.dao接口的实现类:

package com.bjpowernode.dao.impl;

import com.bjpowernode.dao.StudentDao;
import com.bjpowernode.domain.Student;
import com.bjpowernode.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class StudentDaoImpl implements StudentDao {
    @Override
    public List<Student> selectStudents() {
        //获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        String sqlid = "com.bjpowernode.dao.StudentDao.selectStudents";
        //执行sql语句,使用SqlSession类的方法
        List<Student> students = sqlSession.selectList(sqlid);
        sqlSession.close();
        return students;
    }

    @Override
    public int insertStudent(Student student) {
        //获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        String sqlid = "com.bjpowernode.dao.StudentDao.insertStudent";
        //执行sql语句,使用SqlSession类的方法
        int nums = sqlSession.insert(sqlid,student);
        //提交事务
        sqlSession.commit();
        sqlSession.close();
        return nums;
    }
}

   3.测试方法:

public class TestMyBatis {
    @Test
    public void testSelectStudents(){
        //com.bjpowernode.dao.StudentDao
        StudentDao dao = new StudentDaoImpl();
        /*
             List<Student> students = dao.selectStudents(); 调用
             1.dao对象,类型是StudentDao,全限定名称是: com.bjpowernode.dao.StudentDao
               全限定名称和namespace是一样的。

             2.方法名称,selectStudents,这个方法名称就是mapper文件中的id值
               
               1和2获得的字符串拼接后就是之前我们需要使用的sqlid

             3.通过dao中方法的返回值类型也可以确定MyBatis要调用的SqlSession的方法
                  如果返回值类型是List,调用的是SqlSession.selectList() select方法
                  如果返回值类型是int,或者是非List的,看mapper文件中的标签是<insert>,<update>就会调用
                  SqlSession的insert,update等方法
             
             这样就发现通过一个方法调用可以获得以上信息,因此可以利用反射机制。

             mybatis的动态代理:mybatis根据dao的方法调用,获取执行sql语句的信息。
                               mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的对象。
                               完成SqlSession调用方法,访问数据库。
                               所以不需要自己手写dao的实现类。mybatis会利用动态代理自动实现。
         */
        List<Student> students = dao.selectStudents();
        for(Student student : students){
            System.out.println(student);
        }
    }

    @Test
    public void testInsertStudent(){
        StudentDao dao = new StudentDaoImpl();
        Student student = new Student();
        student.setId(1006);
        student.setName("盾山");
        student.setEmail("dunshan@163.com");
        student.setAge(22);
        int nums = dao.insertStudent(student);
        System.out.println("添加对象的数量:" + nums);
    }
}

5.2 使用Mybatis的动态代理

   1.dao接口:

public interface StudentDao {
    List<Student> selectStudents();
    int insertStudent(Student student);
}

   2.利用动态代理的测试方法:

        SqlSession的对象有一个方法getMapper()

public class TestMyBatis {
    @Test
    public void testSelectStudents(){
        /**
         * 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口)
         * getMapper能获取dao接口对应的实现类对象。
         */
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);//利用反射机制
        //dao=com.sun.proxy.$Proxy2:JDK的动态代理
        System.out.println("dao=" + dao.getClass().getName());
        //调用dao的方法,执行数据库的操作
        List<Student> students = dao.selectStudents();
        for (Student student : students){
            System.out.println(student);
        }
        sqlSession.close();
    }

    @Test
    public void testInsertStudent(){
        Student student = new Student();
        student.setId(1007);
        student.setName("李飞");
        student.setEmail("lifei@163.com");
        student.setAge(22);
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        int nums = dao.insertStudent(student);
        sqlSession.commit();
        System.out.println("添加对象的数量:" + nums);
        sqlSession.close();
    }
}

   注意:dao接口不要使用重载方法,即不要使用同名的、不同参数的方法。

PS:根据动力节点课程整理,如有侵权,联系删除。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值