Mybatis - 学习指南一

Posted hunter-1

tags:

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

Mybatis 学习指南1-Hello Mybatis

前言

  • 传统的 JDBC 代码存在的问题。

    • 先看看一下传统 JDBC 开发的代码

      回顾一下JDBC 开发的步骤:

      1、 加载数据库驱动

      2、 创建并获取数据库链接

      3、 创建jdbc statement对象

      4、 设置sql语句

      5、 设置sql语句中的参数(使用preparedStatement)

      6、 通过statement执行sql并获取结果

      7、 对sql执行结果进行解析处理

      8、 释放资源(resultSet、preparedstatement、connection)

      // 加载驱动
      Class.forName("com.mysql.jdbc.Driver"); 
      
      // 通过驱动管理类获取数据库链接
      connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");
      
      //定义sql语句 ? 表示占位符
      String sql = "select * from user where username = ?";
      //获取预处理statement
      preparedStatement = connection.prepareStatement(sql);
      //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
      preparedStatement.setString(1, "王五");
      
      //向数据库发出sql执行查询,查询出结果集
      resultSet =  preparedStatement.executeQuery();
      
      // 结果集处理代码。。。
      // 资源释放代码。。。
      
      
    • 从上面代码起码可以获得以下结论:

      • 代码中存在大量的硬编码,因为Java是编译型语言,修改代码之后需要重新编译,这大大减低可代码的可维护性。

      • 如果需要多次执行数据操作的话,大量出现数据连接操作,造成资源浪费。

    • 从软件开发的角度讨论上面存在的问题:

      • 代码的封装性:上面由于存在大量的硬编码,导致每一次数据操作都需要编写上面重复的代码,大大降低了工作效率
      • 代码可维护性:当代码中出现大量硬编码时,在修改这些硬编码的时候就导致代码的维护性和扩展性变得很差。
    • 总结:代码中应该极力避免出现硬编码,可以用配置文件或者属性文件来代替这些硬编码。

  • Mybatis 如何解决这些问题

    • 使用properties属性文件和xml配置文件结合

    • 使用接口实现类代理对象(后面讲)Mapper

    • 数据连接池datasource

    • 动态sql

    • 结果映射resultType

    上面这些都是我们需要学习的地方,此文针对的是 Mybatis3.2.7版本


Hello Mybatis

开发的步骤

  • 确定需求:查询所有用户

  • 导入sql文件 sql文件下载

  • 创建JAVA工程

  • 新建一个Folder,一般名为lib,来存储Jar包,导入JAR包,JAR包可以在github上面下载: Mybatis下载

    • 主要有 mybatis-3.2.7.jar

    • 和lib目录下的依赖包

  • 创建Log4j属性文件,建议放在新建的SourcePackage(和src一样性质的包,编译之后会合并在一起)下,名为config

    # log4j.properties
    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
  • 在config包下创建mybatis.xml 文件

    <!-- 
      mybatis.xml
     -->
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- xml 约束
      !DOCTYPE 后面的 configuration 规定了该xml文件的根节点为configuration
     -->
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    
    <configuration>
      <!-- 第一步、导入配置数据源的属性文件mysql.properties
          resource属性:指向properties文件的相对路径
       -->
      <properties resource="mysql.properties" />
    
      <!-- 配置mybatis的环境
          environments 说明可以配置多个environment,最后根据default 属性指定使用的environment
          default对应的是environment的id属性
       -->
      <environments default="mysql-env">
          <!-- 
              The content of element type "environment" is incomplete, it must match 
              "(transactionManager,dataSource)".
              从上面的提示中可以看出,enviroment节点下必须有transactionManager 事务管理、
              dataSource 数据源两个节点
    
           -->
          <environment id="mysql-env">
              <!-- 设置事务管理器  事务有mybatis管理
                  注意:mybatis 默认不会自动提交事务,所以再进行增删改的时候需要自己提交事务
              -->
              <transactionManager type="JDBC" />
              <!-- 设置数据源
                  type:
                      POOLED :
               -->
              <dataSource type="POOLED">
                  <property name="driver" value="${jdbc.mysql.Driver}"/>
                  <property name="url" value="${jdbc.mysql.Url}"/>
                  <property name="username" value="${jdbc.mysql.Username}"/>
                  <property name="password" value="${jdbc.mysql.Password}"/>
              </dataSource>
          </environment>
      </environments>
    
    </configuration>

    上面设计到数据源属性文件mysql.properties,同样位于config包下

    # mysql.properties
    # warn:in the properties file can‘n use block after ‘=‘
    jdbc.mysql.Driver=com.mysql.jdbc.Driver
    jdbc.mysql.Url=jdbc:mysql://127.0.0.1:3306/taobao?characterEncoding=utf8
    jdbc.mysql.Username=root
    jdbc.mysql.Password=root
    
    # 注意=号后面不要跟有空格,上面英文就是这个意思,英文很渣,中式英文 =_=|
  • 创建JavaBean类 com.demo.model.User.java

    package com.demo.model;
    
    import java.io.Serializable;
    /**
     * 
    
    * <p>Title: User</p>  
    
    * <p>Description: User 实体类
    *     实体类是一个JavaBean ,以下是JavaBean的规范:
    * 
    *     <li>1、实现Serializable 接口</li>
    *     <li>2、JavaBean提供一个无参构造器。</li>
    *     <li>3、提供成员变量getter、setter方法</li>
    *     <li>4、必须是一个公共类,将其访问属性设置为public</li>
    *     <li>5、所有属性变量都应该是private的</li>
    *     
    *   为什么有这样的规范?
    *     1、为什么要实现Serializable接口?
    *         简单可以理解为便于网络传输就行。
    *     2、为什么要提供无参构造器呢?
    *         个人理解为理由有2点:
    *         a、在反射是创建对象,调用的是无参构造函数,这也是很多框架应用的。
    *         b、在继承时,JVM创建父类对象也是调用无参构造器来实现的。
    *     3、为了对象的信息的封装隐藏。
    *         
    * </p>  
    * 
    * @author Hunter_1 
    * @date 2018年7月15日
     */
    public class User implements Serializable{
    
      private Integer userId;
      private String username;
      private int age;
      private String password;
    
        //...getter...
        //...setter...
        //...toString()....
    }
    
  • 创建sql映射文件sql.xml 同样在config包下

    <?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.demo.model.User">
    
      <!-- 查询所有用户 
          注意:id一定要见名知意,后面有用。
              resultType:指明返回类型的类型
      -->
      <select id="getAllUser" resultType="com.demo.model.User">
          select user_id userId, username, age, password from user;
      </select>
    </mapper>
  • 在mybatis.xml 核心配置文件中导入sql映射配置文件

    <!-- 导入映射文件 -->
    <!-- mappers 节点是configuration的子节点 -->
    <mappers>
        <!-- 
      resource:使用相对路径
      sql.xml 和mybatis.xml 在同一个包下,相对路径就比较简单
      -->
        <mapper resource="sql.xml"/>
    </mappers>
  • 测试:编写测试类 MyTest.java

    package com.demo.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    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 com.demo.model.User;
    
    public class MyTest {
    
      public static void main(String[] args) throws Exception {
    
    
          //1、加载配置文件
          // Resources,这个类在 org.mybatis.io 包中。Resources 类正 如其名,会帮助你从类路径下, 文件系统或一个 web URL 加载资源文件。
          // Resources 是一个静态类,主要用于加载配置文件
          InputStream in = Resources.getResourceAsStream("mybatis.xml");
          //2、构建会话工厂,会话的概念可以简单的认为相当于JDBC中的Connection 
          // 注意:每个数据库对应一个 SqlSessionFactory 实例 
          SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    
          //创建回话对象, SqlSession 会话对象在Mybatis中是一个非常强大的类(目前这样理解就够)
          SqlSession session = factory.openSession();
    
          //查询
          List<User> list = session.selectList("getAllUser");
    
          /**
           * log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).
             log4j:WARN Please initialize the log4j system properly.
             log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    
             出现上面的信息说明缺少log4j的配置文件
    
          日志信息:
          DEBUG [main] - Logging initialized using ‘class org.apache.ibatis.logging.slf4j.Slf4jImpl‘ adapter.
          DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
          DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
          DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
          DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
          打开连接
          DEBUG [main] - Opening JDBC Connection
          创建连接
          DEBUG [main] - Created connection 1551870003.
          自动事务提交 为false,也就是默认事务提交是关闭的
          DEBUG [main] - Setting autocommit to false on JDBC Connection [[email protected]]
          执行sql语句
          DEBUG [main] - ==>  Preparing: select user_id userId, username, age, password from user; 
          没有参数
          DEBUG [main] - ==> Parameters: 
          查询结果为3条记录
          DEBUG [main] - <==      Total: 3
    
          从上面的日志中,我们可以看出,并没有让连接回到连接池的提示信息,那是因为没有关闭session
           */
    
          //关闭session,注意如果是增删改操作的话,在这之前还要进行事务手动提交
          session.close();
          /**
           * 关闭session之后
           *  DEBUG [main] - Resetting autocommit to true on JDBC Connection [[email protected]]
           *  关闭连接
              DEBUG [main] - Closing JDBC Connection [[email protected]]
              让连接返回连接池
              DEBUG [main] - Returned connection 1551870003 to pool.
           */
    
          for (User user : list) {
              System.out.println(user);
          }
          /** 输出;
           *  User [userId=1, username=张三丰, age=90, password=111111]
              User [userId=2, username=张无忌, age=30, password=222222]
              User [userId=3, username=张翠山, age=50, password=111111]
           */
      }
    }
    

    推荐阅读文档

    Mybatis说明文档-提取码26dr

以上是关于Mybatis - 学习指南一的主要内容,如果未能解决你的问题,请参考以下文章

mybatis学习日志二

markdown [mybatis参考]关于mybatis #mybatis的一些片段

Mybatis 学习笔记总结

Mybatis学习笔记:动态SQL

学习笔记——Mybatis逆向工程MBG;MyBatis逆向工程MBG使用步骤

动态SQL基础概念复习(Javaweb作业5)