MyBatis配置文件和简单使用

 MyBatis-01-mybatis配置文件和简单使用

一. MyBatis简介

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(sDAO)

下载地址: MyBatis下载地址

使用版本:3.4.5

1.简介

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录

2. 背景介绍

MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手共设置以及结果集的检索,MyBatis使用简单的XML或者注解用于配置和原始映射,将接口和Java的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。

每个MyBatis应用程序主要利用SqlSessionFactory实例操作数据库,而SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类实例获得。

用xml文件构建SqlSessionFactory实例是非常简单的事情,推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或者f://开头的url创建实例。MyBatis有一个实用类(Resources),它有很多方法,可以方便地从类路径以及其他位置加载资源。

3.框架特点
  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
  • 解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql
4. 总体流程
  1. 加载配置并初始化

​ 触发条件:加载配置文件

​ 处理过程:将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

  1. 接收调用请求

​ 触发条件:调用Mybatis提供的API

​ 传入参数:为SQL的ID和传入参数对象

​ 处理过程:将请求传递给下层的请求处理层进行处理。

  1. 处理操作请求

​ 触发条件:API接口层传递请求过来

​ 传入参数:为SQL的ID和传入参数对象

​ 处理过程:

​ (A)根据SQL的ID查找对应的MappedStatement对象。

​ (B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。

​ (C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。

​ (D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。

​ (E)释放连接资源。

  1. 返回处理结果将最终的处理结果返回
5. 功能架构

Mybatis的功能架构分为三层:

  • API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

  • 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

  • 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

6. 体系结构

mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的 信息。

  • mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
  • 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
  • SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
  • Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型。
7. MyBatis和数据交互的方式

​ MyBatis和数据库交互方式主要分两种:

  • 使用传统的MyBatis提供的API;
  • 使用Mapper接口;
7.1 使用传统的MyBatis API

​ 通过调用MyBatis中SqlSession对象的方法从而达到与数据库交互的方式,有一些类似DBUtils的操作!

上述使用MyBatis的方法,是创建一个和数据库打交道的SqlSession对象,然后根据Statement Id 和参数来操作数据库,这种方式固然很简单和实用,但是它不符合面向对象语言的概念和面向接口编程的编程习惯。由于面向接口的编程是面向对象的大趋势,MyBatis为了适应这一趋势,增加了第二种使用MyBatis 支持接口(Interface)调用方式。

7.2 使用Mapper接口

MyBatis将核心配置文件中的每一个节点抽象为一个 Mapper 接口,而这个接口中声明的方法和跟节点中的节点项对应,即 节点的id值为Mapper接口中的方法名称,parameterType值表示Mapper对应方法的入参类型,而resultMap 值则对应了Mapper接口表示的返回值类型或者返回结果集的元素类型。

根据MyBatis的配置规范配置好后,通过SqlSession.getMapper(XXXMapper.class) 方法,MyBatis会根据相应的接口声明的方法信息,通过动态代理机制生成一个Mapper实例,我们使用Mapper接口的某一个方法时,MyBatis会根据这个方法的方法名和参数类型,确定Statement Id,底层还是通过SqlSession.select("statementId",parameterObject);或者SqlSession.update("statementId",parameterObject);等等来实现对数据库的操作,

MyBatis引用Mapper接口这种调用方式,纯粹是为了满足面向接口编程的需要。(其实还有一个原因是在于,面向接口的编程,使得用户在接口上可以使用注解来配置SQL语句,这样就可以脱离XML配置文件,实现“0配置”)。

#####8.MyBatis配置文件

######8.1. 核心配置文件

​ 在classpath下,创建SqlMapConfig.xml文件,该文件为核心配置文件,可以配置当前环境信息,加载映射文件,加载properties文件,配置全局参数,定义别名等。

xml version="1.0" encoding="UTF-8" ?>

<configuration>

	
	<properties resource="jdbc.properties">
		<property name="jdbc.password" value="12345"/>
	properties>
	
	
	
	
	<typeAliases>
		
		
		
		<package name="com.qf.domain"/>
	typeAliases>
	
	
	<environments default="development">
		<environment id="development">
			
			<transactionManager type="JDBC">transactionManager>
			
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			dataSource>
		environment>
	environments>
	
	
	<mappers>
		
		<mapper resource="User.xml"/>
		
		
		
		 
		 
		 
		 
		 <package name="com.qf.mapper"/>
	mappers>
configuration>

######8.2 映射文件

​ 在指定的目录下创建映射文件,配置要执行的statement,即增删改查等语句。

xml version="1.0" encoding="UTF-8"?>


<mapper namespace="test">

	
	<select id="findById" parameterType="int" resultType="com.qf.domain.User" >
		select * from user where id=#{id}
	select>
	
	
	 
	 <select id="findByUsername" parameterType="java.lang.String"
	 	resultType="com.qf.domain.User">
	 	select * from user where username like '%${value}%'	
	 select>
	 
	 
	  <insert id="addUser" parameterType="com.qf.domain.User">
	  	
	  	
	  	<selectKey keyProperty="id" resultType="int" order="AFTER">
	  		select last_insert_id()
	  	selectKey>
	  
	  	insert into user(username,sex,birthday,address)
	  		values(#{username},#{sex},#{birthday},#{address})
	  insert>
	  
	 
	 
	  <delete id="deleteUser" parameterType="int">
	  	delete from user where id=#{id}
	  delete>
	  
	  
	  
	  <update id="updateUser" parameterType="com.qf.domain.User">
	  	update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address}
			where id= #{id}
	  update>
mapper>

二、MyBatis基本应用

1、搭建MyBatis技术环境

1.1、环境准备

  • Jdk环境:jdk1.8
  • Ide环境:eclipse oxygen
  • 数据库环境:MySQL 5.1
  • Mybatis:3.4.5

1.2、下载MyBatis

mybaits的代码由github.com管理,下载地址:https://github.com/mybatis/mybatis-3/releases

Mybatis-3.4.5.jar:mybatis的核心包

Mybatis-3.4.5.pdf:mybatis的使用指南

1.3、数据库准备

CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL COMMENT '商品名称',
  `price` float(10,1) NOT NULL COMMENT '商品定价',
  `detail` text COMMENT '商品描述',
  `pic` varchar(64) DEFAULT NULL COMMENT '商品图片',
  `createtime` datetime NOT NULL COMMENT '生产日期',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;


CREATE TABLE `orderdetail` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `orders_id` int(11) NOT NULL COMMENT '订单id',
  `items_id` int(11) NOT NULL COMMENT '商品id',
  `items_num` int(11) DEFAULT NULL COMMENT '商品购买数量',
  PRIMARY KEY (`id`),
  KEY `FK_orderdetail_1` (`orders_id`),
  KEY `FK_orderdetail_2` (`items_id`),
  CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;


CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '下单用户id',
  `number` varchar(32) NOT NULL COMMENT '订单号',
  `createtime` datetime NOT NULL COMMENT '创建订单时间',
  `note` varchar(100) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;


CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` date DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性别',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

1.4、数据准备

insert  into `items`(`id`,`name`,`price`,`detail`,`pic`,`createtime`) values (1,'台式机',3000.0,'该电脑质量非常好!!!!',NULL,'2015-02-03 13:22:53'),(2,'笔记本',6000.0,'笔记本性能好,质量好!!!!!',NULL,'2015-02-09 13:22:57'),(3,'背包',200.0,'名牌背包,容量大质量好!!!!',NULL,'2015-02-06 13:23:02');

insert  into `orderdetail`(`id`,`orders_id`,`items_id`,`items_num`) values (1,3,1,1),(2,3,2,3),(3,4,3,4),(4,4,2,3);

insert  into `orders`(`id`,`user_id`,`number`,`createtime`,`note`) values (3,1,'1000010','2015-02-04 13:22:35',NULL),(4,1,'1000011','2015-02-03 13:22:41',NULL),(5,10,'1000012','2015-02-12 16:13:23',NULL);

insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'王五',NULL,'2',NULL),(10,'张三','2014-07-10','1','北京市'),(16,'张小明',NULL,'1','河南郑州'),(22,'陈小明',NULL,'1','河南郑州'),(24,'张三丰',NULL,'1','河南郑州'),(25,'陈小明',NULL,'1','河南郑州'),(26,'王五',NULL,NULL,NULL);

2、获取SqlSession对象

MyBatis框架中涉及到的几个API

  • SqlSessionFactoryBuilder:该对象负责根据MyBatis配置文件SqlMapConfig.xml构建SqlSessionFactory实例
  • SqlSessionFactory:每一个MyBatis的应用程序都以一个SqlSessionFactory对象为核心。该对象负责创建SqlSession对象实例。
  • SqlSession:该对象包含了所有执行SQL操作的方法,用于执行已映射的SQL语句
//1、读取配置文件
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//2、根据配置文件创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3SqlSessionFactory创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();

3、利用SqlSession实现CRUD操作

3.1、新增操作

​ 在映射文件配置标签,用于执行插入操作。

​ 在插入操作完成之前或之后,可以配置标签获得生成的主键的值,获得插入之前还是之后的值,可以通过配置order属性来指定。

​ LAST_INSERT_ID:该函数是mysql的函数,获取自增主键的ID,它必须配合insert语句一起使用


     
     
     
     
<insert id="addUser" parameterType="com.qf.po.User>

id" resultType="int" order="AFTER">
	SELECT LAST_INSERT_ID() 
selectKey>

INSERT INTO USER(username,birthday,sex,address)
        VALUES(#{username},#{birthday},#{sex},#{address})
insert>	

​ 测试代码如下,直接执行配置的statement,可以查看结果。

SqlSession session = sqlSessionFactory.openSession();
session.insert("test.addUser",user);
session.commit();

3.2、删除操作

​ 在映射文件文件中使用标签配置删除的statement。

<delete id="deleteUser" parameterType="int">
	  	delete from user where id=#{id}
delete>

​ 测试代码如下,直接执行配置的statement,可以查看结果。

SqlSession session = sqlSessionFactory.openSession();
session.delete("test.deleteUser",1);
session.commit();

3.3、修改操作

​ 在映射文件使用标签配置修改的statement。

<update id="updateUser" parameterType="com.qf.domain.User">
	  	update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address}  where id= #{id}
update>

​ 测试代码如下,直接执行配置的statement,可以查看结果。

 //构建user参数,没有赋值的属性采取默认值
    User user = new User();
    user.setId(20);
    user.setUsername("admin");
    user.setAddress("beijing");
      
    // 第一个参数:statementid,建议:namespace.statementId(确保唯一)
    // 第二个参数:入参的值,它的类型要和映射文件中对应的statement的入参类型一致
    sqlSession.update("test.updateUser", user);

3.4、查询操作

​ 在映射文件配置