Mybatis入门案例讲解

Mybatis入门案例讲解

目 录

  1. MyBatis概述
  2. MyBatis下载与安装
  3. MyBatis的工作原理
  4. MyBatis的增删改查
  5. 使用resultMap属性映射查询结果
  6. 使用Mapper接口执行SQL

MyBatis概述

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

与持久层框架Hibernate对比

  • Hibernate较深度的封装了JDBC,对开发者编写SQL的能力要求不高,只要通过SQL语句操作对象即可完成对数据库持久化的操作。另外Hibernate的可移植性好,如一个项目开始使用的是MySQL数据库,现在决定使用Oracle数据库,由于不同的数据库使用SQL的标准还是有差距的,因此手动修改会存在很大的困难,而使用Hibernate只需改变一下数据库方言即可。使用Hibernate框架,数据库的移植变得非常方便。但是Hibernate也存在诸多的不足,比如在实际开发中会生成很多不必要的SQL语句耗费程序资源,优化起来也不是很方便,且对存储过程的支持也不够强大。

  • Mybatis也是对JDBC的封装,但是封装得没有Hibernate那么深,通过在配置文件中编写SQL语句,可以根据需求定制SQL语句,数据优化起来比Hibernate容易的多。但Mybatis要求程序员编写SQL的能力要比Hibernate高,且可移植性也不是很好。涉及大数据的系统使用Mybatis比较好,因为优化方便。涉及数据量不大且优化要求不高的系统,可以使用Hibernate。

MyBatis下载与安装

  • 通过官方网站https://github.com/mybatis/mybatis-3/releases下载MyBatis的最新版本mybatis-3.4.6.zip 。
  • 通过CSDN下载 https://download.csdn.net/download/qq_22075913/12842080
  • MyBatis压缩包的文件结构

在这里插入图片描述

MyBatis的工作原理

  • MyBatis框架的执行流程图
    在这里插入图片描述

使用MyBatis操作数据库时,大致经过以下步骤。

(1) 读取MyBatis配置文件mybatis-config.xml

  • mybatis-config.xml是Mybatis的全局配置文件,名称不固定。该文件中配置了数据源、事务等Mybatis运行环境。

(2) 加载映射文件mapper.xml

  • mapper.xml是SQL映射文件,该文件中定义了数据库操作的SQL语句,需要在mybatis-config.xml文件中加载。

(3) 创建会话工厂

  • 根据Mybatis的配置文件创建会话工厂SqlSessionFactory。

(4) 创建会话

  • 通过会话工厂SqlSessionFactory创建SqlSession对象,该对象提供了执行SQL的所有方法。

(5) 通过Executor操作数据库

  • Executor是Mybatis的一个核心接口,它与SqlSession绑定在一起,每个SqlSession都有一个新的Executor对象,由Configuration创建。SqlSession内部通过执行器操作数据库,增删改语句通过Executor接口的update方法执行,查询语句通过query方法执行。

(6) 输入参数和输出结果的映射

  • 在执行SQL语句前,Executor执行器通过MappedStatement对象,将传入的Java对象映射到SQL语句中。在执行SQL语句后,MappedStatement对象将执行结果映射到Java对象。

MyBatis的增删改查

  • 在Java或JavaWeb项目中添加MyBatis必需的核心包,就能对数据表进行增删改查操作了。下面以MySQL数据库eshop中的数据表user_info为例,使用MyBatis实现数据的增删改查。
  1. 根据用户编号查询用户
    实现步骤:
    1)新建名为mybatis1的JAVA项目,新建lib文件夹,添加jar包
    2)复制Mybatis jar包和Mysql jar包到项目中

在这里插入图片描述3) 创建实体类UserInfo

package com.mybatis.pojo;

public class UserInfo {
  private int id;
  private String userName;
  private String password;
  private String realName;
  private String sex;
  private String address;
  private String email;
  private String regDate;
  private int status;
public int getId() {
	return id;
}
public void setId(int 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 getRealName() {
	return realName;
}
public void setRealName(String realName) {
	this.realName = realName;
}
public String getSex() {
	return sex;
}
public void setSex(String sex) {
	this.sex = sex;
}
public String getAddress() {
	return address;
}
public void setAddress(String address) {
	this.address = address;
}
public String getEmail() {
	return email;
}
public void setEmail(String email) {
	this.email = email;
}
public String getRegDate() {
	return regDate;
}
public void setRegDate(String regDate) {
	this.regDate = regDate;
}
public int getStatus() {
	return status;
}
public void setStatus(int status) {
	this.status = status;
}
@Override
public String toString() {
	return "UserInfo [id=" + id + ", userName=" + userName + ", 
	password=" + password + ", realName=" + realName+ ", sex=" + sex + ",
	 address=" + address + ", email=" + email + ", 
	 regDate=" + regDate + ", status="+ status + "]";
}
public UserInfo(int id, String userName, String password, String realName, 
String sex, String address, String email,
		String regDate, int status) {
	this.id = id;
	this.userName = userName;
	this.password = password;
	this.realName = realName;
	this.sex = sex;
	this.address = address;
	this.email = email;
	this.regDate = regDate;
	this.status = status;
}
public UserInfo() {
}
}

4)创建SQL映射的XML文件

UserInfoMapper.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.mybatis.mapper.UserInfoMapper">
 <!-- 根据用户编号查询用户 -->
 <select id="findUserInfoById" parameterType="int" resultType="UserInfo">
   select *from user_info where id=#{id}
 </select>
</mapper>

5)创建属性文件db.properties

# jdbc.driver=com.mysql.jdbc.Driver
jdbc.driver=com.mysql.cj.jdbc.Driver #数据库驱动名
jdbc.url=jdbc:mysql://localhost:3306/eshop?serverTimezone=UTC #数据库Url
jdbc.username=root #数据库用户名
jdbc.password=root #指定用户密码

6)创建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>
 <!-- 加载属性文件 -->
 <properties resource="db.properties"></properties>
 <!-- 给包中的类注册别名,不用在类名前加包名 -->
 <typeAliases>
 	<package name="com.mybatis.pojo"></package>
 </typeAliases>
 <!-- 配置环境 -->
 <environments default="development">
	 <environment id="development">
	     <!-- 使用JDBC事务 -->
		 <transactionManager type="JDBC"></transactionManager>
		 <!-- 指定数据源 POOLED数据库连接池 -->
		 <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="com/mybatis/mapper/UserInfoMapper.xml"></mapper>
 </mappers>
 </configuration>

7)创建测试类

package com.mybatis.test;
import static org.junit.jupiter.api.Assertions.*;
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.After;
import org.junit.Before;
import org.junit.Test;
import com.mybatis.pojo.UserInfo;

public class MybatisTest {
	
	private SqlSessionFactory sqlSessionFactory;
	private SqlSession sqlSession;
	
    //初始化方法
	@Before
	public void init() {
		//读取mybatis配置文件
		String resource="mybatis-config.xml";
		InputStream inputStream;
		try {
			//得到配置文件流
			inputStream=Resources.getResourceAsStream(resource);
			//根据配置文件信息,创建会话工厂
			sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
			//通过工厂得到session
			sqlSession=sqlSessionFactory.openSession();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//根据id查询用户
	@Test
	public void testFindById() {
		//通过sqlSession执行映射文件中定义的sql并返回结果
		UserInfo ui=sqlSession.selectOne("findUserInfoById",1);
	    System.out.println(ui);
	}
    @After
	public void destroy() {
    	//提交事务
    	sqlSession.commit();
    	//关闭sqlSession
    	sqlSession.close();
	}
}

8)测试结果
在这里插入图片描述
在这里插入图片描述
9)项目结构如下
在这里插入图片描述10)SQL语句

/*
SQLyog v10.2 
MySQL - 5.5.27 : Database - eshop
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`eshop` /*!40100 DEFAULT CHARACTER SET gbk */;

USE `eshop`;

DROP TABLE IF EXISTS `user_info`;

CREATE TABLE `user_info` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `userName` varchar(16) DEFAULT NULL,
  `password` varchar(16) DEFAULT NULL,
  `realName` varchar(8) DEFAULT NULL,
  `sex` varchar(4) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `regDate` date DEFAULT NULL,
  `status` int(4) DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `user_info` */

insert  into `user_info`(`id`,`userName`,`password`,`realName`,`sex`,`address`,`email`,`regDate`,`status`) 
values (1,'tom','123456','汤姆','女','江苏省苏州市吴中区','tom@123.com','2013-07-14',1),
(2,'john','123456','约翰','女','江苏省南京市玄武区','wen@135.com','2013-07-14',1),
(3,'my','123456','my','男','江苏省南京市玄武区','a@135.com','2015-09-16',1),
(4,'sj','123456','sj','男','江苏省南京市玄武区','b@135.com','2015-09-16',1),
(5,'lxf','123456','lxf','男','江苏省南京市玄武区','c@135.com','2015-09-16',1),
(6,'lj','123456','lj','男','江苏省南京市玄武区','a@135.com','2015-09-20',1);

根据用户名模糊查询用户

实现步骤:

1)在映射文件UserInfoMapper.xml中,添加根据用户名模糊查询用户的SQL语句,如下所示

<!-- 根据用户名模糊查询用户 -->
 <select id="findUserInfoByName" parameterType="String" resultType="UserInfo">
  select *from user_info where userName like 
  CONCAT(CONCAT('%',#{userName}),'%')
 </select>

2)在测试类MybatisTest中,添加一个测试方法testFindByName,代码如下

//根据用户名模糊查询
	@Test
	public void testFindByName() {
		//通过sqlSession执行映射文件中定义的sql并返回结果
		List<UserInfo> ulist=sqlSession.selectList("findUserInfoByName","m");
	    for(UserInfo u:ulist) {
	    	System.out.println(u);
	    }
	
	}

3)运行测试方法testFindByName,结果如下

在这里插入图片描述
添加用户

实现步骤:

1)在映射文件UserInfoMapper.xml中,添加用户的SQL语句,如下所示

<!-- 添加用户 -->
 <insert id="addUserInfo" parameterType="UserInfo">
 insert into user_info(userName,password) values(#{userName},#{password})
 </insert>

2)在测试类MybatisTest中,添加一个测试方法testAddUserInfo,代码如下

//添加用户
	@Test 
	public void testAddUserInfo() {
		//创建UserInfo对象
		UserInfo userInfo=new UserInfo();
		userInfo.setUserName("paul");
		userInfo.setPassword("6666");
		int result=sqlSession.insert("addUserInfo",userInfo);
		if(result>0) {
			System.out.println("插入成功");
		}else {
			System.out.println("插入失败");
		}
	}

3)运行测试方法testAddUserInfo,结果如下

在这里插入图片描述

在这里插入图片描述修改用户

实现步骤:

1)在映射文件UserInfoMapper.xml中,修改用户的SQL语句,如下所示

<!-- 修改用户 -->
 <update id="updateUserInfo" parameterType="UserInfo">
  update user_info set userName=#{userName},password=#{password} where id=#{id}
 </update>

2)在测试类MybatisTest中,添加一个测试方法testAddUserInfo,代码如下

//修改用户
	@Test
	public void testUpdateUserInfo() {
		//加载编号为7的用户
		UserInfo ui=sqlSession.selectOne("findUserInfoById", 7);
		ui.setUserName("henry");
		ui.setPassword("22222");
		int result=sqlSession.update("updateUserInfo", ui);
		if(result>0) {
			System.out.println("更新成功");
		}else {
			System.out.println("更新失败");
		}
	}
	

3)运行测试方法testUpdateUserInfo,结果如下
在这里插入图片描述
删除用户

实现步骤:

1)在映射文件UserInfoMapper.xml中,删除用户的SQL语句,如下所示

<!-- 删除用户 -->
 <delete id="deleteUserInfo" parameterType="int">
 delete from user_info where id=#{id}
 </delete>

2)在测试类MybatisTest中,添加一个测试方法testAddUserInfo,代码如下

	//删除用户
	@Test
	public void testDeleteUserInfo() {
		//通过sqlSession执行映射文件中定义的sql并返回结果
		int result=sqlSession.delete("deleteUserInfo", 7);
		if(result>0) {
			System.out.println("删除成功");
		}else {
			System.out.println("删除失败");
		}
	}

3)运行测试方法testDeleteUserInfo,结果如下

在这里插入图片描述

使用resultMap属性映射查询结果

  • 在上述示例中,实体类UserInfo中的属性名与数据表user_info中的字段名相同,如果属性名与数据表的字段名不相同,那么就需要使用resultMap属性来进行结果集的映射。

实现步骤:

1)将项目mybatis1复制并命名为mybatis2,再导入eclipse中

2)修改实体类UserInfo.java,将其属性重新命名,使得属性名与数据表user_info的字段名不同
这里修改uid,uname,upass

package com.mybatis.pojo;

public class UserInfo {
  private int uid;
  private String uname;
  private String upass;
  private String realName;
  private String sex;
  private String address;
  private String email;
  private String regDate;
  private int status;

public int getUid() {
	return uid;
}
public void setUid(int uid) {
	this.uid = uid;
}

public String getUname() {
	return uname;
}
public void setUname(String uname) {
	this.uname = uname;
}
public String getUpass() {
	return upass;
}
public void setUpass(String upass) {
	this.upass = upass;
}
public String getRealName() {
	return realName;
}
public void setRealName(String realName) {
	this.realName = realName;
}
public String getSex() {
	return sex;
}
public void setSex(String sex) {
	this.sex = sex;
}
public String getAddress() {
	return address;
}
public void setAddress(String address) {
	this.address = address;
}
public String getEmail() {
	return email;
}
public void setEmail(String email) {
	this.email = email;
}
public String getRegDate() {
	return regDate;
}
public void setRegDate(String regDate) {
	this.regDate = regDate;
}
public int getStatus() {
	return status;
}
public void setStatus(int status) {
	this.status = status;
}

@Override
public String toString() {
	return "UserInfo [uid=" + uid + ", uname=" + uname + ", upass=" + upass + ", realName=" + realName + ", sex=" + sex
			+ ", address=" + address + ", email=" + email + ", regDate=" + regDate + ", status=" + status + "]";
}
public UserInfo() {

}
}

3)修改映射文件UserInfoMapper.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.mybatis.mapper.UserInfoMapper">
 
 <!-- 根据用户编号查询用户 -->
 <select id="findUserInfoById" parameterType="int" resultMap="userInfoMap">
   select *from user_info where id=#{id}
 </select>
 
 <resultMap type="UserInfo" id="userInfoMap">
 <id property="uid" column="id"/>
 <result property="uname" column="userName"/>
 <result property="upass" column="password"/>
 </resultMap>

</mapper>

在 select元素中,通过resultMap属性引用该映射文件中一个id为userInfoMap的 resultMap元素,来完成查询结果的映射。在resultMap元素中,type属性指定映射结果的类型,这里为UserInfo;

4)执行测试类MybatisTest的testFindById方法

结果如下:

在这里插入图片描述

使用Mapper接口执行SQL

  • 在测试类MybatisTest的测试方法中,通过sqlSession对象调用selectOne、selectList、delete和update等方法。在这些方法中,需要指定映射文件中执行语句的id(如findUserInfoById)。如果id的拼写出现错误,只有到运行时才能发现。为此,MyBatis提供了另一种编程方式,即使用Mapper接口执行SQL,从而避免上述情况的出现,同时也更符合Java面向接口编程的习惯。

使用Mapper接口开发时需要遵循如下规范:

  1. 映射文件中的namespace与Mapper接口的类路径相同。

  2. 在Mapper接口中,方法名和映射文件中定义的执行语句的id相同。

  3. 方法的输入参数类型和映射文件中定义的执行语句的parameterType的类型相同。

  4. 方法输出参数类型和映射文件中定义的执行语句的resultType的类型相同。
    在这里插入图片描述

实现步骤:

1)将项目mybatis1复制并命名为mybatis3,再导入eclipse中

2)在com.mybatis.mapper包中,创建接口UserInfoMapper.java,并声明方法,如下所示

package com.mybatis.mapper;
import com.mybatis.pojo.UserInfo;

public interface UserInfoMapper {
	UserInfo findUserInfoById(int uid);
}

3)在测试类MybatisTest中,修改测试方法testFindUserInfoById

//根据id查询用户
    @Test
    public void testFindUserInfoById() {
    	//通过sqlSession对象的getMapper方法获取UserInfoMapper接口的代理对象
    	UserInfoMapper mapper=sqlSession.getMapper(UserInfoMapper.class);
    	//直接调用接口中的方法
    	UserInfo ui=mapper.findUserInfoById(1);
    	
        System.out.println(ui.toString());
    }

4)运行测试方法testFindUserInfoById

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值