Spring学习4:mybatis的使用1

5 篇文章 0 订阅
2 篇文章 0 订阅

首先提出一个问题:

在使用常规JDBC进行访问数据库的时候,我们如果需要对sql语句进行修改的时候,我们是否可以不进入每个类去修改相关的SQL的字符串吗?

在传统的JDBC连接数据库的开发模式下,当需要操作数据库的时候,首先我们需要:

  • 创建数据库连接类DBConnection
  • 通过getConnection方法获取数据库连接对象
  • 然后使用数据库连接对象的prepareStatement方法将编写好的SQL语句预编译。
  • 传入需要操作的参数,并执行SQL语句

常规JDBC如下所示:

public class JDBConnection {
    private final String dbDrive = "com.mysql.cj.jdbc.Driver";
    private final String url = "jdbc:mysql://localhost:3306/data?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
    private final String user = "root";                 //数据库账户名
    private final String Passwd = "123456";       //数据库密码
    private Connection con = null;

    public JDBConnection() {
        try {
            Class.forName(dbDrive).newInstance();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("数据库加载失败!");
        }
        //System.out.println("数据库加载成功!");
    }

    public boolean creatConnection() {
        try {
            con = DriverManager.getConnection(url, user, Passwd);
            con.setAutoCommit(true);
        } catch (SQLException e) {
            System.out.println(e.toString());
        }
        return true;
    }

    public boolean executeUpdate(String sql) {      //对数据库进行增加,修改,删除
        if (con == null) {
            creatConnection();
        }
        try {
            Statement stmt = con.createStatement();
            int iCount = stmt.executeUpdate(sql);
            //System.out.println("操作成功,所影响的记录数为" + String.valueOf(iCount));
            return true;

        } catch (SQLException e) {
            return false;
        }
    }

    public ResultSet executeQuery(String sql)   //对数据库进行查询操作
    {
        ResultSet rs;
        try {
            if (con == null) {
                creatConnection();
            }
            Statement stmt = con.createStatement();
            rs = stmt.executeQuery(sql);
        } catch (Exception e) {
            return null;
        }
        return rs;
    }

    public void closeConnecstion() {
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

我们对JDBC的使用是首先new一个JDBConnection的对象,我们再传入我们需要执行的sql语句。

public class main {
    public static void main(String[] args) {
        JDBConnection connection = new JDBConnection();
        String sql = "select * from main_damage";
        try {
            ResultSet result = connection.executeQuery(sql);
            while (result.next()){
                String s1=result.getString(1);
                String s2=result.getString(2);
                String s3=result.getString(3);
                String s4=result.getString(4);
                System.out.println(s1+" "+s2+" "+s3+" "+s4);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        finally {
            connection.closeConnecstion();
        }
    }
}

对于常规JDBC的sql语句是一种“硬编码”的形式,当数据库相应的表字段出现变动的时候,我们就需要对java的源代码进行修改,然后重新编译、打包、上线,这样的过程不利于软件系统的维护和扩展。

待优化问题:

  • 连接参数、SQL语句和硬编码:讲SQL语句配置在XML或者其他非Java的配置文件中,这样即使SQL发生变化,也不需要重新编译Java文件;
  • 数据库的频繁连接和断开:使用数据库连接池来管理数据的连接;
  • 查询结果集取数据的硬编码:使用一种机制,将查询出的结果集自动映射为JAVA对象,无需手动设置。

使用Mybatis框架可以逐步解决以上问题。
今天我们首先来学Mybatis的第一课:

一、Mybatis的介绍:
  • MyBatis是Apache的一个Java开源项目,原名为iBatis(即Internet与abatis的结合),后因项目托管平台的迁移(由Goolge Code转移至GitHub)更名为MyBatis。Mybatis是一款支持动态SQL语句的持久层框架,支持的目的是让开发人员集中精力在SQL语句上,而不是数据库的配置和连接上。
  • MyBatis可以将SQL语句配置在XML文件中,这就避免了JDBC在Java类中添加SQL语句的硬编码问题;通过MyBatis可以提供输入参数映射方式,讲参数自由灵活地配置在SQL语句配置文件中,解决了JDBC中参数在Java类中手工配置的问题;通过MyBatis的输出映射机制,讲结果集的检索自动映射成相应的Java对象或者Java对象集合,这就避免了JDBC中对结果集的手工检索;同时MyBatis还可以创建自己的数据库连接池,使用XML配置文件的形式,对数据库连接数据进行管理,避免了JDBC的数据库连接参数的硬编码问题。

总的来说:MyBatis的特点在于:采用配置文件动态管理SQL语句,并含有输入映射、输出映射机制以及数据库连接池配置的持久层框架。

二、MyBatis整体架构

MyBatis整体的构造由数据源配置文件、SQL映射配置文件、会话工厂、会话、执行器以及底层封装对象组成。

1、数据源配置文件
  • 对于一个持久层框架,也就是负责连接数据库,并且对数据库进行操作的一套框架,连接数据库是最重要的一步。MyBatis框架对于数据库连接的配置信息,采用了配置“数据库连接池”的形式。所谓的“数据库连接池”又称为“数据源”,就是让数据库的配置信息从外部的某种配置文件(此处为xml文件)中读取,然后由一个独立处理数据库连接的程序来和数据库进行交互。这样我们的应用程序就不必关心数据库的配置信息,数据库的配置交由独立的模块管理和配置。
  • 在MyBatis中,数据库的数据源是配置在SqlMapConfig.xml(文件名自定义)这个配置文件中的,其中配置了数据库驱动、数据库连接地址URL、数据库用户名和密码、事物管理等参数,如果对数据库连接池有性能的要求,还可以配置连接池的连接数和空闲时间等详细参数。

在项目中SqlMapConfig.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>
    <environments default="development">
        <environment id="development">
            <!--使用JDBC事物管理-->
            <transactionManager type="JDBC">
            </transactionManager>
            <!--数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybitas_test?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=UTC&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

但是,我们如果在使用Spring MVC框架的整合中的时候,我们将会使用Spring MVC讲练数据库的连接池,我们就不需要再为MyBatis单独配置数据库连接池了。

2、SQL映射配置文件
  • 在传统的JDBC开发模式中,SQL语句是硬编码在Java代码中的,而MyBatis框架讲SQL配置在独立的配置文件Mapper.xml文件中,作为Mapper配置文件。在这个配置文件中可以配置任何类型的SQL语句,包括select、update、delete和insert语句。
  • 对于SQL语句执行所需要的参数,以及查询语句返回的结果集对象,都可以在Mapper.xml配置文件中配置。在输入参数方面MyBatis框架会根据配置文件中的参数配置,将组装参数的Java对象或Map对象中的相关字段与Mapper.xml中的参数配置做匹配,再把相关数据绑定在需要执行的SQL语句上;在查询语句输出结果的时候,会根据Mapper.xml中配置的结果集信息,将从数据库去除的数据字段,一一映射到相应的Java对象或Map对象中。也就是说,Mapper.xml配置文件,完成了对SQL语句的输入和输出参数的映射配置

在项目中,Mapper.xml配置文件的大致内容如下:

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="test">
    <select id="findUserById" parameterType="int" resultType="cn.com.mybatis.po.User">
       select * from user where id= #{id}
    </select>

    <select id="findUser" resultType="cn.com.mybatis.po.User">
        select * from user
    </select>

</mapper>

在上诉的配置信息中,我们可以在mapper标签对中配置很对SQL语句。其中select标签对中包含了一段SQL查询的语句,其中parameterType指定了输入参数的类型,而resultType指定了输出结果映射的Java对象类型。可以看到其中的resultType的参数信息是一个JavaBean,相当于这一段select的结果参数配置表示将单挑记录映射成一个Java对象
Mapper.xml的文件路径,一般会配置在数据源配置文件SqlMapConfig.xml中,其会随着数据库配置参数一起被加载。配置方法如下:

<mappers>
        <mapper resource="config/UserMapper.xml"/>
</mappers>
3、会话工厂与会话
  • 准备好了数据库连接处配置文件SqlMapConfig.xml,以及SQL映射配置文件Mapper.xml之后,需要相关的程序来读取并加载这些配置文件的信息。而MyBatis处理这些的核心对象就是“会话工厂” 和 “会话”。
  • 在Mybatis中,“会话工厂”就是SqlSessionFactory类。工厂其实是一种会产生某种规范的对象的类的过程。SqlSessionFactory类会根据Resources资源信息加载对象,获取开发人员在项目中配置的数据库连接池配置文件SqlMapConfig.xml的信息,从而产生一种可以与数据库交互的会话实例类——SqlSession。就好像一个汽车工厂一样,给厂商一个汽车的详细配置说明书,这个厂商就可以生产出满足这个配置的汽车产品。SqlSessionFactory可以根据数据库配置信息产生出可以连接数据库并与其交互的SqlSession会话实例类。
  • 早在我们配置SqlMapConfig.xml配置文件的时候,它也加载了Mapper.xml中的SQL语句的配置信息,这样我们就可以通过产生的SqlSession会话实例类,可以依照Mapper配置文件中的SQL配置,对数据库执行增删改查的操作。
三、MyBatis运行流程

MyBatis运行流程

四、MyBatis入门程序的搭建和测试

下面我们将亲自动手来编写一个MyBatis入门工程,该工程可研对数据库的某个字段进行查询。开发步骤如下:创建工程、引入依赖jar包、搭建日志输出环境、配置数据库连接池、创建持久层Java对象、编写Mapper配置文件、编写可运行的样例代码。

1.数据库的准备

首先我们使用MySQL数据库,创建一个mybatis_test的数据库,并在其中创建一张User的表,SQL代码如下:

/*
 Navicat Premium Data Transfer

 Source Server         : localmysql
 Source Server Type    : MySQL
 Source Server Version : 80016
 Source Host           : localhost:3306
 Source Schema         : mybitas_test

 Target Server Type    : MySQL
 Target Server Version : 80016
 File Encoding         : 65001

 Date: 11/02/2020 16:15:57
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(120) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `gender` varchar(5) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `email` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `province` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `city` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `birthday` date NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '张三', '111', '男', '1111@126.com', '河南省', '郑州市', '2014-06-28');
INSERT INTO `user` VALUES (2, '李四', '222', '男', '2222@126.com', '河北省', '邯郸市', '2020-02-28');
INSERT INTO `user` VALUES (3, '刘丽', '333', '女', '3333@126.com', '江苏省', '苏州市', '2020-02-22');
INSERT INTO `user` VALUES (4, '李丽', '444', '女', '4444@126.com', '四川省', '成都市', '2020-02-16');

SET FOREIGN_KEY_CHECKS = 1;

2. 搭建工程环境

2.1、 首先打开idea创建一个web工程,命名为MyBatis_testDemo.然后导入MyBatis框架所依赖的jar包:
在这里插入图片描述
我们这里添加log4j的包,目的在于输出日志文件,以便于在开发过程中对结果问题的分析和查询。

**2.2、**然后创建一下的class和配置文件:DataConnection.java、User.java、MybatisTest.java、UserMapper.xml、SqlMapConfig.xml
在这里插入图片描述在这里插入图片描述
每一个文件内容如下:

DataConnection.java

package cn.com.mybatis.datasource;

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 DataConnection {
    private String resource="SqlMapConfig.xml";
    private SqlSessionFactory sqlSessionFactory;
    private SqlSession sqlSession;

    /**
     * 返回可以与数据库交互的SqlSession对象
     * @return
     * @throws IOException
     */
    public SqlSession getSqlSession() throws IOException{
        //获取到xml文件
        InputStream inputStream= Resources.getResourceAsStream(resource);
        //创建会话工厂 传入MyBatis配置文件信息
        sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession=sqlSessionFactory.openSession();
        return sqlSession;
    }
}

User.java

本文件建立的时候注意必须定义无参构造函数,因为mybatis框架在最开始调用的时候,调用的是无参构造函数,如果不定义无参构造函数,将报找不到有参构造函数的error

package cn.com.mybatis.po;

import java.io.Serializable;
import java.sql.Date;


public class User implements Serializable {
    private int id;
    private String username;
    private String password;
    private String gender;
    private String email;
    private String province;
    private String city;
    private Date birthday;
    public User(){  }
    public User(int id, String username, String password, String gender, String email, String province, String city, Date birthday) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
        this.gender = gender;
        this.email = email;
        this.province = province;
        this.city = city;
        this.birthday = birthday;
    }

    public int getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getEmail() {
        return email;
    }

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

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Date getBirthday() {
        return birthday;
    }

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

MybatisTest.java

此处使用单元测试功能

package cn.com.mybatis.test;


import cn.com.mybatis.datasource.DataConnection;
import cn.com.mybatis.po.User;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;

public class MybatisTest {
    public DataConnection dataConnection=new DataConnection();
//    单元测试
    @Test
    public void TestSelect() throws IOException{
        SqlSession sqlSession=dataConnection.getSqlSession();

        List<User> userList=sqlSession.selectList("test.findUser");
        for(User user:userList) {
            System.out.println("姓名: " + user.getUsername());
            System.out.println("性别: " + user.getGender());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
            System.out.println("生日" + sdf.format(user.getBirthday()));
            System.out.println("所在地 " + user.getProvince() + "/" + user.getCity());
        }
    }
}

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

<mapper namespace="test">
    <select id="findUserById" parameterType="int" resultType="cn.com.mybatis.po.User">
       select * from user where id= #{id}
    </select>

    <select id="findUser" resultType="cn.com.mybatis.po.User">
        select * from user
    </select>

</mapper>

SqlMapConfig.xml文件

注意:在使用idea的时候,&符号idea不认识,需要把&修改为&amp;即可

<?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="LOG4J"/>
    </settings>
    
    <environments default="development">
        <environment id="development">
            <!--使用JDBC事物管理-->
            <transactionManager type="JDBC">

            </transactionManager>
            <!--数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybitas_test?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=UTC&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!--Mapper-->
    <mappers>
        <mapper resource="config/UserMapper.xml"/>
    </mappers>

</configuration>

创建log4j.properties文件

log4j.rootLogger = debug,stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

在以上文件全部构建完毕后,启动单元测试:TestSelect()
在这里插入图片描述
得到的结果如下:
在这里插入图片描述
查询到所有的user表中的数据,并输出在控制台中。

今天的学习就到此结束啦,MyBatis的出现使得我们在开发项目的过程中,
对于sql代码的硬编码问题得到了较大的改善,
在以后的学习Spring MVC后,MyBatis将会更加发挥它的优势所在。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值