dao(Data Access Object) 数据访问对象
Mybatis-9.28
环境
jdk1.8
Mysql5.7
maven3.6.1
IDEA
回顾
JDBC
Mysql
java基础
Maven
junit
框架 配置文件的,最好的方式,看官网文档
https:///mybatis.org/mybatis-3/index.html
简介
什么是mybatis 持久层框架
MyBatis 它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
Mybatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,
2013年11月迁移到Github
如何获得Mybatis
maven仓库


org.mybatis
mybatis
3.4.6

github网站
https://github.com/mybatis/mybatis-3/releases 下载地址
持久化
数据持久化
持久化就是将程序的数据在持久状态和瞬时状态转化的过程
内存:断电即失
数据库(jdbc) io文件持久化
生活 冷藏 罐头
为什么需要持久化
有一些对象不能让他们丢掉
内存太贵了
持久层
Dao层 Service层 Controller层
完成持久化工作的代码块
层是界限十分明显的
为什么需要Mybatis
帮助程序员将数据存入到数据库中
方便
传统的jdbc代码太复杂 简化 框架 自动化
不用mybatis也可以,更容易上手技术没有高低之分
优点
简单易学 灵活 sql和代码分离 提高了可维护性
提供映射标签支持对象与数据库的orm字段关系映射
提供对象关系映射标签支持对象关系组件维护
提供xml标签,支持编写动态sql
最重要的一点,使用的人多
Spring SpringMVC SpringBoot
第一个Mybatis程序
思路 搭建环境—>导入Mybatis—》编写代码—》测试
搭建环境
搭建数据库
新建项目

  1. <dependencies>
  2. <!--mysql驱动-->
  3. <dependency>
  4. <groupId>mysql</groupId>
  5. <artifactId>mysql-connector-java</artifactId>
  6. <version>5.1.47</version>
  7. </dependency>
  8. <!--mybatis驱动-->
  9. <dependency>
  10. <groupId>org.mybatis</groupId>
  11. <artifactId>mybatis</artifactId>
  12. <version>3.5.2</version>
  13. </dependency>
  14. <!--junit驱动-->
  15. <dependency>
  16. <groupId>junit</groupId>
  17. <artifactId>junit</artifactId>
  18. <version>4.12</version>
  19. </dependency>
  20. </dependencies>

创建一个模块
编写核心配置文件

<?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>
      <typeAliases>
        <!--     
            设置这个包下面的所有类的别名
            <package name="cn.itsource.domain"/> 
        -->

        <!--  
            设置单个类的别名       alias:取的别名    type:这个别名所对应的Java类    别名使用的时候与大小写无关
        -->
        <typeAlias alias="ST" type="com.kuang.dao.StudentTeacher"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>
编写mybits工具类 util
package com.kuang.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;

//sqlSessionFactory --> sqlSession
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }

}
实体类
package com.kuang.pojo;

public class User {
    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    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 getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}
Dao接口
package com.kuang.dao;

import com.kuang.pojo.User;

import java.util.List;
import java.util.Map;

public interface UserDao {
     List<User> getUserLike(String value);
     //查询全部用户
     List<User> getUserList();
     //根据ID查询用户
     User getUserById(int id);
     User getUserById2(Map map);
     //insert一个用户
     int addUser(User user);
     //修改用户
     int updateUser(User user);
     //删除用户
     int deleteUser(int id);
}
接口实现类由原来的UseDaoImpl转变为一个Mapper配置文件
<?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绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.kuang.dao.UserDao">
    <select id="getUserList" resultType="com.kuang.pojo.User">
        SELECT * FROM mybatis.user
    </select>
    <select id="getUserById" parameterType="int" resultType="com.kuang.pojo.User">
        SELECT * FROM mybatis.user WHERE id=#{id}
    </select>
    <select id="getUserById2" parameterType="Map" resultType="com.kuang.pojo.User">
        SELECT * FROM mybatis.user WHERE id = #{helloid} AND name=#{helloname}
    </select>
    <select id="getUserLike" resultType="com.kuang.pojo.User">
        SELECT * FROM mybatis.user WHERE name LIKE #{value}
    </select>
    <!--对象中的属性可以直接取出来-->
    <insert id="addUser" parameterType="com.kuang.pojo.User" >
        INSERT INTO mybatis.user(id, name, pwd) VALUE (#{id},#{name},#{pwd});
    </insert>
    <update id="updateUser" parameterType="com.kuang.pojo.User" >
        update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
    </update>
    <delete id="deleteUser" parameterType="int" >
        DELETE FROM mybatis.user WHERE id=#{id};
    </delete>
</mapper>

测试代码

package com.kuang.dao;

import com.kuang.pojo.User;
import com.kuang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserDaoTest {
    @Test
    public void test(){
        //第一步获得sqlSession对象
        SqlSession sqlSession= MybatisUtils.getSqlSession();
        try{
            //方式一:getMapper
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            List<User> userList = userDao.getUserList();
            for(User user:userList){
                System.out.println(user);
            }
        } finally {
            //关闭SqlSession
            sqlSession.close();
        }

    }
    @Test
    public void getUserById(){
        SqlSession sqlSession= MybatisUtils.getSqlSession();
        UserDao mapper =sqlSession.getMapper(UserDao.class);
        User user = mapper.getUserById(2);
        System.out.println(user);
        sqlSession.close();
    }
    @Test
    public void getUserById2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("helloid",1);
        map.put("helloname","fengchao");
        User user =mapper.getUserById2(map);
        System.out.println(user);
        sqlSession.close();
    }
    @Test
    public void getUserLike(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> listuser =mapper.getUserLike("李_");
        for(User user: listuser){
            System.out.println(user);
        }
    }
    //增删改需要提交事务
    @Test
    public void addUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper =sqlSession.getMapper(UserDao.class);
       int res= mapper.addUser(new User(4,"李五","156789"));
       if(res>0){
           System.out.println("successful");
       }
       //提交事务
        sqlSession.commit();
        sqlSession.close();
    }
    @Test
    public void updateUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        mapper.updateUser(new User(1,"fengchao","123789"));
        sqlSession.commit();
        sqlSession.close();
    }
    @Test
    public void deleteUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        mapper.deleteUser(4);
        sqlSession.commit();
        sqlSession.close();
    }
}
可能遇到的问题<br />增删改查(CRUD)<br />    namespace 它中的包名要和Dao/mapper接口的包名一致<br />    select<br />    选择,查询语句<br />    id 就是对应的namespace中的方法名<br />    resultType Sql语句执行的返回值<br />    parameterType 参数类型<br />    增删改需要提交事务<br />    多个参数用map或者注解<br />    模糊查询<br />配置解析<br />核心配置文件<br />mybatis-config.xml<br />    MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息<br />    configuration(配置)<br />    properties(属性)<br />    settings(设置)<br />    typeAliases(类型别名)<br />    typeHandlers(类型处理器)<br />    objectFactory(对象工厂)<br />    plugins(插件)<br />    environments(环境配置)<br />        environment(环境变量)<br />            transactionManager(事务管理器)<br />            dataSource(数据源)<br />    databaseIdProvider(数据库厂商标识)<br />    mappers(映射器)<br />环境配置<br />    mybatis可以配置成适应多种环境<br />    不过每个SqlSessionFactory实例只能选择一种环境<br />    学会使用配置多种运行环境<br />    mybatis默认的事务管理器就是jdbc,连接池:pooled<br />属性(properties)<br />    可以使用通过属性来实现引用配置文件<br />    可以直接引入外部文件<br />    可以在其中增加一些属性配置<br />    如果两个文件有同一个字段,优先使用外部配置文件的<br />类型别名(typeAliases)<br />    类型别名是为java类型设置一个短的名字<br />    存在的意义仅在于用来减少类完全限定名的冗余<br />  <typeAliases><br />            <typeAlias type="com.kuang.pojo.User" alias="User"/><br />     </typeAliases><br />    也可以指定一个包名,MyBatis会在包名下面搜索需要的java Bean,比如<br />    扫描实体类的包,他的默认别名就为这个类的类名,首字母小写<br />  <typeAliases><br />            <package name="com.kuang.pojo"/><br />     </typeAliases><br />    在实体类比较少的时候,使用第一种方式<br />    如果实体类十分多,建议使用第二种<br />    第一种可以自定义别名第二种则不行不过可以用注解<br />    @Alias("user")<br />    public class user{}<br />设置<br />    这是MyBatis中极为重要的调整设置,它们会改变MyBatis的运行时行为<br />其他配置<br />    typeHandlers(类型处理器)<br />    objecFactory(对象工厂)<br />    plugins插件<br />  mybatis-generator-core<br />  mybatis-plus<br />  通用mapper<br />映射器<br />    MapperRegistry:注册绑定我们的Mapper文件<br />    方式一 推荐使用<br />    每一个Mapper.xml文件都需要在Mybatis核心配置文件中注册<br />    <mappers><br />            <mapper resource="com/kuang/dao/UserMapper.xml"/><br />    </mappers><br />    方式二 使用class文件绑定注册<br />    <mappers><br />            <mapper class="com.kuang.dao.UserMapper"/><br />        </mappers><br />    注意点<br />    接口和他的Mapper配置文件必须同名<br />    接口和他的Mapper配置文件必须在同一个包下<br />    方式三 使用扫描包进行注入绑定<br />    <mappers><br />            <package name="com.kuang.dao"/><br />        </mappers><br />生命周期和作用域<br />    生命周期和作用域是至关重要的,因为错误的使用会导致非常严重并发问题<br />    SqlSessionFactoryBuilder<br />    一旦创建了SqlSessionFactory 就不需要它了<br />    局部变量<br />    SqlSessionFactory<br />    说白了就是可以想象为:数据库连接池<br />    SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或者重新创建另一个实例<br />    因此SqlSessionFactory的最佳作用域是应用作用域<br />    最简单的就是使用单例模式或者静态单例模式<br />    SqlSession<br />    连接到连接池的一个请求<br />    SqlSession的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域<br />    用完之后需要赶紧关闭否则资源被占用<br />    这里面的每一个Mapper,就代表一个具体的业务<br />    解决属性名和字段名不一致的问题<br />    数据库中的字段<br />    新建一个项目,拷贝之前的,测试实体类字段不一致的情况<br />    重新定义密码名字,再次查询会发现为空<br />    解决方法<br />    起别名 select id,name,pwd as password from user<br />    resultMap<br />    结果集映射<br />    id name pwd<br />    id name password<br />    <resultMap id="UserMap" type="User"><br />            <result column="id" property="id"/><br />            <result column="name" property="name"/><br />            <result column="pwd" property="password"/><br />        </resultMap><br />    resultMap元素是MyBatis中最重要最强大的元素<br />    ResultMap的设计思想是,对于简单的语句根本不需要配置显示的结果集映射,而对于复杂一点的语句只需要描述他们的关系就好了<br />    ResultMap最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显示地用到他们<br />    日志<br />    日志工厂<br />    如果一个数据库操作出现了异常,我们需要排错,日志就是最好的助手<br />    曾经:sout debug<br />    现在:日志工厂  <br />        SLF4J |<br />  LOG4J | 掌握<br />  LOG4J2 |<br />  JDK_LOGGING |<br />  COMMONS_LOGGING |<br />    STDOUT_LOGGING | 掌握<br />  NO_LOGGING  <br />    在Mybatis中具体使用哪个日志<br />    <settings><br />        <setting name="logImpl" value="STDOUT_LOGGING"/><br />    </settings><br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/5373548/1607484486257-71762c88-cc7a-4d83-aee5-e3c5fbfc084f.png#align=left&display=inline&height=211&margin=%5Bobject%20Object%5D&name=image.png&originHeight=422&originWidth=957&size=46183&status=done&style=none&width=478.5)<br />    什么是Log4j<br />    它是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台,文件,GUI组件<br />    我们可以控制每一条日志的输出格式<br />    通过定义每一条日志信息的级别,我们能够能加细致地控制日志的生成过程<br />    通过一个配置文件来灵活地进行配置,而不需要修改应用的代码<br />    先导入log4j的包
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

建一个文件
去网上搜索log4j配置文件就有

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

配置log4j为日志的实现

    <settings>
        <!--标准的日志工厂实现 -->
        <!--<setting name="logImpl" value="STDOUT_LOGGING"/>-->
        <setting name="logImpl" value="LOG4J"/>
    </settings>

Log4j的使用
直接测试运行
简单使用
在要使用log4j的类中导入包 import org.apache.log4j.Logger;
日志对象,参数为当前类的class

    static Logger logger =Logger.getLogger(UserDaoTest.class);

日志级别

        logger.info("info:进入了testLog4j");
        logger.debug("debug:进入了testLog4j");
        logger.error("error:进入了testLog4j");

分页
为什么要分页
减少数据的处理量
使用Limit分页

语法 SELECT* FROM user LIMIT startIndex.pageSize;
SELECT * FROM user LIMIT 2; 只写一个就是从0开始每页几个

使用Mybatis 实现分页,核心SQL
接口

     List<User> getUserByLimit(Map map);

UserMapper.xml语句

    <select id="getUserByLimit" parameterType="Map" resultType="com.kuang.pojo.User">
        SELECT * FROM mybatis.user limit #{startindex},#{pagesize}
    </select>

测试类

    @Test
    public void getUserByLimit(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Map<String,Integer> map = new HashMap<>();
        map.put("startindex",2);
        map.put("pagesize",3);
        List<User> userlist = mapper.getUserByLimit(map);
        for(User user:userlist) {
            System.out.println(user);
        }
        sqlSession.close();
    }

注解开发
不用mapper直接在接口里面写

public interface UserDao {
    @Select("select * from user")
    public List<User> getUserList();
    @Select("select * from user where id = #{id}")
    public User findById(@Param("id") int id,@Param("name") String name);
    public void deleteById();
    public User updateById();
    public void add(User user);
}

{} 和 ${}的区别
主要就是防止sql注入
Lombok的使用
安装插件
几个注解的含义
@Data @AllArgsConstructor @NoArgsConstructor @EqualsAnHashCode @TOString @Getter
连表查询
环境
创建学生教师表

CREATE TABLE teacher(
id INT NOT NULL,
NAME VARCHAR(20) NOT NULL
)ENGINE = INNODB
CREATE TABLE student(
id INT NOT NULL,
NAME VARCHAR(20) NOT NULL,
tid INT NOT NULL 
)ENGINE = INNODB

插入信息
我用客户端插入的这样子省事儿
把之前的环境搞过来
util 实体类 接口 测试类 还有mybatis核心配置文件基本就没什么了
连表查询需要这样写

<?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.kuang.mapper.StuTeaMapper">
    <select id="find" resultMap="ResoutMap" >
        SELECT * from student
    </select>
    <resultMap id="ResoutMap" type="com.kuang.pojo.Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--复杂的属性,我们需要单独处理 对象 association 集合 collection
javaType 指定属性的类型-->
        <association property="teacher" column="tid" javaType="com.kuang.pojo.Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getTeacher" resultType="com.kuang.pojo.Teacher">
        SELECT * from teacher where id = #{tid}
    </select>
</mapper>

一对多

<?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.kuang.mapper.StuTeaMapper">
    <select id="find2" resultMap="ResoutMap" >
        SELECT s.id sid,s.name sname,t.name tname,t.id tid
          from student s,teacher t
          where s.tid = t.id and t.id = #{tid}
    </select>
    <resultMap id="ResoutMap" type="com.kuang.pojo.Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="Student">
                  <result property="id" column="sid"/>
                  <result property="name" column="sname"/>
                  <result property="tid" column="tid"/>
          </collection>
    </resultMap>
  <!--第二种-->
  <select id="getTeacher2" resultMap="ResoutMap">
    select * from mybatis.teacher where id=#{tid}
  </select>
  <resultMap id="ResoutMap" type="Teacher">
    <collection property="students"javaType="ArrayList" ofType="Student"/>
  </resultMap>
  <select id="getStudentByTeacherId" resultType="Student">
    select * from mybatis.student where tid=#{tid}
  </select>
</mapper>

关联 association 多对一
集合 collection 一对多
javaType & ofType
jacaType 用来指定实体类中属性的类型
ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型
注意
保证sql的可读性,尽量保证通俗易懂
注意一对多和多对一中属性名和字段的问题
如果问题不好排查错误,可以使用日志,建议使用Log4j
缓存
什么是缓存【cache】
存在内存中的临时数据
将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型 数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能 问题
为什么使用缓存
减少和数据库的交互次数,减少系统开销,提高系统效率
什么样的数据能使用缓存
经常查询并且不经常改变的数据
Mybatis缓存
MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率
MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存
默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
二级缓存需要手动开启和配置,它是基于namespace级别的缓存
为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存。
一级缓存
一级缓存也叫本地缓存:
与数据库同一次会话期间查询到的数据会放在本地缓存中
以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库
二级缓存
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存。
spring与mybatis的整合
resources下的spring-dao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!-- xmlns 是xml的命名空间
    要引入新的 context命名空间
-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
 https://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd">

    <!--
       读取 jdbc.properties 中的内容
            property-placeholder: 占位符
            location: 属性文件的位置
    -->
    <!--<context:property-placeholder location="classpath:jdbc.properties"/>-->

    <!-- 1) 获得数据库连接池对象,并交由 spring 同一管理 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <!-- 连接数据库的驱动,连接字符串,用户名和登录密码-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>

        <!-- 数据池中最大连接数和最小连接数-->
        <!--<property name="maxActive" value="${max}"/>-->
        <!--<property name="minIdle" value="${min}"/>-->
    </bean>

    <!-- 2) 获取 SqlSessionFactory 对象,并交由 spring 管理-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入连接池
         给 sqlsessionFactory 的属性 dataSource 赋值
            ref="引用该 spring容器 中的另一个 bean的id"
        -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 注入 映射文件 mapper
         给 sqlsessionFactory 的属性 mapperLocation 赋值
           value="映射文件 XXXmapper.xml 的相对路径"
          -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/kuang/mapper/*.xml"/>

    </bean>

    <!-- 3) 获取 SqlSession 对象,并交由 spring 管理  用SqlSessionTemplate得到的SqlSession可以不用我们自己操心事务的管理,以及关闭操作-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 给 SqlSessionTemplate 的构造函数赋值-->
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>

</beans>

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">
<configuration>
        <typeAliases>
            <package name="com.kuang.pojo"/>
        </typeAliases>
</configuration>

resources下的applicationContext.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!-- xmlns 是xml的命名空间
    要引入新的 context命名空间
-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
 https://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd">
    <import resource="spring-dao.xml"/>
    <!---->
    <bean id="STMapperImpl" class="com.kuang.mapper.STMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
    </bean>
    <bean id="STMapperImpl2" class="com.kuang.mapper.STMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
</beans>

实体类
接口

package com.kuang.dao;

import com.kuang.pojo.Student;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface StudentTeacher {
    //@Select("Select * from student")
    List<Student> find();
}

mapper

<?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.kuang.dao.StudentTeacher">
    <select id="find" resultType="com.kuang.pojo.Student" >
        SELECT * from student
    </select>
</mapper>

实现类有两种

package com.kuang.mapper;

import com.kuang.dao.StudentTeacher;
import com.kuang.pojo.Student;
import org.mybatis.spring.SqlSessionTemplate;

import java.util.List;

public class STMapperImpl implements StudentTeacher{
    private SqlSessionTemplate sqlSession;
    public void setSqlSession(SqlSessionTemplate sqlSession){this.sqlSession=sqlSession;}
    public List<Student> find(){
        StudentTeacher studentTeacher = sqlSession.getMapper(StudentTeacher.class);
        return studentTeacher.find();
    }
}
package com.kuang.mapper;

import com.kuang.dao.StudentTeacher;
import com.kuang.pojo.Student;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class STMapperImpl2 extends SqlSessionDaoSupport implements StudentTeacher {
    public List<Student> find(){

        return getSqlSession().getMapper(StudentTeacher.class).find();
    }
}

最后测试类

package com.kuang.dao;

import com.kuang.mapper.STMapperImpl2;
import com.kuang.pojo.Student;
import javafx.application.Application;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StuTeaTest {
    @Test
    public void find(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        StudentTeacher studentTeacher = context.getBean("STMapperImpl",StudentTeacher.class);
        for(Student student:studentTeacher.find()){
            System.out.println(student);
        }
    }
    @Test
    public void find2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
       StudentTeacher studentTeacher = context.getBean("STMapperImpl2",StudentTeacher.class);
       for(Student s:studentTeacher.find()){
           System.out.println(s);
       }
    }
}