MyBatis(SqlSession)

Posted 364.99°

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis(SqlSession)相关的知识,希望对你有一定的参考价值。

1.简介

1.1 Mybatis

mybatis: 一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,可以使用简单的XML或注解来配置和映射原生信息。

MyBatis对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

简而言之:一个半自动ORM框架,本质是对JDBC的封装。使用MyBatis重点需要程序员编写SQL命令,不需要写一行JDBC代码

ORM(Object Relational Mapping):在关系型数据库和对象之间作一个映射。使程序能够通过操纵描述对象方式来操纵数据库。
持久层(Persistence Layer):实现数据持久化应用领域的一个逻辑层面,将数据使用者和数据实体相关联。
持久化:把数据(如内存中的对象)保存的磁盘的某一文件中。

JDBC的缺点:

Java代码和SQL语句之间的耦合太高

查询数据库时很费劲,影响开发效率

效率比较低,需要自己使用连接池连接

1.2 相关网址

官网:https://mybatis.org/mybatis-3/zh/index.html
mybatis的jar包+源码:https://github.com/mybatis/mybatis-3/releases

记得挂一个加速器,毕竟是国外网站

数据库驱动jar包:https://downloads.mysql.com/archives/c-j/

2.测试

2.1 运行第一个mybatis

1 准备数据库

用户信息

数据库user,表Dept

2 新建一个web工程





3 新建lib文件夹,导入jar包

依赖包

核心包

数据库驱动包

4 新建mybatis的核心配置文件mybatis.xml


核心配置文件的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>

数据库连接配置

    <!--配置mybatis中数据库连接环境-->
    <!--选择一个<enviroment>的数据库连接-->
    <environments default="mysql">

        <!--具体链接某个数据库-->
        <environment id="mysql">
            <!--配置mybatis中的事务,和JDBC中的事务保持一致-->
            <transactionManager type="JDBC"/>
            <!--配置连接数据库的4个元素,底层采用的是数据库连接池的方式-->
            <dataSource type="POOLED">
                <!--根据自己的数据库信息配置-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--&amp;  &的转义-->
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/user?
                    useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true"/>
                <property name="username" value="364_99"/>
                <property name="password" value="admin"/>
            </dataSource>
        </environment>
    </environments>

5 新建Dept类

package com.mybatis.proj;

import java.io.Serializable;
//当你想把的内存中的对象状态保存到一个文件中或者数据库中时,需要实现此接口
public class Dept implements Serializable {
    private Integer deptno;
    private String dname;
    private String loc;

    //重写toString
    @Override
    public String toString() {
        return "Dept{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\\'' +
                ", loc='" + loc + '\\'' +
                '}';
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }
}

6 新建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">

写入sql语句

<!--
namespace原则上可以任意命名  规范的叫法使用 包名称+xml名称,用于区分不同的xml
多个mapper映射文件的namespace不能相同
-->
<mapper namespace="com.mybatis.mapper.DeptMapper1">
    <!--
        id——方法名称
        resultType——返回值类型
        parameterType——参数类型(建议省略,怕写错)
    -->
    <select id="selectAll" resultType="com.mybatis.proj.Dept">
        select * from Dept;
    </select>
</mapper>

7 在核心配置文件中加载映射文件

    <!--加载映射文件-->
    <mappers >
        <!--
            resource:文件在项目文件中的位置
            url:文件在磁盘中的位置,格式:url="file///磁盘位置"
        -->
        <mapper resource="com/batis/mapper/DeptMapper1.xml"></mapper>
    </mappers>
</configuration>

8 新建log4j.properties文件

在src中创建

#定义全局日志级别调试阶段推荐debug
log4j.rootLogger=debug,stdout 
#包级别日志 调试阶段推荐debug
log4j.logger.com.mybatis.mapper=debug

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout

log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=d:/bjsxt.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n

9 新建测试类

package com.test;

import com.mybatis.proj.Dept;
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 Test1 {
    public static void main(String[] args) throws IOException {
        //解析扫描mybatis.xml文件
        InputStream stream = Resources.getResourceAsStream("mybatis.xml");
        //获得sqlsession的工厂对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
        //获得sqlsession对象
        SqlSession sqlSession = factory.openSession();
        //执行sql语句
        List<Dept> list = sqlSession.selectList("com.mybatis.mapper.DeptMapper1.selectAll");

        System.out.println(list);

        //关闭资源
        sqlSession.close();

    }
}

运行

2.2 相关配置详解

1 log4j.properties

log4j三个重要组件:

  • 日志信息的优先级:只会输出比声明优先级高的信息(包括声明的优先级)
    A:off 最高等级,用于关闭所有日志记录。
    B:fatal 指出每个严重的错误事件将会导致应用程序的退出。
    C:error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
    D:warm 表明会出现潜在的错误情形。
    E:info 一般和在粗粒度级别上,强调应用程序的运行全程。
    F:debug 一般用于细粒度级别上,对调试应用程序非常有帮助。

    G:all 最低等级,用于打开所有日志记录。
  • 日志信息的输出目的地
    指定了日志将打印到控制台还是文件中
  • 日志信息的输出格式
    控制了日志信息的显示内容

定义配置文件:

  • 根Logger
log4j.rootLogger = [ level ] , appenderName, appenderName, …

level:优先级
appenderName:日志信息输出到哪个地方,可同时指定多个地址

  • 输出目的地Appender
log4j.appender.appenderName = fully.qualified.name.of.appender.class  
log4j.appender.appenderName.option1 = value1  
…  
log4j.appender.appenderName.option = valueN

输出的地址参数:
org.apache.log4j.ConsoleAppender:控制台
org.apache.log4j.FileAppender:文件
org.apache.log4j.DailyRollingFileAppender:每天产生一个日志文件
org.apache.log4j.RollingFileAppender:文件大小到达指定尺寸的时候产生一个新的文件
org.apache.log4j.WriterAppender:将日志信息以流格式发送到任意指定的地方

  • 日志信息的格式(布局)
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class  
log4j.appender.appenderName.layout.option1 = value1  
…  
log4j.appender.appenderName.layout.option = valueN

layout参数:
org.apache.log4j.htmlLayout:以HTML表格形式布局
org.apache.log4j.PatternLayout:可以灵活地指定布局模式
org.apache.log4j.SimpleLayout:包含日志信息的级别和信息字符串
org.apache.log4j.TTCCLayout:包含日志产生的时间、线程、类别等等信息

  • Log4J打印格式格式化日志信息的参数:
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL  
%r 输出自应用启动到输出该log信息耗费的毫秒数  
%c 输出所属的类目,通常就是所在类的全名  
%t 输出产生该日志事件的线程名  
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”  
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:20021018221028921  
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)

在代码中使用Log4j

  1. 获取记录器
    记录器将负责控制日志信息
public static Logger getLogger( String name)

// 通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字
static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )
  1. 读取配置文件
//当获得了日志记录器之后,第二步将配置Log4j环境

    BasicConfigurator.configure (): 自动快速地使用缺省Log4j环境。

    PropertyConfigurator.configure ( String configFilename) :读取使用Java的特性文件编写的配置文件。

    DOMConfigurator.configure ( String filename ) :读取XML形式的配置文件。

  1. 插入记录信息(格式化日志信息)
//当上面两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方


    Logger.debug ( Object message ) ;

    Logger.info ( Object message ) ;

    Logger.warn ( Object message ) ;

    Logger.error ( Object message ) ;

2 事务配置

在mybatis核心配置文件中 emvirment中 通过transactionManager配置事务的处理策略

JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。
MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如 Spring 或 JEE 应用服务器的上下文) 默认情况下它会关闭连接。然而一些容器并不希望这样, 因此如果你需要从连接中停止它,将 closeConnection 属性设置为 false. mybatis本身并不做事务的处理,交给其他框架去处理事务,如spring

3 映射文件的加载方式

  1. mapper映射文件的文件路径导入 使用的mapper标签的resource属性
  2. 网络资源路径 使用的mapper标签的url属性
  3. 接口的全限定名导入 使用的是mapper标签的class属性 (基于接口的代理模式开发)
  4. 包扫描形式加载所有的mapper映射文件 使用的是 package标签

4 实体类别名处理

在mybatis核心配置文件中使用别名处理

    <!--设置实体类别名-->
    <typeAliases>
        <!--
        通过包扫描给所有的实体类起别名
        给指定报名下的所有类起别名
        默认每个实体类的别名是首字母小写的类名
        Dept   dept
        Emp    emp
        -->
        <package name="com.mybatis.proj"/>
    </typeAliases>

在映射文件的resultType 返回值类型 和paramterType 上就可以使用别名了

<mapper namespace="com.mybatis.mapper.DeptMapper1">
    <!--
       别名不区分大小写
    -->
    <select id="selectAll" resultType="DEpt">
        select * from Dept;
    </select>
</mapper>

5 外部属性配置文件存储数据库链接信息

在src下准备jdbc.properties属性配置文件

将数据库的连接内容写到此配置文件中

#最好在名字前加一个前缀,防止冲突
d_driver=com.mysql.cj.jdbc.Driver
#不需要写转义字符,直接写&
d_url=jdbc:mysql://127.0.0.1:3306/user?useUnicode=true&characterEncoding=utf8&useSSL=true
d_username=364_99
d_password=admin

在核心配置文件中引入jdbc.properties属性文件

    <properties resource="jdbc.properties"></properties>

property中的value值改为${配置文件中对应的名称}

    <!--选择一个<enviroment>的数据库连接-->
    <environments default="mysql">

        <!--具体链接某个数据库-->
        <environment id="mysql">
            <!--配置mybatis中的事务,和JDBC中的事务保持一致-->
            <transactionManager type="JDBC"/>
            <!--配置连接数据库的4个元素,底层采用的是数据库连接池的方式-->
            <dataSource type="POOLED">
                <!--根据自己的数据库信息配置-->
                <property name="driver" value="${d_driver}"/>
                <!--&amp;  &的转义-->
                <property name="url" value="${d_url}"/>
                <property name="username" value="${d_username}"/>
                <property name="password" value="${d_password}"/>
            </dataSource>
        </environment>
    </environments>

3.MyBatis基于传统DAO模式开发

即使用SQLSession对象完成CURD

3.1 MyBatis查询的三种方式

  1. 返回对象List集合selectList
  2. 返回单个对象selectOne
  3. 返回对象Map集合selectMap

Mapper映射文件

<mapper namespace="com.mybatis.mapper.DeptMapper1">

   <select id="selectList" resultType="dept">
        select * from Dept;
    </select>
    
    <select id="selectOne" resultType="dept">
        select * from Dept where deptno = 1;
    </select>
    
    <select id="selectMap" resultType="dept">
        select * from Dept;
    </select>
</mapper>

测试类

        //A、查询方式一  selectList()
        List<Dept> list = sqlSession.selectList("com.mybatis.mapper.DeptMapper1.selectList");
        System.out.println(list);
        //B、查询方式二  selectOne()  查询结果最多返回是一条记录数
        Dept dept = sqlSession.selectOne("com.mybatis.mapper.DeptMapper1.selectOne");
        System.out.println(dept);
                //C、查询方式三  selectMap()   uid指定数据库中那一列作为map集合中key
        Map<Object, Object> deptno= sqlSession.selectMap("com.mybatis.mapper.DeptMapper1.selectMap", "deptno");
        System.out.println(deptno);
        System.out.println(uid);
        //关闭资源
        sqlSession.close();

3.2 MyBatis参数传递的三种方式

  1. 单个基础数据类型作为参数

映射文件:

    <!--
        Dept selectOne(int deptno)
        param1:代表当前参数
    -->
    <select id="selectOne" resultType="dept">
        select * from Dept where deptno = #{param1};
    </select>

测试类:

        /*传递一个参数值
            s:sql语句
            o:参数数值
         */
        Dept dept = sqlSession.selectOne("com.mybatis.mapper.DeptMapper1.selectOne",3);
        System.out.println(dept);

  1. 多个基础数据类型的map 集合作为参数

映射文件

    <!--
        Dept selectOne(Map map)
        param1:代表当前参数
    -->
    <select id="selectOne2" resultType="dept">
        select * from Dept where dname=#{a} and loc=#{b};
    </select>

测试类

        Map<String,Object> map = new HashMap<>();
        map.put("a","行政管理部");
        map.put("b","A409");
        Dept dept2 = sqlSession.selectOne("com.mybatis.mapper.DeptMapper1.selectOne2",map);
        System.out.println(dept2);
  1. 引用类型作为参数

映射文件:

    <!--
        Dept selectOne(Dept dept)
        param1:代表当前参数
    -->
    <select id=MyBatis源码解读——MapperProxy

Mybatis缓存机制

当MYSQL设置AUTOCOMMIT = 0时,Mybatis sqlSession.com不起作用

MyBatis框架UserMapperTest类的改进及核心配置文件

八SqlSession 执行 Mapper 过程详解

MyBatis--01.基础