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 [com.mysql.jdbc.JDBC4Connection@5c7fa833]
    		执行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 [com.mysql.jdbc.JDBC4Connection@5c7fa833]
    		 *  关闭连接
    			DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@5c7fa833]
    			让连接返回连接池
    			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

posted @ 2018-07-15 18:57  Hunter_1  阅读(298)  评论(0编辑  收藏  举报