typora-copy-images-to: imgs

回顾:

JDBC开发的流程:
1)注册驱动
2)通过驱动管理器获取连接对象
    conn.setAutoCommit(false);//手动开启事务
3)获取发送SQL的对象(3种)
    //获取预编译对象
   PreparedStatement pstm= conn.prepareStatement(sql模板);
   //对模板中?赋值
   pstm.setString(占位符索引位,值);
4)发送SQL或者参数(2个方法)
   //发送参数,执行SQL
   int count= pstm.executeUpdate();
   ResultSet rs= pstm.executeQuery();
5)接收参数并解析
    conn.commit();
    conn.rollback();
6)关闭资源,释放连接(3个close)

连接池:
  好处:1)提高了Connection连接对象的复用性;
       2)避免连接对象反复的创建与销毁带来的性能开销,提高了数据库吞吐量;

1. MyBatis(第1天)

1604625421462

2. 1.框架概述

2.1. 什么是框架

程序开发中的框架往往是对常见功能的封装,通常与具体业务无关,也可以认为是软件的半成品。程序框架理解为基础或者机械标准件(例如螺丝螺母标准的机械部件)。

假如你要造一辆马车,在没有框架的情况下,你需要自己去伐木,去把木头做成木板,木棍,然后组成轮子,门,等部件,然后组装起来。但如果你用了框架,就相当于你有现成的轮子,门等部件,你只需要组装一下就可以了。

一个框架是一组可复用的设计构件。

框架是一个半成品,软件是成品。我们在它的基础上开发出成品(软件)。

2.2. 框架解决的问题

1.解决了技术通用的问题

在JavaEE体系中,有着各种各样的技术。不同的软件企业,根据自身的业务需求选择不同的技术,容易造成应用依赖技术,增加了项目开发实现的复杂性和技术风险性。而框架技术就可以解决上述问题。

2.提升了开发效率

企业项目中使用框架,只需要专注实现业务需求。使用框架的方便性,提升了开发效率

3.提升了系统稳定性

一个成熟的框架,经过了在众多企业项目中的验证使用,稳定性有保障

3. 2.Mybatis框架介绍

3.1. 2.1 mybatis框架介绍

    mybatis是Apache软件基金会下的一个开源项目,前身是iBatis框架。2010年这个项目由apache 软件基金会迁移到google code下,改名为mybatis。2013年11月又迁移到了github(GitHub 是一个面向开源及私有 软件项目的托管平台)。
    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射(多表)。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。它对 jdbc 的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建 connection、创建 statement、手动设置参数、结果集检索等 jdbc 繁杂的过程代码。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

3.1.1. 1.mybatis的优点

  1. 简单易学:mybatis本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个SQL映射文件即可。
  2. 使用灵活:Mybatis不会对应用程序或者数据库的现有设计强加任何影响。SQL语句写在XML里,便于统一管理和优化。
  3. 解除SQL与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易进行单元测试。SQL语句和代码的分离,提高了可维护性。

3.1.2. 2.mybatis的不足

  1. 编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
  2. SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
  3. 框架还是比较简陋,功能尚有缺失(分页插件\乐观锁\分布式事务等)。

3.1.3. 3.官方网站及框架包下载

官网地址:http://www.mybatis.org/mybatis-3/

3.1.4. 4.mybatis框架整体架构

1)导入依赖的jar包
2)配置核心的配置文件:一般全局只有一个,内部主要配置了1)数据源配置 2)加载sql映射文件 等
3)配置sql映射文件:一个项目中可以有多个映射文件,特点:1)namespace唯一标识这个文件信息 2)通过select/insert/delete/update标签的id唯一定义一个SQL;
4)加载核心配置文件,构建会话工厂
5)获取会话对象(openSession())
6)调用SqlSession的API完成增删改查操作
7)关闭资源,释放连接

3.1.5. 5.MyBatis的ORM方式


Object Relational Mapping 对象关系映射

Mybatis有两种映射方式:

1.通过XML映射;
2.通过注解;

小结:

1、mybatis解决了三层(web,service,dao)中哪一层的问题?

dao层
数据访问层
持久层

2、mybatis框架是对什么技术进行的封装?

jdbc

4. 3.MyBatis框架入门开发【掌握】

4.1. 4.1入门案例:环境的搭建和代码实现

数据准备:

create table user (
  id int primary key auto_increment,
  username varchar(20) not null,
  birthday date,
  sex char(1) default '男',
  address varchar(50)
);

insert into user values (null, '孙悟空','1980-10-24','男','花果山水帘洞');
insert into user values (null, '白骨精','1992-11-12','女','白虎岭白骨洞');
insert into user values (null, '猪八戒','1983-05-20','男','福临山云栈洞');
insert into user values (null, '蜘蛛精','1995-03-22','女','盤丝洞');

select * from user;
https://mybatis.org/mybatis-3/zh/index.html 
-- 官网参考地址

需求1:使用Mybatis框架,从User表中查询所有的用户

1.创建项目 2.创建lib目录,并导入mysql-connector-java-5.1.37.jar,mybatis-3.5.0.jar,log4j.jar

1604626641296

3.创建实体类User

package com.pojo;

import java.sql.Date;

public class User {

    private Integer id;

    private String username;

    private Date birthday;

    private String sex;

    private String address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

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

    public String getSex() {
        return sex;
    }

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

    public String getAddress() {
        return address;
    }

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

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

4.在src下创建核心配置文件: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">
<!--mybatis核心配置文件的跟标签-->
<configuration>
    <!--environments多环境配置标签 default="development"表示默认使用development环境 -->
    <environments default="dev">
        <!--配置具体数据库数据源环境 id表示环境的唯一标识-->
        <environment id="dev">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///day06_1"/>
                <property name="username" value="root"/>
                <property name="password" value="1234"/>
            </dataSource>
        </environment>
    </environments>
    <!--批量加载 sql映射文件-->
    <mappers>
        <mapper resource="UserMapper.xml"/>
        <!--<mapper resource="UserMapper2.xml"/>-->
    </mappers>
</configuration>

5.在src下创建映射文件userMapper.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="org.example.UserMapper">
    <!--select:表示查询的标签  id表示唯一标识,但是在当前的命名空间下必须唯一 -->
    <!--resultType="com.pojo.User":表示查询返回的结果类型 -->
    <select id="selectUser" resultType="com.pojo.User">
        select * from user where id = #{id}
    </select>
</mapper>

6.编写测试类代码

public class TestAll {

    @Test
    public void test1() throws IOException {
        //1)加载核心配置文件,构建会话工厂
        String config_file="mybatis-config.xml";
        InputStream in = Resources.getResourceAsStream(config_file);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //2)获取会话对象
        SqlSession session = factory.openSession();
        //3)执行sql,获取结果
        User user = (User)session.selectOne("org.example.UserMapper.selectUser", 2);
        System.out.println(user.toString());
        //4)释放资源,关闭连接
        session.close();
    }
}

7.配置log4j.properties日志

### 设置Logger输出级别和输出目的地 ###
log4j.rootLogger=debug, stdout
### 把日志信息输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout

8.效果

1604630174882

加载流程:

1604629953570

小结:

使用mybatis老式的开发模式弊端:

1)命名空间随便取名,维护性比较差;
2)调用指定命名空间下的sql语句,需要拼接,容易出错,维护性差;

4.2. 4.2 基于IDEA自定义常用xml文件模板

模板官网地址:https://mybatis.org/mybatis-3/zh/getting-started.html

我们可以将核心的配置文件在idea中做成一个模板文件,用的时候直接创建就好;

1604630728155

使用模板:

1604630806290

4.3. 4.3 IDEA下使用自带的数据库客户端

注意:

1.我们可以使用IDEA连接数据库避免开发过程终端的切换,提高开发效率;

注意事项:连接数据库可能报时区的错误

-- 数据库端添加时区设置的参数
set global time_zone='+8:00';
-- 或者在连接的url中指定
jdbc:mysql://url:3306/test?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai

1604630924858

1604631108389

使用:

1604631304442

小结:

1.Mybatis框架的核心组件有哪些?

1)SqlSessionFactoryBuilder
2)SqlSessionFactory-->--->build();
3)SqlSession---->openSession();

2.老式mybatis入门程序的开发流程?

1)导入jar包
2)创建表的映射pojo;
3)配置核心配置文件(1.数据源 2.加载映射文件)
4)配置映射文件(1.namespace全局唯一 2.增删改查标签在命名空间下唯一)
5)加载核心配置文件,构建会话工厂;
6)获取会话对象
7)调用会话对象的API完成sql操作(selectOne,selectList,insert,delete,update等等)
    要定位一个sql需要【命名空间.增删改查标签的id】来定位sql
8)关闭资源,释放连接

5. 4.mybatis的dao层动态代理实现【掌握】

说明:Mybatis存在2种执行SQL语句的方式:

1)旧版本mysql执行的方式;

2)动态代理实现操纵数据库;

需求2:利用Mybatis动态代理,从mysql中查询所有的用户

第一步:新建接口 UserMapper;

public interface UserMapper {

    User findUserById(Integer id);

}

第二步:将接口和映射文件绑定,在映射文件中书写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">
<!--映射文件的跟标签 namespace:命名空间,值对应的时接口的全限定名称-->
<mapper namespace="com.mapper.UserMapper">
    <!--select:表示查询的标签  id表示唯一标识,与接口中的方法名称要一致 -->
    <!--resultType="com.pojo.User":表示查询返回的结果类型 -->
    <select id="findUserById" resultType="com.pojo.User">
        select * from user where id = #{id}
    </select>
</mapper>

第四步:获取UserMapper的动态代理对象完成查询;

    /**
     * 基于动态代理实现mybatis sql调用
     */
    @Test
    public  void test2() throws IOException {
        //1)加载核心配置文件,构建会话工厂
        String config_file="mybatis-config.xml";
        InputStream in = Resources.getResourceAsStream(config_file);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //2)获取会话对象
        SqlSession session = factory.openSession();
        //3)获取接口的代理对象
        //session.selectOne("命名空间.id",参数)
        UserMapper userMapper = session.getMapper(UserMapper.class);
        User user = userMapper.findUserById(2);
        System.out.println(user.toString());
        //4)释放资源,关闭连接
        session.close();
    }

原理图:

1604633544621

小结:

1.Mybatis动态代理开发流程?

1)导入依赖的jar; 
2)创建pojo类;
3)配置核心配置文件;
4)创建Mapper接口
5)创建SQL的映射文件,同时与Mapper接口进行绑定;
  (1.sql映射文件的命名空间的值与接口的全限定名称一致 2.接口中的方法名称与sql映射文件中增删改查标签的id要一致 3.写sql)
6)加载核心配置文件,构建会话工厂(new SqlSessionFactoryBuilder().build(in));
7)通过会话工厂获取会话对象(factory.openSession())
8)通过会话对象获取接口的代理对象
9)直接调用接口方法,完成业务功能;
10)关闭资源,释放连接(session.close())

6. 5.mybatis核心配置

【mybatis全局配置介绍】

​ mybatis-config.xml,是MyBatis的全局配置文件,包含全局配置信息,如数据库连接参数、插件等。整个框架中只需要一个即可

参考:https://mybatis.org/mybatis-3/zh/configuration.html
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
configuration(配置)
        properties(属性)
        settings(设置)
        typeAliases(类型别名)
        typeHandlers(类型处理器)
        environments(环境配置)
        environment(环境变量)
        transactionManager(事务管理器)
        dataSource(数据源)
        mappers(映射器)

说明:上述标签在实际使用过程中,要严格遵循使用顺讯,否则报错;

1604634346360

6.1. 5.1、properties(属性)

6.1.1. 1.作用:

1、通过子标签property设置属性;
2、加载外部的java资源文件(properties文件);

1604634552372

6.1.2. 2.两种使用\标签的方式

方式1(了解即可):
1、通过properties的子标签设置属性;
2、使用${key}获取设置的属性值;
方式2:
1.通过properties标签 resource属性引入加载外部properties文件
    <!--<properties>
       <property name="userName" value="root"/>
    </properties>-->
  <!-- resource属性表示引入外部的properties配置文件,使用${变量}获取配置文件中的数据-->
    <properties resource="config/jdbc.properties"/>

    <!--environments多环境配置标签 default="development"表示默认使用development环境 -->
    <environments default="dev">
        <!--配置具体数据库数据源环境 id表示环境的唯一标识-->
        <environment id="dev">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

6.1.3. 2.练习

练习:使用properties下的resource引入外部配置文件(企业开发推荐)

  <!-- resource属性表示引入外部的properties配置文件,使用${变量}获取配置文件中的数据-->
    <properties resource="config/jdbc.properties"/>

第一步:创建jdbc.properties配置文件:

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=1234
jdbc.url=jdbc:mysql:///day06_1

第二步:核心配置文件通过\表中的resource属性引入jdbc.properties文件

  <!-- resource属性表示引入外部的properties配置文件,使用${变量}获取配置文件中的数据-->
    <properties resource="config/jdbc.properties"/>

    <!--environments多环境配置标签 default="development"表示默认使用development环境 -->
    <environments default="dev">
        <!--配置具体数据库数据源环境 id表示环境的唯一标识-->
        <environment id="dev">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

小结:

1)properties作用:配置一些全局的属性集(key--->value)
2)获取value值---》"${key}"

6.2. 5.2、settings(设置)

settinngs是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

image-20201021205535135

settings参数有很多,我们先学习驼峰匹配mapUnderscoreToCamelCase,翻译过来就是映射下划线到驼峰式命名。

练习:可视化操作DDL修改数据库username属性为user_name,并建立与pojo映射关系,配置驼峰映射

思考:如果数据库的字段名与属性名不一致,且不满足上述映射规范,该如何处理?

1)pojo:

public class User {

    private Integer id;

    private String userName;

    private Date birthday;

    private String sex;

    private String address;
    ......

2)设置开启驼峰映射

    <settings>
        <!--开启驼峰映射 table :user_name 映射成: pojo userName-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
     </settings>

小结:

1.开启驼峰自动映射的作用?

开启语法:
<settings>
 <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
作用:
驼峰映射: 库: name_name1_name_2 ----->类:nameName1Name2

6.3. 5.3、typeAliases(类型别名)

6.3.1. 1.作用

类型别名是给类的全限定名称(包名.类名) 取一个短名称。存在的意义仅在于用来减少类完全限定名的冗余

image-20201021210241071

可以通过设置一些短名来代替全限定名,有两种方式:

方式一:使用typeAliases标签的子标签typeAlias手动设置类型别名(逐一设置维护);
方式二:使用typeAliases标签的子标签package包扫描映射别名(推荐);

6.3.2. 2.需求

练习1:使用typeAliases标签的子标签typeAlias简化UserMapper.xml中pojo类的名称

<typeAliases>
        <!--好处:可以随便去别名
             弊端:有多个pojo就需要配置多少个别名标签
        -->
        <typeAlias type="com.pojo.User" alias="user"/>
    </typeAliases>

练习2:使用typeAliases标签的子标签package包扫描映射别名

 <typeAliases>
        <package name="com.pojo"/>
  </typeAliases>

6.3.3. 3.内置别名

这是一些为常见的 Java 类型内建的相应的类型别名。它们都是不区分大小写的,注意对基本类型名称重复采取的特殊命名风格。

别名 映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

练习3:完成根据id查询用户信息,且使用参数使用Integer别名int;

<!-- parameType=“int” int别名代表Integer -->    
<select id="findUserById" resultType="user" parameterType="int">
        select * from user where id = #{id}
</select>

6.4. 5.4、typeHandlers(类型处理器)【了解】

​ MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器。

image-20201021210930639

提示 从 3.4.5 开始,MyBatis 默认支持 JSR-310(日期和时间 API) 。

https://mybatis.org/mybatis-3/zh/configuration.html#settings

说明:mybatis内置的一些类型处理器,企业开发中使用默认的类型处理器;

6.5. 5.5、environments【了解】

MyBatis 可以配置成适应多种环境,例如,开发、测试和生产环境需要有不同的配置;
尽管可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一。
虽然,这种方式也可以做到很方便的分离多个环境,但是实际使用场景下,我们更多的是选择使用spring来管理数据源,来做到环境的分离。
      父标签: environments(环境配置)
            子标签:
                environment(环境变量)
                transactionManager(事务管理器)
                dataSource(数据源)

注意事项:

虽然,这种方式也可以做到很方便的分离多个环境,但是实际使用场景下,我们更多的是选择使用第三方的连接池:druid,C3P0。并且使用spring来管理数据源(连接池),来做到环境的分离。

练习:

1.配置多环境数据源,比如dev,test.online等,并指定online为默认环境运行mybatis

    <!--environments多环境配置标签 default="development"表示默认使用development环境 -->
    <environments default="test">
        <!--配置具体数据库数据源环境 id表示环境的唯一标识-->
        <environment id="dev">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

        <environment id="test">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="jdbc:mysql:///day06_2"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

2.配置多环境数据源,比如dev,test.online等,并使用会话构建工厂指定运行环境

​ 说明:在构建会话工厂的build方法中指定运行环境;

    @Test
    public  void test2() throws IOException {
        //1)加载核心配置文件,构建会话工厂
        String config_file="mybatis-config.xml";
        InputStream in = Resources.getResourceAsStream(config_file);
        //SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in,"test");
        //2)获取会话对象
        SqlSession session = factory.openSession();
        //3)获取接口的代理对象
        //session.selectOne("命名空间.id",参数)
        UserMapper userMapper = session.getMapper(UserMapper.class);
        User user = userMapper.findUserById(2);
        System.out.println(user.toString());
        //4)释放资源,关闭连接
        session.close();
    }

小结:

2种改变数据源的方式:
1)通过environments标签下default="指定的数据库环境environment标签id"
2)通过SqlSessionFactoryBuilder 下build(in,数据库环境id标识)

6.6. 5.6、mappers(映射器)

6.6.1. 1.介绍

mappers(映射器):UserMapper.xml====>UserMapper.java接口 关联.

作用:维护接口和映射文件之间的关系.

使用方式: 1、加载映射文件,关联UserMapper.java接口 【1】 从src下加载映射文件; 【2】 从本地磁盘中加载映射文件,但是需要添加file:///协议

​ 2、加载接口,关联映射文件 ​ 条件:1、接口名和映射文件名保持一致;2、路径保持一致; ​ 【1】class:加载单独的接口: ​ 【2】批量加载class:

6.6.2. 2.练习

1)使用mapper下resource属性加载xml映射文件关联接口

    <mappers>
        <!--方式1:1.映射文件名称随便定义 2.映射文件不用与接口存放到一块-->
        <mapper resource="user4Mapper.xml"/>
        <!--<mapper resource="UserMapper2.xml"/>-->
    </mappers>

2)使用完全限定资源符加载映射文件(了解即可)

    <mappers>
        <!--方式1:1.映射文件名称随便定义 2.映射文件不用与接口存放到一块-->
        <!--<mapper resource="user4Mapper.xml"/>-->
        <!--开发过程不推荐
            1)不同的开发人员,项目代码存放的路基不同,维护性差;
            2)项目部署后,部署的路径不一定与开发的路径一致;
            3)在集群环境下,不同的机器下可能部署的路径不一致;
        -->
        <mapper url="file:///E:\heima_code\119\mybatis_day06\src\user4Mapper.xml"/>
    </mappers>

3)使用映射器接口实现类的完全限定类名 (了解即可)

前提条件:
1、接口名和映射文件名保持一致;
2、路径保持一致;
3.映射文件中的namespace必须与接口的全限定名称一致;
       <!--
          约束前提:
             1)接口的名称与xml映射文件的名称必须一致
             2)接口存放的路径必须与xml映射文件存放的路径要一致
           弊端:
             1)xml文件与java文件存放到相同路径下,可维护性查询
             2) 约束条件多 
       -->
        <mapper class="com.mapper.UserMapper"/>

4)加载接口,关联映射文件方式package(推荐)

前提条件:
1.接口与映射文件名称必须相同;
2.接口与映射文件路径必须相同;
3.映射文件中的namespace必须与接口的全限定名称一致;
<!--
            约束前提:
             1)接口的名称与xml映射文件的名称必须一致
             2)接口存放的路径必须与xml映射文件存放的路径要一致
           name="com.mapper":表示扫描com.mapper包下的所有接口,并加载
           推荐:在基于注解开发的时候推荐使用
-->
<package name="com.mapper"/>

小结:

1)xml加载的4中方式:

1)使用resource属性加载 基于xml开发推荐使用
  <mappers>
     <mapper resource="引入外部的映射文件"/>
  </mappers>
2)使用url定位映射文件绝对路径加载 了解即可
  <mappers>
     <mapper url="file:///引入外部的映射文件"/>
  </mappers>
3)加载接口,使用class属性
  <mappers>
     <mapper class="接口的全限定名称"/>
     .....
  </mappers>
4)基于package扫包,加载指定包下的所有接口
  <mappers>
     <package name="接口路径"/>
  </mappers>

1.基于package扫描的原理?

1)前提约束:
   1.xml映射文件与接口要在同一个路径下;
   2.xml映射文件名称与接口名称要一致;
基于包扫描指定的包名,加载接口集合,就可以获取接口的信息(名称), 就可以加载xml映射文件

2.思考:基于package扫描存在的缺点?

1)约束太多了
    1.同路径;
    2.同名;

7. 6.编写会话工具类


  1. 在静态代码块中创建会话工厂对象
  2. 编写静态方法得到会话对象
  3. 编写静态方法得到会话工厂对象
public class MybatisUtils {

    static final String CONFIG_FILE="mybatis-config.xml";

    static SqlSessionFactory factory;

    static  ThreadLocal<SqlSession> threadLocal=new ThreadLocal<>();
    //会话工厂只加载一次即可,因为会话工厂的创建有io开销
    static {
        initFactory(CONFIG_FILE);
    }

    /**
     * 初始化会话工厂的方法
     * @param configFile
     */
    private static void initFactory(String configFile) {
        InputStream in = null;
        try {
            in = Resources.getResourceAsStream(configFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        factory = new SqlSessionFactoryBuilder().build(in);
    }

    //sesssion要使用的地方: 1)获取代理对象 2)设置事务commit/rollback 3.close
    /**
     * 获取session对象
     * @return
     */
    public static SqlSession getSession(){
        SqlSession sqlSession = threadLocal.get();
        if(sqlSession==null){
          sqlSession=  factory.openSession();
          threadLocal.set(sqlSession);
        }
        return sqlSession;
    }

    /**
     * 获取动态代理对象
     * @param tClass
     * @param <T>
     * @return
     */
    public static  <T> T getMapper(Class<T> tClass){
        return getSession().getMapper(tClass);
    }

    /**
     * 关闭资源,释放连接
     */
    public static void close(){
        SqlSession sqlSession = threadLocal.get();
        if(sqlSession!=null){
            sqlSession.close();
            threadLocal.set(null);
        }
    }

    /**
     * 事务提交
     */
    public static void commit(){
        SqlSession sqlSession = threadLocal.get();
        if(sqlSession!=null){
            sqlSession.commit();
        }
    }

    /**
     * 事务回滚
     */
    public static void rollback(){
        SqlSession sqlSession = threadLocal.get();
        if(sqlSession!=null){
            sqlSession.rollback();
        }
    }
}

8. 7.Mybatis环境搭建及相关插件使用

1.需求

搭建mybatis环境,完成dao层根据id查询用户数据功能;

2.数据准备:

create table user (
  id int primary key auto_increment,
  username varchar(20) not null,
  age int,
  birthday date,
  sex char(1) default '男',
  address varchar(50)
);

insert into user values (null, '孙悟空',30,'1980-10-24','男','花果山水帘洞');
insert into user values (null, '白骨精',20,'1992-11-12','女','白虎岭白骨洞');
insert into user values (null, '猪八戒',20,'1983-05-20','男','福临山云栈洞');
insert into user values (null, '蜘蛛精',30,'1995-03-22','女','盤丝洞');

select * from user;

3.具体操作步骤

1.创建工程

2.导入依赖jar包;

3.创建接口和实体类;

4.配置mybatis全局配置文件和映射文件;

5.测试;

9. 8.Mybatis映射文件配置

【注意】

​ Mapper映射文件中定义了操作数据库的sql,每一个sql都被包含在一个statement中。映射文件是mybatis操作数据库的核心。

SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

cache – 该命名空间的缓存配置。
cache-ref – 引用其它命名空间的缓存配置。
resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
parameterMap – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
sql – 可被其它语句引用的可重用语句块。
insert – 映射插入语句。
update – 映射更新语句。
delete – 映射删除语句。
select – 映射查询语句。

1604650228948

9.1. 8.1、SQL语句-CRUD

​ 映射文件中需要直接书写SQL语句对数据库进行操作,对数据库操作SQL语句主要有CRUD这四类。这四类对应到映射文件中的配置为四类标签:selectinsert,updatedelete

9.1.1. 1.select标签

select标签属性:

属性名 说明 是否必须
id 这条SQL语句的唯一标识,和接口的方法名一致
parameterType 入参类型
resultType 返回值类型

练习:根据id查询姓名

1)pojo

public class User {

    private Integer id;

    private String userName;

    private Date birthday;

    private String sex;

    private String address;

2)定义接口

public interface UserMapper {

    /**
     * 根据id查询用户名称
     * @param id
     * @return
     */
    String findUserNameById(Integer id);

}

3)配置核心文件:

<?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>

    <!--<properties>
       <property name="userName" value="root"/>
    </properties>-->
  <!-- resource属性表示引入外部的properties配置文件,使用${变量}获取配置文件中的数据-->
    <properties resource="jdbc.properties"/>

     <settings>
        <!--开启驼峰映射 table :user_name 映射成: pojo userName-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
     </settings>

    <!--<typeAliases>
        &lt;!&ndash;好处:可以随便去别名
             弊端:有多个pojo就需要配置多少个别名标签
        &ndash;&gt;
        <typeAlias type="com.pojo.User" alias="user"/>
    </typeAliases>-->
    <typeAliases>
        <!--别名是类的名称,并且首字母小写-->
        <package name="com.heima.pojo"/>
    </typeAliases>

    <!--environments多环境配置标签 default="development"表示默认使用development环境 -->
    <environments default="dev">
        <!--配置具体数据库数据源环境 id表示环境的唯一标识-->
        <environment id="dev">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

        <environment id="test">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="jdbc:mysql:///day06_2"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--批量加载 sql映射文件-->
    <mappers>
        <!--方式1:1.映射文件名称随便定义 2.映射文件不用与接口存放到一块-->
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

3)将接口与映射文件进行绑定

<?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="com.heima.mapper.UserMapper">
    <select id="findUserNameById" resultType="string" >
        select user_name from user where id=#{id}
    </select>
</mapper>

4)加载核心配置文件,构建会话工厂,完成测试

public class TestAll {

    @Test
    public  void   test1() throws IOException {
        //1)加载核心配置文件,构建会话工厂
        Reader in = Resources.getResourceAsReader("mybatis-config.xml");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
        //2)获取会话对象
        SqlSession sqlSession = sessionFactory.openSession();
        //3)获取代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //4)调用接口方法即可
        String name = userMapper.findUserNameById(1);
        System.out.println(name);
        //5)关闭资源,释放连接
        sqlSession.close();

    }
}

9.1.2. 2.insert标签

属性:

属性 说明 是否必须
id 这条SQL语句的唯一标识,和接口的方法名一致

注意:

//默认手动提交事务,可改为自动提交事务:
SqlSession sqlSession = sqlSessionFactory.openSession(true);

说明:#{username},#{birthday},#{sex},#{address} 大括号里面的值必须和pojo的实体类User类中的属性名一致,否则会报错。其实这里看的是User类中的getXxx()的get后面的xxx内容;

例如 getUserName---看的是userName ,就是将get去掉,U变为小写u,后面不变

1)定义接口方法:

    /**
     * 返回类型integer表示受影响的行数
     * @return
     */
    Integer addUser(User user);

2)绑定映射文件

    <!--
      如果接口传入的是一个pojo对象,那么#{变量}  变量名称与pojo中对应属性名称要一致
      userName -> getUserName->反射获取属性值
    -->
    <insert id="addUser">
        insert into user values(null,#{userName},#{birthday},#{sex},#{address})
    </insert>

3)完成测试

    @Test
    public void test2(){
        UserMapper userMapper = MybatisUtils.getMapper(UserMapper.class);
        User user = new User();
        user.setAddress("上海");
        user.setBirthday(Date.valueOf("2020-11-06"));
        user.setSex("男");
        user.setUsername("柳岩");
        Integer count = userMapper.addUser(user);
        System.out.println(count);
        //手动提交
        MybatisUtils.commit();
        //释放资源
        MybatisUtils.close();
    }

小结:

1)<insert id="对应接口中的方法名称">
    insert into t values(null,#{pojo对应表的属性名})
  </insert>

9.1.3. 3.update标签属性说明

属性 说明 是否必须
id SQL语句的唯一标识,和接口的方法名一致

1)定义接口方法

    /**
     * 更新用户信息
     * @return
     */
    void updateUser(User user);

2)绑定映射文件

    <update id="updateUser">
        update user set user_name=#{userName},birthday=#{birthday},
        sex=#{sex},address=#{address} where id=#{id}
    </update>

3)测试

    @Test
    public void test3(){
        UserMapper userMapper = MybatisUtils.getMapper(UserMapper.class);
        User user = new User();
        user.setId(5);
        user.setAddress("湖南");
        user.setBirthday(Date.valueOf("1987-11-06"));
        user.setSex("女");
        user.setUsername("柳岩2");
        userMapper.updateUser(user);
        MybatisUtils.commit();
        MybatisUtils.close();
    }

9.1.4. 4.delete标签

属性:

属性 说明 是否必须
id SQL语句的唯一标识,和接口的方法名一致

1)定义接口方法

    /**
     * 根据用户id查询用户信息
     * @param id
     */
    void deleteById(Integer id);

2)映射文件绑定接口方法

    <delete id="deleteById">
        delete from user where id=#{id}
    </delete>

3)测试

    @Test
    public void test4(){
        UserMapper userMapper = MybatisUtils.getMapper(UserMapper.class);
        userMapper.deleteById(5);
        MybatisUtils.commit();
        MybatisUtils.close();
    }

总结:

1)核心配置文件配置标签mybatis-config.xml(要求:能理解即可)
<configuration>
  <properties resource="外部的properties文件"/>

  <settings>
    <setting name="xxx" value="布尔值,表示开启或者关闭"/>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
  </settings>

  <typeAliases>
     <typeAlias type="pojo的全限定名称" alias="别名" />
     <package name="pojo的包路径"/>
  </typeAliases>

  <!-- 2种指定数据源的方式1) default  2)SqlSesionFactoryBuilder ---> build(in,数据源唯一标识) -->
  <environments default="指定默认的数据库环境">
     <environment id="xxx 要唯一">
            <!--transactionManager标识事务交给jdbc去管理-->
            <transactionManager type="JDBC"/>
            <!--数据源配置标签  type="POOLED" 表示使用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
     </environment>
  </environments>

  <mappers>
    <!-- 共4中加载xml映射文件的方式 -->
    <mapper resource="外部的映射文件路径"/>
    <package name="接口的包路径"/>
  </mappers>

</configuration>

2)映射文件中常用标签
1.select
   格式:
   <select id="对应接口中的方法名称" resultType="pojo名称默认首字符小写/_基本类型/jdk对象类型小写">
      select * from t where id=#{任意变量}
   </select>
2.insert
   格式:
   <insert id="xx">
      insert into t values(null,#{对应pojo中属性名称},....)
   </insert>
3.update
    格式:
    <update id="xxx">
      update t set 字段1=#{对应pojo中属性名称},.... where id=#{id}
    </update>
4.delete
   格式:
   <delete id="xxx">
     delete from t where id=#{id}
   </delete>

results matching ""

    No results matching ""