MyBatis 入门

本文介绍了MyBatis的基本概念、优点和执行原理,详细讲解了MyBatis的配置文件、核心配置,包括SQLSession工具类、自动扫描包自定义别名、<mappers>元素等内容,并简要提到了动态SQL和关联映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、MyBatis 简单介绍及工作原理

什么是Mybatis?Mybatis有什么用?

(1) Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement、等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。

(2) MyBatis可以使用XML或注解来配置和映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集。

(3) 通过xml文件或注解的方式将要执行的各种statement 配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis 框架执行sql并将结果映射为java对象并返回。(从执行sql 到返回result 的过程)。

Mybaits的优点


(1) 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在XML 里,解除sql 与程序代码的耦合,便于统一管理;提供XML 标签,支持编写动态SQL语句,并可重用。

(2) 与JDBC相比,减少了50%以上的代码量,消除了JDBC 大量冗余的代码,不需要手动开关连接;

(3) 很好的与各种数据库兼容(因为MyBatis 使用JDBC 来连接数据库,所以只要JDBC 支持的数据库MyBatis 都支持)。

(4) 能够与Spring 很好的集成;

(5) 提供映射标签,支持对象与数据库的ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

MyBatis的执行原理详细介绍


为了使大家能够更加清晰的理解MyBatis程序,在正式讲解MyBatis入门案例之前,先来了解一下MyBatis程序的工作原理,如下图所示。

从中可以看出,MyBatis框架在操作数据库时,大体经过了8个步骤。下面就对图中的每一步流程进行详细讲解,具体如下。

(1) 读取MyBatis配置文件mybatis-config.xml。mybatis-config.xml作为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,其中主要内容是获取数据库连接。

(2) 加载映射文件Mapper.xml。Mapper.xml文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml可以加载多个配置文件,每个配置文件对应数据库中的一张表。

(3) 构建会话工厂。通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory。

(4) 创建SqlSession对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL的所有方法。

(5) MyBatis底层定义了一个Executor接口来操作数据库,它会根据SqlSession传递的参数动态的生成需要执行的SQL语句,同时负责查询缓存的维护。

(6) 在Executor接口的执行方法中,包含一个MappedStatement类型的参数,该参数是对映射信息的封装,用来存储要映射的SQL语句的id、参数等。Mapper.xml文件中一个SQL对应一个MappedStatement对象,SQL的id即是MappedStatement的id。

(7) 输入参数映射。在执行方法时,MappedStatement对象会对用户执行SQL语句的输入参数进行定义(可以定义为Map、List类型、基本类型和POJO类型),Executor执行器会通过MappedStatement对象在执行SQL前,将输入的Java对象映射到SQL语句中。这里对输入参数的映射过程就类似于JDBC编程中对preparedStatement对象设置参数的过程。

(8) 输出结果映射。在数据库中执行完SQL语句后,MappedStatement对象会对SQL执行输出的结果进行定义(可以定义为Map和List类型、基本类型、POJO类型),Executor执行器会通过MappedStatement对象在执行SQL语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程。

上面这部分转载于mybatis看这一篇就够了,简单全面快速入门_是一只萨摩耶的博客-CSDN博客

二、MyBatis 入门程序

创建一个Java项目后

 ⑴ 导入JAR包

1. ant-1.9.6.jar

2. ant-launcher-1.9.6.jar

3. asm-5.2.jar

4. cglib-3.2.5.jar

5. commons-logging-1.2.jar

6. javassist-3.22.0-GA.jar

7. log4j-1.2.17.jar

8. log4j-api-2.3.jar

9. log4j-core-2.3.jar

10. mybatis-3.4.6.jar  核心jar包

11. mysql-connector-java-5.1.46.jar  MySQL驱动jar包

12. ognl-3.1.16.jar

13. slf4j-api-1.7.25.jar

14. slf4j-log4j12-1.7.25.jar

⑵ 配置文件

在项目的 src 目录下,创建 log4j.properties 文件,编辑后的内容如下:

# Global logging configuration
# 全局日志配置
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
# MyBatis 日志配置
log4j.logger.com.neko=TRACE
# 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

注意:在MyBatis 日志配置中 我的配置是 com.neko   

⑶ 在 src 目录下,创建一个 com.neko.po 包,再创建 User 类 

package com.neko.pojo;

public class User {
	public User(Integer id, String username, String password, String code, String nikoname,String image){
		super();
		this.id = id;
		this.username = username;
		this.password = password;
		this.code = code;
		this.nikoname = nikoname;
		this.image = image;
	}
	public User(){};
	
	private Integer id;
	private String username;
	private String password;
	private String code;
	private String nikoname;
	private String image;
	
	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;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getNikoname() {
		return nikoname;
	}
	public void setNikoname(String nikoname) {
		this.nikoname = nikoname;
	}
	public String getImage() {
		return image;
	}
	public void setImage(String image) {
		this.image = image;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", code=" + code + ", nikoname="
				+ nikoname + ", image=" + image + "]";
	}
}

⑷ 在 src 目录下,创建一个 com.neko.mapper 包,用来储存 mapper 映射文件,

<?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">
 
 <!-- namespace表示命名空间 -->
 <mapper namespace="com.neko.mapper.UserMapper">
	<!-- 根据客户编号获取客户信息 -->
	<select id="findUserById" parameterType="int" resultType="com.neko.po.User">
	  select * from tbl_user where id = #{id}
	</select>
	
	<!-- 增添数据  -->
	<insert id="addUser" parameterType="com.neko.po.User">
	   insert into tbl_user(username,password,code,nikoname,image)
	   values(#{username},#{password},#{code},#{nikoname},#{image})
	</insert>
	
    <!-- 修改数据 -->
	<update id="editUser" parameterType="com.neko.po.User">
	  update tbl_user set username=#{username},password=#{password}
	  where id=#{id}
	</update>
	
    <!-- 删除数据 -->
	<delete id="delUser" parameterType="int">
	  delete from tbl_user where id=#{id}
	</delete>
 </mapper>

⑸ 在 src 目录下,创建 MyBatis 的核心配置文件 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>
<!-- 1、配置环境,默认环境id为mysql -->
  <environments default="mysql">
    <!-- 1.1 配置环境id为mysql的数据库环境 -->
    <environment id="mysql">
      <!-- 使用JDBC事务管理 -->
      <transactionManager type="JDBC"></transactionManager>
      <!-- 数据库连接池 -->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/userdb?characterEncoding=utf8&amp;useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="root123"/>
      </dataSource>
    </environment>
  </environments>
  
  <mappers>
    <mapper resource="com/neko/mapper/UserMapper.xml"/>
  </mappers>
</configuration>

⑹ 测试,在 src 目录下,创建一个 com.neko.test 包,在该包下创建测试类,

package com.neko.test;

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

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.Test;

import com.neko.pojo.User;

public class MyBatisTest {
	private static SqlSessionFactory sf = null;
	static{
		InputStream is;
		try {
			//定义输入流读取配置文件
			is = Resources.getResourceAsStream("mybatis-config.xml");
			//根据流对象构建工厂会话
			sf = new SqlSessionFactoryBuilder().build(is);
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws IOException {

		//从工厂会话中获取会话
		SqlSession session =sf.openSession();
		//使用会话的API执行sql
		//selectOne("",3); "":根据..查询;3:查询第三条 
		User user = session.selectOne("com.neko.mapper.UserMapper.findUserById",2);
		System.out.println(user);
		
		
//		//测试添加
//		User user = new User();
//		user.setUsername("neko");
//		user.setPassword("2333");
//		user.setNikoname("会玩猫的iPhone");
//		int result = session.insert("com.neko.mapper.UserMapper.addUser", user);
//		if (result>0) {
//			System.out.println("数据插入成功");
//		}else {
//			System.out.println("执行插入失败");
//		}
//		session.commit();
		
		//关闭会话
		session.close();
	}
	
	@Test
	public void testAddUser(){
		SqlSession session = sf.openSession();
		User user = new User(0,"neko","123","ne","ne","null");
		int result = session.insert("com.neko.mapper.UserMapper.addUser", user);
		if (result>0) {
			session.commit();
		}else {
			session.rollback();
		}
		System.out.println(result);
	}
	
	@Test
	public void testDelUser(){
		SqlSession session = sf.openSession();
		int result = session.delete("com.neko.mapper.UserMapper.delUser",1 );
		if (result>0) {
			session.commit();
		}else {
			session.rollback();
		}
		System.out.println(result);
	}
	
}

 注意:在使用 MyBatis 框架时,主要涉及两个核心对象: SqlSessionFactory SqlSession 。同时为了简化开发,我们把前者封装到一个工具类中,然后通过工具类来创建 SqlSession

创建SqlSession 的工具类

package com.neko.util;

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

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 MybatisUtils {
	private static SqlSessionFactory sf = null;
	static {
		InputStream is;
		try {
			//定义输入流--读取配置文件
            is = Resources.getResourceAsStream("mybatis-config.xml");
            //根据流对象构建工厂会话
            sf = new SqlSessionFactoryBuilder().build(is);
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	/**
	 * 获取SQLSession的静态方法
	 * @return SqlSession对象
	 */
	public static SqlSession getSqlSession() {
		return sf.openSession();
	}
}

二、MyBatis 的核心配置

1 创建SQLSession 的工具类,如上:

2 配置文件  

2.1 使用自动扫描包自定义别名

<!-- 使用自动扫描包来定义别名 -->
<typeAliases>
    <package name="com.neko.po"/>
</typeAliases>

注意:上述方式的别名只适用于没有使用注解的情况。

            如果在程序中使用了注解,则别名为其注解的值,如下:

@Alias(value="customer")
public class Customer {
    //Customer 的属性和方法    

}

2.2 <environments>元素

      mybatis-config 配置文件:

<?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>
  <environments default="mysql">
    <environment id="mysql">
      <transactionManager type="JDBC"></transactionManager>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/userdb?characterEncoding=utf8&amp;useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="root123"/>
      </dataSource>
    </environment>
  </environments>
  
  <mappers>
    <mapper resource="com/neko/mapper/UserMapper.xml"/>
  </mappers>
</configuration>

 2.3 <mappers>元素

    在配置文件中,<mappers>元素用于指定 MyBatis 映射文件的位置,一般可以使用以下4种方法引入映射器文件,如下:

2.3.1 使用类路径引入(使用)

<mapper>
    <mapper resource="com.neko.mapper.CustomerMapper.xml"/>
</mapper>

2.3.2 使用本地文件路径引入

<mapper>
    <mapper url="file:///E: /src/com/neko/mapper/CustomerMapper.xml" />
</mapper>

2.3.3 使用接口类引入

<mapper>
    <mapper class="com.neko.mapper.CustomerMapper" />
</mapper>

2.3.4 使用包名引入(使用

<mapper>
    <package name="com.neko.mapper"/>
</mapper>

根据实际项目需要选取使用即可。 

下面是映射文件:

2.4 <select>元素

事例:

<select id="findCustomerById" parameterType="int" resultType="com.neko.po.Customer">
    select * from tbl_customer where id = #{id}
</select>

id:表示命名空间的唯一标识符;

parameterType:表示传入 SQL 语句的参数类的全限定名或者别名;

resultType: 从 SQL 语句中返回的类型的类的全限定名或者别名;

resultMap:表示外部 resultMap 的引用。返回时可以使用 resultTyperesultMap 

flushCathe:表示在调用 SQL 语句后,是否需要 MyBatis 清空之前查询的本地缓存和二级缓存。其值为布尔类型,默认值为 false。如果设置为 true ,则任何时候只要 SQL 语句被调用,都会清空本地缓存和二级缓存;

-------------------------------------------------------------------------------------------------------------------------

useCathe

timeOut

fetchSize

statementType

resultSetType

2.5 <insert>元素

2.6 <update>元素

2.7 <delete>元素

2.8 <sql>元素

2.9 <resultMap>元素

    <resultMap> 元素表示结果映射集,是 MyBatis 中最重要也是最强大的元素。它的主要作用是定义映射规则、级联的更新以及定义类型转换器等。

    <resultMap> 的元素结构如下:

<!-- resultMap 的元素结构 -->
<resultMap type="" id=""> <!-- type属性表示需要映射的POJO,id属性是这个resultMap 的唯一标识 -->
    <constructor> <!-- 类在实例化时,用来注入结果到构造方法中 -->
        <idArg /> <!-- ID参数;标记结果作为ID -->
        <arg /> <!-- 注入到构造方法的一个普通结果 -->
    </constructor>
    <id /> <!-- 用于表示哪个列是主键 -->
    <result /> <!-- 注入到字段或 JavaBean 属性的普通结果-->
    <association property="" /> <!--  用于一对一关联 -->
    <collection property="" /> <!--  用于一对多关联 -->
    <dsicriminattor javaType=""> <!-- 使用结果值来决定使用哪个结果映射 -->
        <case value="" /> <!-- 基于某些值的结果映射 -->
    </dsicriminattor>
</resultMap>

三、动态 SQL

四、MyBatist 的关联映射

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值