【MyBatis】框架-----MyBatis的基础知识以及案例分析

一、MyBatis的基础知识

1、概念(什么是MyBatis?)

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

简单来看,就是这样一个关系:
在这里插入图片描述

2、Hibernate和MyBatis的区别(MyBatis的优势是什么?)

在这里插入图片描述

3、MyBatis的工作原理

在这里插入图片描述

其中各个部分的功能如下图:

名字说明
配置文件mybatis-config.xml用于配置MyBatis运行环境 (主要内容是获取数据库连接),内部可加载多个映射文件
映射文件Mapper.xml用于配置操作数据库的SQL语句
构造会话工厂SqlSessionFactory用于创建会话对象SqlSession,代表一个数据库,建议使用单例
会话对象SqlSession会话工厂的实例化对象,包含数据库中所有执行SQL操作的方法。用于执行持久化操作
Executor执行器用于操作数据库(它会根据SqlSession传递的参数动态生成所需执行的SQL语句,还负责查询缓存的维护)
MappesStatement对象Executor的执行方法的一个参数,是映射信息的封装。用于存储要映射的SQL语句的id、参数等。 一个SQL对应一个MappesStatemen,两者id号相同

4、MyBatis的核心配置

(1)核心对象
在这里插入图片描述
(2)配置文件
(3)映射文件

二、案例分析

创建了一个简单的学生信息管理案例,下图为整个项目的框架:
在这里插入图片描述
这是各个文件的作用:

文件作用
Test.java程序入口,拥有main方法,测试类(获取SqlSession对象以及代理对象,调用方法)
StudentMapper.java映射器接口(放各种方法头)
StudentMapper.xml映射器XML文件,描述映射关系、SQL等内容
Student.javaPOJO对象(普通的学生对象)
StudentDBUtil.java一个工具类,用于创建SqlSessionFactory
log4j.properties日志配置文件,让后台日志数据MyBatis运行的过程日志
mybatis-config.xmlMyBatis配置文件

1、启动MySQL数据库服务器,执行下列脚本,创建student数据库,做数据库访问前的准备工作

-- student数据库创建示例
create database student;
use student;

create table stu
(
	sno char(9) primary key,
	sname varchar(30) not null,
	ssex char(2) not null,
	snative varchar(30),
	mno int
);

insert into stu values('100000001','尚小云','女','广东广州',1);
insert into stu values('100000002','廖时飞','男','广东梅州',1);
insert into stu values('100000003','宋凌枫','男','湖南郴州',2);
insert into stu values('100000004','刘小纳', '女','广东佛山',2);

2、访问student数据库
(1)在Eclipse中新建一个Java项目,取名为MybatisTest。
(2)在项目中增加Mybatis框架的核心包、依赖包及MySQL数据库连接包,如下:
在这里插入图片描述(3)在src根目录中加入log4j.properties文件

# \u914D\u7F6E\u6839Logger
log4j.rootLogger=DEBUG, stdout
log4j.logger.org.mybatis=DEBUG
# \u914D\u7F6E\u65E5\u5FD7\u4FE1\u606F\u8F93\u51FA\u76EE\u7684\u5730Appender\u53CAAppender\u9009\u9879, \u8F93\u51FAConsoleAppender\u5230\u63A7\u5236\u53F0
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# \u914D\u7F6E\u65E5\u5FD7\u4FE1\u606F\u7684\u683C\u5F0F\uFF08\u5E03\u5C40\uFF09\u53CA\u683C\u5F0F\u5E03\u5C40\u9009\u9879
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C %m%n

(4)在com.utils包中新建StudentDBUtil类,用于构造会话对象。代码如下:

package com.utils;

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 StudentDBUtil {
	private static SqlSessionFactory sqlSessionFactory = null;
	
	static {
		try {
			Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	
	public static SqlSession getSession() {
		return sqlSessionFactory.openSession();
	}
}

(5)在com.po包中新建Student类(即Java Bean),代码如下(请保持Java Bean的属性和数据表Stu中字段间的一致):

package com.po;

public class Student {
	private String sno;
	private String sname;
	private String ssex;
	private String snative;
	private int mno;
	public String getSno() {
		return sno;
	}
	public void setSno(String sno) {
		this.sno = sno;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public String getSsex() {
		return ssex;
	}
	public void setSsex(String ssex) {
		this.ssex = ssex;
	}
	public String getSnative() {
		return snative;
	}
	public void setSnative(String snative) {
		this.snative = snative;
	}
	public int getMno() {
		return mno;
	}
	public void setMno(int mno) {
		this.mno = mno;
	}
	@Override
	public String toString() {
		return sno + " | " + sname + " | " + ssex + " | " + snative + " | " + mno ;
	}
}

(6)在src根目录中,新建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>
	<environments default="mysql_student">
		<environment id="mysql_student">
			<transactionManager type="jdbc" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://localhost:3306/student?characterEncoding=gbk"/>
				<property name="username" value="root"/>
				<property name="password" value="root"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/mapper/StudentMapper.xml"/>
	</mappers>
</configuration>

(7)在com.mapper包中,定义接口StudentMapper,其方法与StudentMapper.xml文件中的配置信息对应。部分代码如下:

package com.mapper;
import com.po.Student;

public interface StudentMapper {
	public Student selectStudentBySno(String sno);
   	public List<Student> selectStudentBySname(String sname);
	public int insertStudent(Student student);
	public int deleteStudent(String sno);
	public int updateStudent(Student student);
}

(8)在com.mapper包中,新建StudentMapper.xml文件,在文件中编写对stu表进行查询、插入、删除及更新等操作的配置信息。配置信息如下:

<?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.mapper.StudentMapper">
	<select id="selectStudentBySno" parameterType="String" resultType="com.po.Student">
		select * from stu where sno=#{sno};
	</select>
	<select id="selectStudentBySname" parameterType="String" resultType="com.po.Student">
		select * from stu where sname like concat('%',#{sname},'%');
	</select>
	<insert id="insertStudent" parameterType="com.po.Student">
		insert into stu(sno,sname,ssex,snative,mno) values(#{sno},#{sname},#{ssex},#{snative},#{mno});
	</insert>
	<delete id="deleteStudent" parameterType="String">
		delete from stu where sno=#{sno}
	</delete>
	<update id="updateStudent" parameterType="com.po.Student">
		update stu set sname=#{sname},ssex=#{ssex},snative=#{snative},mno=#{mno} where sno=#{sno}
	</update>
</mapper>

(9)在com包中,新建Test类,在main方法编写代码,通过由Mapper接口生成的代理对象访问数据库(测试对stu表的查询、插入、删除和更新等操作)。

package com;
import java.util.List;

import org.apache.ibatis.session.SqlSession;
import com.mapper.StudentMapper;
import com.po.Student;
import com.utils.*;

public class Test {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SqlSession sqlSession = StudentDBUtil.getSession();
		int count = -1;

		// 生成Mapper的代理对象studentMapper
		StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

		//精确查询测试
		Student student = studentMapper.selectStudentBySno("100000001");
		System.out.println(student);

		// 模糊查询测试
//		List<Student> list = studentMapper.selectStudentBySname("小");
//		for (Student stu : list)
//			System.out.println(stu);
		
		// 插入记录测试
//		Student student = new Student();
//		student.setSno("100000006");
//		student.setSname("黎明");
//		student.setSsex("男");
//		student.setSnative("广东肇庆");
//		student.setMno(2);
//		count = studentMapper.insertStudent(student);
//		sqlSession.commit();
//		System.out.println("成功插入了" + count + "条记录。");

		// 删除记录测试
//		count = studentMapper.deleteStudent("100000004");
//		sqlSession.commit();
//		System.out.println("成功删除了" + count + "条记录。");

		// 更新记录测试
           Student student = new Student();
		student.setSno("100000002");
		student.setSname("廖凡");
		student.setSsex("男");
		student.setSnative("广东汕头");
		student.setMno(2);
		count = studentMapper.updateStudent(student);
		sqlSession.commit();
		System.out.println("成功更新了" + count + "条记录。");

		sqlSession.close();
	}
}

三、遇到的问题和一些想法

1、运行成功,但是出现红色部分的log4j:WARN。解决方法:在src根目录中加入文件log4j.properties即可
在这里插入图片描述

2、在成绩表(成绩表)操作时,传递多个参数出错

<delete id="deleteSc" parameterType="String">
		delete from sc where sno=#{sno} and cno=#{cno} and tno=#{tno}
</delete>

在这里插入图片描述

我的代码如上,但是一直报SQL错误,我查看了数据库的表中的数据段,觉得SQL语句似乎没有错误。
后来查阅博客才发现这个错误的意思是传递多个参数时的写法有错误。正确的写法应该如下:

//注意这里进行多个参数传值时,#{}中内容是arg0,arg1这样的形式 
<delete id="deleteSc" parameterType="String">
		delete from sc where sno=#{arg0} and cno=#{arg1} and tno=#{arg2}
</delete>

3、为什么要使用工具类?
试想一下,我们在每次做案例,每个方法执行时都要读取配置文件,并根据配置文件的信息构建SqlSessionFactory对象,然后创建SqlSession对象,这导致了大量的重复代码。而且这很不符合Java的封装思想。

4、为什么要用一个Mapper映射器?
这是不使用Mapper映射器的,你会发现它的路径参数很长,“com.mapper.StudentMapper.selectStudentBySno”,而且调用其他方法时,总是要写这么长的一串路径,是不是很麻烦,而且又易错?

Student student = sqlSession.select("com.mapper.StudentMapper.selectStudentBySno", "100000001");

那么,使用Mapper映射器呢?你看代码,是不是一下子感觉清爽了很多?不用写长长的路径了!

Student student = studentMapper.selectStudentBySno("100000001");
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值