天天看点

MyBatis从零开始-MyBatis入门

1. MyBatis入门

1.1 MyBatis简介

​ MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

1.2 创建Maven项目

在Eclipse中打开File->New->Other打开创建项目如下图:

MyBatis从零开始-MyBatis入门

选择Maven下的Maven Project,点击Next下一步;

MyBatis从零开始-MyBatis入门

选中Create a simple project(skip archetype selection) 点击下一步(创建一个简单的项目);

MyBatis从零开始-MyBatis入门

完成上述操作后,稍等会得到如下结构的一个Maven项目;

MyBatis从零开始-MyBatis入门

打开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.xiangty</groupId>
	<artifactId>learn-MyBatis</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>learn-MyBatis</name>
	<description>learn-MyBatis</description>
	
	<properties>
		<!-- 设置源码编译码方式UTF-8 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>
	
	<dependencies>
		<!-- 单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>

		<!-- MyBatis核心依赖 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.3.1</version>
		</dependency>

		<!-- MySQL数据库 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.38</version>
		</dependency>
		
		<!-- 日志相关 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.12</version>
		</dependency>
		
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.12</version>
		</dependency>
		
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
	</dependencies>
	
	<build>
		<plugins>
		<!-- 设置编译源代码的JDK版本,为了增大兼容范围,这里指定JDK版本1.8 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
    
</project>
           

设置pom.xml以后,选中项目,右击在Maven中选择Update Project来更新pom.xml结构中配置的外部依赖的jar包。

1.3 简单配置让MyBatis跑起来

1.3.1 准备数据库

DROP TABLE IF EXISTS `info`;
CREATE TABLE `info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(40) DEFAULT NULL,
  `password` varchar(40) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='信息表';

---------------------------------
INSERT INTO `info` VALUES ('1', 'admin', 'admin');
INSERT INTO `info` VALUES ('2', '路人甲', '123456');
INSERT INTO `info` VALUES ('3', '炮兵乙', '111111');
           

1.3.2 配置MyBatis

使用XML形式进行配置,在src/main/resources下面创建db.properties(配置数据库信息)和mybatis-config.xml配置文件;

db.properties信息:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123456
           

mybatis-config.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>

	<!-- db.properties与src/main/resources下的db.properties对应 -->
	<properties resource="db.properties"></properties>

	<settings>
		<!-- 输出LOG4J日志 -->
		<setting name="logImpl" value="LOG4J"></setting>
		<!-- 驼峰命名 -->
		<setting name="mapUnderscoreToCamelCase" value="true"></setting>
	</settings>

	<!-- 
		typeAliase配置放在xml的靠前的位置,在mybatis-config.xml文件中配置之后, 在mapper.xml文件中resultType可以只写类名 
		例: 没配置的时候,需要写成 resultType="com.xiangty.bean.Info" 配置之后,可以简写成resultType="Info"
	-->
<!-- 
	<typeAliases>
		<package name="com.xiangty.bean"></package>
	</typeAliases>
 -->	
 
 	<!-- 此处 <environment>标签可以配置多个,default="environment",是默认优先加载id="environment" -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<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>
	
	<!-- 
		映射器
		官方提供有四种方式:参考网址  "http://www.mybatis.org/mybatis-3/zh/configuration.html"
		1.使用相对于类路径的资源引用
		2.使用完全限定资源定位符(URL)
		3.使用映射器接口实现类的完全限定类名
		4.将包内的映射器接口实现全部注册为映射器
		此处用的是第一种
	-->
	<mappers>
        <!-- 此处mapper配置,是使用mapper的配置实例-->
		<mapper resource="com/xiangty/mapper/InfoMapper.xml" />
        <!-- 实际开发中xml太多,使用mapper配置的话路径太多了,可以使用package这种简洁配置 -->
		<package name="com.xiangty.mapper"/>
	</mappers>
	
</configuration>
           

1.3.3 创建实体类和Mapper.xml文件

MyBatis是一个对象关系映射框架,这里创建的实体类实际上是一个数据值对象,在实际应用中,一个表一般会对应一个实体,用于INSERT、UPDATE、DELETE和简单的SELECT。

在src/main/java下创建包com.xiangty.bean,根据数据库表info,创建实体类Info.java,代码如下:

public class Info {
	private Integer id;
	private String username;
	private String password;

	public Info(){}
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer 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;
	}
	
	@Override
	public String toString() {
		return "Info [id=" + id + ", username=" + username + ", password=" + password + "]";
	}
	
	/*
	 * 参照阿里的开发规范,集合处理
	 * 关于 hashCode 和 equals 的处理,遵循如下规则:
	 * 1) 只要重写 equals ,就必须重写 hashCode 。
	 * 2) 因为 Set存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的
	 * 对象必须重写这两个方法。
	 * 3) 如果自定义对象作为 Map 的键,那么必须重写 hashCode 和 equals 。
	 * 说明: String 重写了 hashCode 和 equals 方法,所以我们可以非常愉快地使用 String 对象作为 key 来使用。
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((username == null) ? 0 : username.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Info other = (Info) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}
	
}

           

在src/main/resources下面创建com/xiangty/mapper目录,再在该目录下面创建Info.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="com.xiangty.bean.Info">

	<!-- 
		根据id查询Info信息
		resultType的属性值简写,可以参见mybatis-config.xml文件typeAliase属性说明
		如果typeAliase属性没有做特定配置,那么这里的resultType的属性值就需要写全称
	 -->
	<select id="selectAllInfo" resultType="com.xiangty.bean.Info">
		select * from Info 
	</select>
	
</mapper>
           

< mapper >:XML的根元素,属性namespace定义了当前xml的命名空间

< select >元素:定义的一个SELECT查询。

​ id属性:定义了当前SELECT查询的唯一一个id,程序中调用的话就调用这个id的属性值;

​ resultType:定义了当前查询的返回值类型,此处指的是实体类Info。

1.3.4 配置Log4j便于查看MyBatis操作数据库的过程

log4j.rootLogger=ERROR, stdout

#MyBatis log config
log4j.logger.com.xiangty.mapper=TRACE

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

1.3.5 编写测试代码让MyBatis跑起来

src/test/java下,创建com.xiangty.test包,编写InfoTest测试类

import java.io.IOException;
import java.io.Reader;
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 org.junit.BeforeClass;
import org.junit.Test;

import com.xiangty.bean.Info;

public class InfoTest {

	private static SqlSessionFactory sqlSessionFactory;

	@BeforeClass // 必须配合static一起用
	public static void init() {
		try(Reader reader = Resources.getResourceAsReader("mybatis-config.xml");){
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		} catch (IOException e) {			
			e.printStackTrace();
		}
	}
	
	
	@Test
	public void testSelectAll(){
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			List<Info> infoList = sqlSession.selectList("com.xiangty.bean.Info.selectAllInfo");
			if (infoList != null && infoList.size() > 0) {
				infoList.forEach(info -> {
					System.out.println(info);
				});
			}
		} finally {
			sqlSession.close();
		}
	}
	
}
           

输出结果:

MyBatis从零开始-MyBatis入门

上述代码执行过程:

通过Resources工具类将mybatis-config.xml配置文件读入到Reader。

在通过SqlSessionFactoryBuilder建造类使用Reader创建SqlSessionFactory工厂对象。在创建SqlSessionFactory对象的过程中,首先解析mybatis-config.xml配置文件,读取配置文件中的mapper配置后会读取全部的Mapper.xml进行具体的方法解析,这些解析完成后,SqlSessionFactory就包含了所有的配置属性和执行SQL的信息。

使用时通过SqlSessionFactory工厂获取SqlSession。

通过SqlSession的selectList方法查找到InfoMapper.xml中的id="selectAll"的方法,执行SQL查询。

MyBatis底层使用的JDBC执行SQL,获得查询结果集ResultSet后,根据resultType的配置将结果映射到Info类的集合,返回查询结果。

注:使用完毕后一定要关闭sqlSession,避免造成过多连接没有关闭导致数据库锁或者更严重的系统异常等。

项目目前的结构:

MyBatis从零开始-MyBatis入门

系列博客目录:MyBatis从零开始博客目录

MyBatis从零开始-MyBatis入门

如果文档中有任何问题,可以直接联系我,便于我改正和进步。希望文档对您有所帮助。文档中代码GitHub地址:https://gitee.com/xiangty1/learn-MyBatis/