MyBatis详解(一)框架简述与实现

MyBatis框架

第一章 框架简述

1.三层架构

​ mvc:web开发中,使用mvc架构模式。m:数据,v:视图,c:控制器

​ c 控制器:接受请求,调用service对象,显示请求的处理结果。当前使用servlet作为控制器

​ v 试图: 现在使用jsp,html,css,js。显示请求的处理结果,把m中数据显示出来。

​ m 数据: 来自数据库mysql,来自文件,来自网络。

​ mvc作用:

​ 1).实现解耦合

​ 2).让mvc各负其职

​ 3)使系统扩展更好。更容易维护。

​ 三层架构

​ 1.界面层(视图层):接受用户请求,调用service,显示请求的处理结果的。包含了jsp,html,servlet等对象。

​ 2.业务逻辑层:处理业务逻辑,使用算法处理数据的。把数据返回给界面层。对应的是service包,和包中的很多的

XXXService类。例如:StudentService,OderService,ShopService.

​ 3.持久层(数据库访问层):访问数据库,或者读取文件,访问网络。获取数据。对应的包是dao。dao包中很多的StudentDao,OderDao,ShopDao等等.

2.三层架构请求的处理流程

​ 用户发起请求 -> 界面层 ->业务逻辑层 ->持久层->数据库(mysql)

3.为什么要使用三层架构

1.结构清晰、耦合度低、各层分工明确。

2.可维护性高,可拓展性高。

3.有利于标准化。

4.开发人员可以只关注整个结构中的其中某一层的功能实现。

5.有利于各层逻辑的复用。

4.三层架构模式和框架

每一层对应着一个框架

​ 1.界面层----SpringMVC框架

​ 2.业务层—Spring框架

​ 3.持久层—MyBatis框架

5.框架

1).什么是框架(framework)

​ 框架就是一个软件,完成了部分的功能。软件中的类和类之间的方法调用都已经规定好了。通过这些可以完成某些功能。框架看做是模板。

​ 框架是可以升级的,改造的。框架是安全的。

​ 框架是对某一个方面有用的,不是全能的。

6.框架解决的问题

1)框架能实现技术的整合。

2)提高开发的效率。降低难度。

7.JDBC访问数据库的优缺点

优点:

​ 1.直观,好理解。

缺点:

​ 1.创建很多对象 Connection,Statement,ResultSet

​ 2.注册驱动

​ 3.执行sql语句

​ 4.把ResultSet转为Student,List集合。

​ 5.关闭资源

​ 6.sql语句和业务逻辑代码混在一起。

8.MyBatis框架

​ 什么是mybatis:是一个持久层框架,原名ibatis,2013年改名MyBatis,MyBatis可以操作数据库,对数据库执行增删改查。看做是高级的jdbc。解决jdbc的缺点。

​ MyBatis可以做什么?

1)注册驱动

2)创建jdbc中使用的Connection,Statement,ResultSet

3)执行sql语句,得到ResultSet

4)处理ResultSet,把记录集中的数据转为Java对象,同时还能把Java对象放入到List集合。

5)关闭资源。

6)实现sql语句和java代码的解耦合。

MyBatis官网:https://mybatis.org/mybatis-3/zh/index.html

第二章 MyBatis入门

​ 这一部分首先不完全借助框架来实现查询2.1-2.4

​ 最后最大化的利用框架简化操作2.5

2.1第一个例子

实现步骤:

​ 1.创建student表(id,name,email,age)

​ 2.新建maven项目

​ 3.修改pom.xml

​ 1)加入MyBatis依赖,mysql驱动,junit

​ 2)在<*build>加入资源插件

​ 4.创建实体类Student,定义属性,属性名和列名保持一致。

​ 5.创建Dao接口,定义操作数据库的方法。

​ 6.创建xml文件(mapper文件),写sql语句。

​ mybatis框架推荐把sql语句和java代码分开。

​ mapper文件:定义和dao接口在同一目录,一个表一个mapper文件。

​ 7.创建mybatis的主配置文件(xml文件):有一个,放在resources目录下

​ 1)定义创建连接实例的数据源(DataSource)对象

​ 2)指定其他mapper文件的位置。

​ 8.创建测试的内容。

​ 使用main方法,测试mybatis访问数据库

​ 也可以使用junit访问数据库。

只问耕耘,不问收获

具体实现

3.Maven的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.bjpowernode</groupId>
  <artifactId>ch01-first</artifactId>
  <version>1.0</version>



  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <!--依赖列表-->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--mybatis依赖 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
    <!-- mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.9</version>
    </dependency>
  </dependencies>

  <build>
    <!--资源插件: 处理src/main/java目录中的xml-->
    <resources>
      <resource>
        <directory>src/main/java</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>

    <!-- 指定jdk的版本,我们已经指定过来,所以现在就不需要-->
<!--    <plugins>-->
<!--      <plugin>-->
<!--        <artifactId>maven-compiler-plugin</artifactId>-->
<!--        <version>3.1</version>-->
<!--        <configuration>-->
<!--          <source>1.8</source>-->
<!--          <target>1.8</target>-->
<!--        </configuration>-->
<!--      </plugin>-->
<!--    </plugins>-->


  </build>
</project>

​ 5.创建Dao接口,定义操作数据库的方法。

Java下的domain层写Student类,dao层写StudentDao接口。同一目录下写StudentDao.xml

package com.sunny.dao;

import com.sunny.domain.Student;

public interface StudentDao {

    //查询一个学生
    Student selectStudentById(Integer id);
}

​ 6.创建xml文件(mapper文件),写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.sunny.dao.StudentDao">
<!--    <select id="selectBlog" resultType="Blog">
        select * from Blog where id = #{id}
    </select>-->
<!--    查询一个学生Student
        <select>:表示查询操作,里面是select语句
        id:要执行的sql语句的唯一标识,是一个自定义字符串。
            推荐使用dao接口中的方法名称
        resultType:告诉mybatis,执行sql语句,把数据赋值给哪个类型的java对象。
            resultType的值现在使用的java对象的全限定名称

		        #{studentId}:占位符,表示从java程序中传入过来的数据。
-->
    <select id="selectStudentById" resultType="com.bjpowernode.domain.Student">
        select id,name,email,age from student where id= #{studentId}
    </select>
<!--    添加insert
        insert into student values (1003,"李峰","lifeng@qq,com",26)
        如果传入给mybatis是一个java对象,使用#{属性名}获取此属性值。
        属性值放到#{}占位符的位置,mybatis执行此属性对应的getXXX().
        例如#{id},执行getId()
-->
    <insert id="insertStudent">
        insert into student values (#{id},#{name },#{email},#{age})
    </insert>
</mapper>

<!--
    1.约束文件
        http://mybatis.org/dtd/mybatis-3-mapper.dtd
        约束文件的作用:定义和限制当前文件中可以使用的标签和属性,以及标签出现的顺序
    2.mapper是根标签
      namespace: 命名空间,必须有值,不能为空。唯一值。
                  推荐使用Dao接口的全限定名称。
      作用:   参与识别sql语句的作用。
    3.在mapper里面可以写<insert>,<update>,<delete>,<select>等标签。
    <insert> 里面是 insert语句,表示执行的insert操作。
    <update> 里面是 update语句
    <delete> 里面是 delete语句
    <select> 里面是 select语句

-->

7.创建mybatis的主配置文件(xml文件):有一个,放在resources目录下

?useUnicode=true&characterEncoding=utf-8

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
<!--         配置数据源:创建Connection对象-->
            <dataSource type="POOLED">
<!--             driver:驱动的内容-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
<!--                连接数据库的url-->
                <property name="url" value="jdbc:mysql://localhost:3306/springdb?useUnicode=true&amp;
                characterEncoding=utf-8"/>
<!--                用户名-->
                <property name="username" value="root"/>
<!--                密码-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
<!--    指定其他mapper文件的位置:
        其他mapper文件目的 是找到其他文件的sql语句。
-->
    <mappers>
<!--        
        使用mapper的resource属性指定mapper文件的路径。
        这个路径是从target/classes路径开启的。
        
        使用注意:
            resource = mapper文件的路径,使用/分割路径
            一个mapper resource 指定一个mapper文件
-->
        <mapper resource="com/bjpowernode/dao/StudentDao.xml"/>
<!--        <mapper resource="com/bjpowernode/dao/OrderDao.xml"/>-->
<!--        <mapper resource="com/bjpowernode/dao/UserDao.xml"/>-->
    </mappers>
</configuration>

在test文件下测试代码

package com.sunny;

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 org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class MyTest {

    //测试mybatis执行sql语句
    @Test
    public void testSelectStudentById() throws IOException {
//         调用mybatis某个对象的方法,执行mapper文件中的sql语句。

//         mybatis核心类: SqlSessionFactory

//        1.定义mybatis主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";

//        2.读取主配置文件。使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);

//        3.创建SqlSessionFactory对象,使用SqlSessionFactoryBuilder类
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//        4.获取SqlSession对象
        SqlSession session = factory.openSession();
//        5.指定要执行的sql语句的id
//        sql的id = namespace+“.”+<select>|update|insert|delete标签的id属性值。
        String sqlId="com.bjpowernode.dao.StudentDao"+"."+"selectStudentById";

//        6.通过SqlSession的方法,执行sql语句。
        Student student = session.selectOne(sqlId);
        System.out.println("使用mybatis查询一个学生"+student);

//        7.关闭SqlSession对象
        session.close();
    }
    
    @Test
    public void testSelectStudentById2() throws IOException {
//         调用mybatis某个对象的方法,执行mapper文件中的sql语句。

//         mybatis核心类: SqlSessionFactory

//        1.定义mybatis主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";

//        2.读取主配置文件。使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);

//        3.创建SqlSessionFactory对象,使用SqlSessionFactoryBuilder类
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//        4.获取SqlSession对象
        SqlSession session = factory.openSession();
//        5.指定要执行的sql语句的id
//        sql的id = namespace+“.”+<select>|update|insert|delete标签的id属性值。
        String sqlId="com.bjpowernode.dao.StudentDao"+"."+"selectStudentById";

//        6.通过SqlSession的方法,执行sql语句。
        Student student = session.selectOne(sqlId,1002);
        System.out.println("使用mybatis查询一个学生"+student);

//        7.关闭SqlSession对象
        session.close();
    }

    @Test
    public void testInsertStudent() throws IOException {

        String config = "mybatis.xml";
        InputStream inputStream = Resources.getResourceAsStream(config);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = factory.openSession();

        String sqlId="com.bjpowernode.dao.StudentDao"+"."+"insertStudent";

//        6.通过SqlSession的方法,执行sql语句。
        Student student = new Student();
        student.setId(1005);
        student.setName("张飞");
        student.setEmail("zhangfei@qq.com");
        student.setAge(26);

        int rows = session.insert(sqlId,student);
        System.out.println("使用mybatis添加一个学生,rows="+rows);

//        mybatis默认执行sql语句是 手工提交事务模式,在做insert,update,delete后需要提交事务。
        session.commit();
//        7.关闭SqlSession对象
        session.close();
    }

    @Test
    public void testAutoCommitInsertStudent() throws IOException {

        String config = "mybatis.xml";
        InputStream inputStream = Resources.getResourceAsStream(config);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = factory.openSession(true);

        String sqlId="com.bjpowernode.dao.StudentDao"+"."+"insertStudent";

//        6.通过SqlSession的方法,执行sql语句。
        Student student = new Student();
        student.setId(1007);
        student.setName("小乔");
        student.setEmail("zhangfei@qq.com");
        student.setAge(26);

        int rows = session.insert(sqlId,student);
        System.out.println("使用mybatis添加一个学生,rows="+rows);


//        7.关闭SqlSession对象
        session.close();
    }    
}

使用mybatis查询一个学生Student实体的信息{id=1001, name='李四', email='sunny@qq.com', age=21}

Process finished with exit code 0

2.2概念

​ 1.自动提交:当你的sql语句执行完毕后,提交事务。数据库更新操作直接保存到数据库。

​ 在mybatis.xml文件中加入

<configuration>
<!--    设置日志-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

​ 可选的值有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING

​ 这是控制台的一次打印过程

Opening JDBC Connection
Created connection 161960012.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@9a7504c]
//把自动提交功能关闭了;
//再执行sql语句
==>  Preparing: select id,name,email,age from student where id= ? 
    //占位符会变成一个问号  参数值
    //参数值
==> Parameters: 1002(Integer)
    //列
<==    Columns: id, name, email, age
    //列对应的行值
<==        Row: 1002, 张三, zhangs@qq.com, 22
    //本次查询出一行记录。
<==      Total: 1
    //我自己的代码输出
使用mybatis查询一个学生Student实体的信息{id=1002, name='张三', email='zhangs@qq.com', age=22}
	//重新将自动提交设置为真,关闭连接,把连接放到连接池中。
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@9a7504c]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@9a7504c]
Returned connection 161960012 to pool.

Process finished with exit code 0

​ 2.手动提交事务:在你需要提交事务的位置,执行方法,提交事务或者回顾事务。

容易出现的问题

​ idea有时候没用将xml拷贝到target中。

解决方法:

​ 1.Build一下

​ 2.maven - clean - compile

​ 3.重启idea File-> Invalidate Cacher/Restart

​ 4.手工把文件拷贝过去。

2.3 MyBatis的一些重要对象

1)Resources:mybatis框架中的对象,一个作用读取主配置信息。

InputStream inputStream = Resources.getResourceAsStream(config);

2)SqlSessionFactoryBuilder:负责创建SqlSessionFactory对象

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

3)SqlSessionFactory:重要对象

SqlSessionFactory是重量级对象:创建此对象需要使用更多的资源和时间。重量级对象在项目中有一个就可以了。

SqlSessionFactory接口:作用SqlSession的工厂,就是创建SqlSession对象。

DefaultSqlSessionFactory实现类

public class DefaultSqlSessionFactory implements SqlSessionFactory{}

SqlSessionFactory接口中的方法

openSession():获取一个默认的SqlSession对象,默认是需要手工提交事务的。

openSession(boolean):boolean表示是否自动提交事务。

​ true:创建一个自动提交事务的SqlSession

​ false:等同于没有参数的openSession。

4)SqlSession对象

SqlSession对象是通过SqlSessionFactory获取的。SqlSession本身是接口。

DefaultSqlSession:实现类

public class DefaultSqlSession implements SqlSession {}

SqlSession作用是提供了大量的执行sql语句的方法:

selectOne:执行sql语句,最多得到一行记录,多于1行是错误的。
selectList:执行sql语句,返回多行数据。
selectMap:执行sql语句的,得到一个Map结果。
insert:执行insert语句。
update:执行update语句。
delete:执行delete语句。
commit:提交事务。
rollback:回滚事务。

注意:SqlSession对象不是线程安全的,使用的步骤:

①:在方法的内部,执行sql语句之前,先获取SqlSession对象

②:调用SqlSession的方法,执行sql语句。

③:关闭SqlSession对象,执行SqlSession.close()

2.4 idea工具类和模板功能

1.创建模板

File->Settings->Editer ->File and Templates ->File->+添加自定义模板

接口配置文件模板内容 mybatis-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">
<mapper namespace="dao接口的全限定名称">
    <!-- 使用insert,update,delete,select标签写sql语句-->	

</mapper>

主配置文件模板

<?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>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--         配置数据源:创建Connection对象-->
            <dataSource type="POOLED">
                <!--             driver:驱动的内容-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--                连接数据库的url-->
                <property name="url" value="jdbc:mysql://localhost:3306/springdb?useUnicode=true&amp;
                characterEncoding=utf-8"/>
                <!--                用户名-->
                <property name="username" value="root"/>
                <!--                密码-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>

        <mapper resource="自己的接口xml文件"/>

    </mappers>
</configuration>

2.工具类

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;


/*
* 工具类:创建sqlSession对象
* */
public class MyBatisUtil {
    private static SqlSessionFactory factory = null;
    /*
    * 静态代码块可以让当前这个类在虚拟机加载的时候,把SqlSessionFactory创建一次就行了。
    * */
    static{
        String config ="mybatis.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(config);
            factory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//    创建方法,获取SqlSession对象
    public static SqlSession getSqlSession(){
        SqlSession session = null;
        if(factory!=null){
            session = factory.openSession();//openSession(true);
        }
        return session;
    }
}

测试类


public class MyTest {
    @Test
    public void testSelectById(){
//        1.获取SqlSession
        SqlSession session= MyBatisUtil.getSqlSession();
//        2.指定sqlId
        String sqlId = "com.bjpowernode.dao.StudentDao.selectById";
//        3.执行SqlSession的方法,表示执行Sql语句
        Student student = session.selectOne(sqlId,1001);
        System.out.println("查询结果==="+student);
//        4.关闭SqlSession对象
        session.close();
    }
    @Test
    public void testSelectStudents(){
//        1.获取SqlSession
        SqlSession session= MyBatisUtil.getSqlSession();
//        2.指定sqlId
        String sqlId = "com.bjpowernode.dao.StudentDao.selectStudents";
//        3.执行SqlSession的方法,表示执行Sql语句
        List<Student> students = session.selectList(sqlId);
        for(Student stu:students){
            System.out.println("student====="+stu);
        }
//        4.关闭SqlSession对象
        session.close();
    }

    @Test
    public void testInsetStudent(){
//        1.获取SqlSession
        SqlSession session= MyBatisUtil.getSqlSession();
//        2.指定sqlId
        String sqlId = "com.bjpowernode.dao.StudentDao.insertStudent";
//        3.执行SqlSession的方法,表示执行Sql语句
        Student student = new Student();
        student.setId(1008);
        student.setName("东皇");
        student.setEmail("donghuang@qq.com");
        student.setAge(30);

        int rows = session.insert(sqlId,student);
        session.commit();
        System.out.println("insert的行数===="+rows);
//        4.关闭SqlSession对象
        session.close();
    }
}

3.dao执行sql

​ 用一个类实现接口

import com.bjpowernode.dao.StudentDao;
import com.bjpowernode.domain.Student;
import com.bjpowernode.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class StudentDaoImpl implements StudentDao {
//    ctrl+o

    public StudentDaoImpl() {
        super();
    }

    @Override
    public Student selectById(Integer id) {
        SqlSession session = MyBatisUtil.getSqlSession();
        String sqlId = "com.bjpowernode.dao.StudentDao.selectById";
        Student student = session.selectOne(sqlId,1001);
        session.close();
        return student;
    }

    @Override
    public List<Student> selectStudents() {
//        1.获取SqlSession
        SqlSession session= MyBatisUtil.getSqlSession();
//        2.指定sqlId
        String sqlId = "com.bjpowernode.dao.StudentDao.selectStudents";
//        3.执行SqlSession的方法,表示执行Sql语句
        List<Student> students = session.selectList(sqlId);

//        4.关闭SqlSession对象
        session.close();
        return students;
    }

    @Override
    public int insertStudent(Student student) {
//        1.获取SqlSession
        SqlSession session= MyBatisUtil.getSqlSession();
//        2.指定sqlId
        String sqlId = "com.bjpowernode.dao.StudentDao.insertStudent";
//        3.执行SqlSession的方法,表示执行Sql语句
        int rows = session.insert(sqlId,student);
        session.commit();
        System.out.println("insert的行数===="+rows);
//        4.关闭SqlSession对象
        session.close();
        return rows;
    }
}

测试方法



public class MyTest2 {
    /*
    *SqlSession session= MyBatisUtil.getSqlSession();
    String sqlId = "com.bjpowernode.dao.StudentDao.selectById";
    *
    *
    * 测试方法中:调用dao的方法
    * Student student = dao.selectById(1001);
    * 1)dao:通过反射能得到 全限定类型名称
    *   dao是Student类型的,全限定com.bjpowernode.dao.StudentDao
    * 2)selectById:dao中的方法名称, 方法名称就是mapper文件中标签的id
    *   通过dao.selectById()得到 sqlId="com.bjpowernode.dao.StudentDao.selectById";
    *
    * 3)确定调用SqlSession的哪个方法
    *   1.根据dao接口的方法返回中,如果返回是一个对象,例如Student,调用SqlSession.selectOne();
    *       如果dao接口的方法返回List,调用SqlSession的 selectList();
    *
    *   2.根据mapper文件中的标签,如果标签是<insert>,调用SqlSession.insert()方法
    *
    * mybatis框架,发现使用dao的方法调用能确定 执行sql语句的必要信息,mybatis简化dao对象的实现。
    * 由mybatis框架在程序执行期间,根据你的Dao接口,创建一个内存中的接口的实现类的对象。
    * mybatis把这个技术叫做代理技术(动态代理,dao的动态代理)。
    *
    * dao代理技术:由mybatis创建StudentDao接口的实现类Proxy(StudentDaoImpl),使用框架创建的StudentDaoImpl代替
    * 你自己手工实现的StudentDaoImpl类的功能,不能开发人员写dao接口的实现类。
    *
    * 使用dao的代理要求
    *   1.mapper文件中的namespace:必须是dao接口的全限定名称
    *   2.mapper文件中标签的id是dao接口中的方法名称(一摸一样的)
    * */

    @Test
    public void testSelectOne(){
//        要使用dao的方法
//        接口类型  变量 = new 接口的实现类();
        StudentDao dao = new StudentDaoImpl();

        Student student = dao.selectById(1001);
        System.out.println("通过dao执行方法,得到的对象==="+student);

    }
    @Test
    public void testSelectStudents(){
        StudentDao dao=new StudentDaoImpl();
        List<Student> students = dao.selectStudents();
        students.forEach(stu-> System.out.println("stu="+stu));
    }

    @Test
    public void testInsert(){
        StudentDao dao = new StudentDaoImpl();
        Student student = new Student();
        student.setId(1009);
        student.setName("周瑜");
        student.setEmail("zhouqiang@qq.com");
        student.setAge(28);
        dao.insertStudent(student);
    }
}

2.5 dao代理

1.mybatis提供代理:

mybatis创建Dao接口的实现类对象,完成对sql语句的执行。mybatis创建一个对象代替你的dao实现类功能。

2.使用mybatis代理的要求:

​ 1)mapper文件中的namespace一定dao接口的全限定名称。

​ 2)mapper文件中标签的id是dao接口方法名称。

3.mybatis代理的实现方式

​ 使用SqlSession对象的方法getMapper(dao.class)

​ 例如:现在有StudentDao接口。

SqlSession session = MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = dao.selectById(1001);

//上面代码中
StudentDao dao = session.getMapper(StudentDao.class);
//等同于
StudentDao dao = new StudentDaoImpl();
public class MyTest {

    @Test
    public void testSelectById(){
//        1.获取SqlSession
        SqlSession session= MyBatisUtil.getSqlSession();
//        2.获取dao的代理
        StudentDao dao = session.getMapper(StudentDao.class);
        Student student = dao.selectById(1005);
        System.out.println("student = "+ student);
//        3.关闭SqlSession对象
        session.close();
    }

    @Test
    public void testSelectStudents(){
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        System.out.println("dao==="+dao.getClass());
//        dao===class com.sun.proxy.$Proxy2 代理类型。代替了实现类的功能。
        List<Student> students = dao.selectStudents();
        students.forEach(stu-> System.out.println("stu="+stu));
        session.close();
    }

}
public class MyTest {

    @Test
    public void testSelectById(){
//        1.获取SqlSession
        SqlSession session= MyBatisUtil.getSqlSession();
//        2.获取dao的代理
        StudentDao dao = session.getMapper(StudentDao.class);
        Student student = dao.selectById(1005);
        System.out.println("student = "+ student);
//        3.关闭SqlSession对象
        session.close();
    }

    @Test
    public void testSelectStudents(){
        SqlSession session = MyBatisUtil.getSqlSession();
        StudentDao dao = session.getMapper(StudentDao.class);
        System.out.println("dao==="+dao.getClass());
//        dao===class com.sun.proxy.$Proxy2 代理类型。代替了实现类的功能。
        List<Student> students = dao.selectStudents();
        students.forEach(stu-> System.out.println("stu="+stu));
        session.close();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值