文档章节

MyBatis笔记(一)——带你入门带你飞

HappyBKs
 HappyBKs
发布于 2015/07/02 11:12
字数 2644
阅读 1955
收藏 102

MyBatis(原名是ibatis)简介

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

与数据库进行交互,有很多种方法或者框架:由简到繁可以排列为:

JDBC->dbutils->MyBatis->Hibernate

JDBC不用多说,最基本的Java数据库交互手段。

dbutils相对于JDBC的优势在于,它能够自动封装查询结果集,不需要操作statement或resualtset。但是,它的CRUD操作还是需要写SQL语句的。

Hibernate则完全是与对象打交道了,存一个对象的数据只需要save(object)就可以了。

而Mybaits是介于dbutils与Hibernate之间的东西。Mybatis需要写SQL语句,但是不是存放在Java代码中,而是存放在xml文件中,相当于一个中间件一样,当Java代码需要与数据库进行交互,就调用这个xml中大的SQL语句。另外,与xml并行的是,还可以使用注解来完成这个操作。

那么,既然有了Hibernate,为什么还需要Mybatis呢?很多情况下是为了避免浪费,比如一些查询,我们可以控制在我们希望的范围内。相比于dbutils,Mybatis的优势呢?Mybatis虽然不像Hibernate那样是完全围绕对象的,但是Mybatis在Java代码中操作的仍然是对象,只是需要xml中的SQL与数据库交互;而dbutils的Java代码仍然需要操作SQL。

那么接下来,我们来用一个例子梳理构建一个Mybatis应用的一般步骤:

我们希望做这样一件事情:我们在数据库中构造一个users表,在代码模块中构建一个User类,users表的字段与User的属性是完全一一对应的。现在,我们希望通过输入一个id字段或者属性值,将相应的users表中的记录行查询出来并自动封装成User对象。那么,现在的问题就是如何形成这种代码区的对象与数据库表的映射,以及如何在此基础上构建一个我们需要的查询服务。这就需要我们的Mybatis。

(本文出自:http://my.oschina.net/happyBKs/blog/473255)

环境与项目的搭建:

为了方便,我使用的IDE是STS,项目用的是Maven的quickstart项目。

首先,我们需要导入相应的jar。包括mybatis的和mysql driver。

pom.xml如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.happyBKs.mybatis</groupId>
  <artifactId>C1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>C1</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>

	<dependency>
		<groupId>org.mybatis</groupId>
		<artifactId>mybatis</artifactId>
		<version>3.3.0</version>
	</dependency>


	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>5.1.35</version>
	</dependency>
    
  </dependencies>
</project>

然后,加入一个源文件文件夹,命名为src/main/resources,为的是以后存放项目中的各种配置文件和资源文件。

最后,我们把数据库搭建好。我用的是mysql-5.6.25,用bin下的mysqld命令登录。

bin> mysqld -u root

这里我是默认的设置,用户名root,密码为空。


构建Mybatis程序的基本步骤:

1.数据库建表users,并插入数据。

create database mybatis;
use mybatis;
CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20), age INT);
INSERT INTO users(NAME, age) VALUES('Tom', 12);
INSERT INTO users(NAME, age) VALUES('Jack', 11);

happyBKs很希望根红苗正的mysql workbench。在那里操作吧。


2. 添加Mybatis的配置文件config.xml

这个文件是mybatis的核心配置文件,包含了数据库配置信息,如driver名称、数据库url、用户名和密码等;还包含了我们刚才提到的映射的构建,也是在这里把所有的映射文件罗列出来。

在实际使用时,我们需要先行加载这里文件,所以可谓是整个,Mybatis的项目配置文件的树干部分。

在这个项目中,我将config.xml放到了src/main/resources文件夹下。

这里,我们先只进行数据库配置,映射配置等会儿再说。

<?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>
<!-- 
development: 开发模式
work: 工作模式
 -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="" />
			</dataSource>
		</environment>
	</environments>
</configuration>

值得一提的是,这里的evironments或environment可以有两种模式:

development: 开发模式

work: 工作模式

区别这里不说,影响不大。但是请注意,无论你选择哪一种模式,请让evironments或environment的模式保持统一,否则要出问题的哦。


3. 定义表所对应的实体类

这里我们构建一个与users表对应的类User。

package com.happyBKs.mybatis.C1;

public class User {
	private int id;
	private String name;
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public User(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public User() {
		super();
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
	}

}
//shift+alt+s, 谁用谁知道

这里差一个题外话,为了给初学者们一个提醒,高手们是如何写bean类定义的,果断shift+alt+s。


4. 定义操作users表的sql映射文件userMapper.xml

这里应该是最核心的部分了,怎么把类与表关联;如何写一个服务,如按id查询。

<?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.happyBKs.mybatis.C1.userMapper"> 
	<!-- 根据id查询对象 -->
	<select id="getUser" parameterType="int" resultType="com.happyBKs.mybatis.C1.User">
		select * from users where id=#{id}
	</select>
</mapper>

构建一个映射,就是要构建一个mapper节点并配置。mapper需要一个唯一性的标识,就是namespace属性,这里给出一种比较常用的命名规范,用User类的包名 + 这个映射文件的文件名。这里文件名的命名规范是,类名首字母小写+Mapper。当然这只是一种习惯或者规范,你当然也可以命名成其他形式,只要能保证其唯一性。

然后,如何把类与表关联起来呢?Mybatis没有像Hibernate那样,在配置文件中将数据库名和类名、数据库字段和类属性直接对应着配置建立映射。Mybatis是直接在构建服务的过程中将类名和表包含其中:构建一个查询服务,要用到select节点,User类名在select的resultType中被指定;表明这是在select节点内容的SQL查询语句中被写明。所以,Mybatis与Hibernate相比,并不能是一种映射结构清楚、映射程度完全的解决方案,但是Mybatis也的确很灵活和方便,我们可以自己定制SQL语句,并且也完成了类与表在服务上的映射关系。

好吧,我们还是看看这个服务吧。

select标签中我们指定了三个属性。服务的id,这个和users表中的id字段没有任何关系。select的id是用来标识这个服务的名称,我们在后面调用服务的时候会用到,当然它要求命名唯一。parameterType标识输入参数的类型,这里我们是按users的id字段进行查询,所以这里的参数类型指的就是users的id字段类型。在select节点的SQL语句中,我们用通配符来标识这个参数#{id}。resultType用来标识服务的返回结果的类型,是一个User类的对象。


5. 在config.xml文件中注册userMapper.xml文件

所有的映射文件需要统一在mybatis的配置文件config.xml中注册。方法就是构建一个mappers节点,然后为每个映射文件构建一个mapper节点。

<?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>
<!-- 
development: 开发模式
work: 工作模式
 -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- 在conf.xml文件中注册userMapper.xml文件 -->
	<mappers>
		<mapper resource="com/happyBKs/mybatis/C1/userMapper.xml"/>
	</mappers>

</configuration>



6. 测试程序:

好吧,我们来调用看看吧。

这里我给出两段测试代码,功能一样。第二个比较推荐,因为家在配置文件config.xml时使用了类加载器。

大致思路是:

我需要一个Session,它接收一个statement和一个参数来完成查询。

statement如何是描述服务的,怎么描述呢。就是要用到我们刚才usrMapper.xml映射文件中定义的命名空间 + select服务标签的id内容,这样就标记出来了唯一性的服务,他可是包含了SQL语句和类与表映射关系的哦。

那么,session从哪来,用SqlSessionFactory对象造出来。

那么,SqlSessionFactory从哪来,用SqlSessionFactoryBuilder来build出来。好吧,这里构造一个SqlSessionFactory对象,需要指定数据库配置等信息,那么很自然的需要在build方法中提供mybaitis的config.xml配置文件的内容。这里提供配置文件config.xml内容的方式是传入一个InputStream。

所以一开始就需要构建一个config.xml的InputStream对象。

package com.happyBKs.mybatis.C1;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;


public class App 
{
    public static void main( String[] args )
    {
		test2();

    }

	private static void test1() throws IOException {
		String resource = "config.xml"; 
		//加载mybatis的配置文件(它也加载关联的映射文件)
		Reader reader = Resources.getResourceAsReader(resource); 
		//构建sqlSession的工厂
		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
		//创建能执行映射文件中sql的sqlSession
		SqlSession session = sessionFactory.openSession();
		//映射sql的标识字符串
		String statement = "com.happyBKs.mybatis.C1.userMapper"+".getUser";//先找映射文件,后找标签
		//执行查询返回一个唯一user对象的sql
		User user = session.selectOne(statement, 1);
		System.out.println(user);
	}
	
	private static void test2()
	{
		String resource = "config.xml"; 
		//用类加载器加载mybatis的配置文件
		
		InputStream inputStream=App.class.getClassLoader().getResourceAsStream(resource);
		
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession session = factory.openSession();
		
		String statement = "com.happyBKs.mybatis.C1.userMapper"+".getUser";//先找映射文件,后找标签
		User user = session.selectOne(statement,2);//根据id查,这里id为2
		//类型不需要强转,强大吧
		System.out.println(user);
	}
}


好吧,最后看看结果。


© 著作权归作者所有

HappyBKs

HappyBKs

粉丝 665
博文 306
码字总数 481268
作品 0
浦东
程序员
私信 提问
加载中

评论(5)

i
itxx2016
推荐国内最流行的ibatis、mybatis代码生成网站: fwjava.com
无需任何安装配置,直接在线生成,且十分规范好用.
现在,很多知名的互联网公司都在用它.
haizhi8911
haizhi8911
重新梳理一番
HappyBKs
HappyBKs 博主

引用来自“maosi”的评论

单词错了,两处“evvironments”
看得好仔细,改好了
maosi
maosi
单词错了,两处“evvironments”
五杀联盟
五杀联盟
Mybatis太麻烦 有办法吗
4月25日云栖精选夜读:阿里巴巴CEO张勇:“有种乡愁叫淘宝”

“有种乡愁叫淘宝。” 4月24日,阿里巴巴集团CEO张勇在澳大利亚举办的“阿里之夜”上,对着台下2400名从各地赶来的华人听众、澳洲商家、生态合作伙伴说。据悉,此次阿里巴巴举办的活动,所有...

Mr_zebra
2018/04/26
12
0
飞特商城微服务发布 dubbo 2.0.3 分支,从放弃到入门

昨天是10.24 程序员的节日,给自己放假,今天要忙碌上线。 飞特,自由职业者,程序猿接私活利器,取之开源,用之开源。 新特性 如果你未接触微服务,希望飞特带你快速入门微服务。如果你有过...

18356087258
2018/10/25
2.2K
2
8月30日云栖精选夜读 | 谈谈“野生”Java程序员学习的道路!

一、引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来。LZ自己当初面试完以后,除了记住一些聊过的...

yq传送门
2018/08/30
0
0
MyBatis多对多保存示例——MyBatis学习笔记之十七

前几天有网友问到MyBatis多对多的问题,不过愧对网友厚爱的是,最近一直忙,直到现在才有时间处理此事。今天就先写一个多对多保存的示例,算是对这位网友的初步回应,以后会有更多相关的博文...

NashMaster2011
2013/08/11
0
0
如何在MyBatis-3.2.7中使用Log4j2 rc2——MyBatis学习笔记之十九

前天我上传了我的MyBatis系列课程(http://edu.51cto.com/course/course_id-1110.html)的第六讲,主要内容是如何使用Log4j2(具体版本为v2.0-rc1)为MyBatis 3.2.7配置日志。实际上目前最新...

NashMaster2011
2014/07/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

golang-字符串-地址分析

demo package mainimport "fmt"func main() {str := "map.baidu.com"fmt.Println(&str, str)str = str[0:5]fmt.Println(&str, str)str = "abc"fmt.Println(&s......

李琼涛
今天
4
0
Spring Boot WebFlux 增删改查完整实战 demo

03:WebFlux Web CRUD 实践 前言 上一篇基于功能性端点去创建一个简单服务,实现了 Hello 。这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD WebFlux 应用,让开发更方便。这里...

泥瓦匠BYSocket
今天
6
0
从0开始学FreeRTOS-(列表与列表项)-3

FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像。 在FreeRTOS中,列表与列表项使用得非常多,是FreeRTOS的一个数...

杰杰1号
今天
8
0
Java反射

Java 反射 反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的 Class,Class 类 用于表示.class 文件(字节码)) 一、反射的概述 定义:JAVA 反射机制是在运行状态中,对于任...

zzz1122334
今天
5
0
聊聊nacos的LocalConfigInfoProcessor

序 本文主要研究一下nacos的LocalConfigInfoProcessor LocalConfigInfoProcessor nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/LocalConfigInfoProcessor.java p......

go4it
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部