一.简介
MyBatis(前身是iBatis)是一个支持普通SQL查询、存储过程以及高级映射的持久层框架,它消除了几乎所有的JDBC代码和参数的手动设置以及对结果集的检索,并使用简单的XML或注解进行配置和原始映射,用以将接口和Java的POJO(Plain Old Java Object,普通Java对象)映射成数据库中的记录,使得Java开发人员可以使用面向对象的编程思想来操作数据库。
MyBatis框架也被称之为ORM(Object/Relation Mapping,即对象关系映射)框架。所谓的ORM就是一种为了解决面向对象与关系型数据库中数据类型不匹配的技术,它通过描述Java对象与数据库表之间的映射关系,自动将Java应用程序中的对象持久化到关系型数据库的表中。ORM框架的工作原理如图1所示。
图1 ORM框架的工作原理
从图1可以看出,使用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的方式来操作持久化对象(PO,即Persisent Object),而ORM框架则会通过映射关系将这些面向对象的操作转换成底层的SQL操作。
当前的ORM框架产品有很多,常见的ORM框架有Hibernate和MyBatis。这两个框架的主要区别如下:
● Hibernate:是一个全表映射的框架。通常开发者只需定义好持久化对象到数据库表的映射关系,就可以通过Hibernate提供的方法完成持久层操作。开发者并不需要熟练的掌握SQL语句的编写,Hibernate会根据制定的存储逻辑,自动的生成对应的SQL,并调用JDBC接口来执行,所以其开发效率会高于MyBatis。然而Hibernate自身也存在着一些缺点,例如它在多表关联时,对SQL查询的支持较差;更新数据时,需要发送所有字段;不支持存储过程;不能通过优化SQL来优化性能等。这些问题导致其只适合在场景不太复杂且对性能要求不高的项目中使用。
● MyBatis:是一个半自动映射的框架。这里所谓的“半自动”是相对于Hibernate全表映射而言的,MyBatis需要手动匹配提供POJO、SQL和映射关系,而Hibernate只需提供POJO和映射关系即可。与Hibernate相比,虽然使用MyBatis手动编写SQL要比使用Hibernate的工作量大,但MyBatis可以配置动态SQL并优化SQL,可以通过配置决定SQL的映射规则,它还支持存储过程等。对于一些复杂的和需要优化性能的项目来说,显然使用MyBatis更加合适。
二.项目部署mybatis
1.创建maven项目
java或者web都行
2.引入依赖
在pom.xml中添加依赖
3.创建mybatis配置文件mysql mysql-connector-java8.0.26
org.mybatis
mybatis
3.5.9
在resources文件夹添加mybatis_config.xml并配置数据库信息
4.使用
4.1创建数据库表
create table tb_students(
sid int primary key auto_increment,
stu_num char(5) not null unique,
stu_name varchar(20) not null,
stu_gender char(2) not null,
stu_age int not null
);
4.2创建实体类
//使用API对实体类操作
//对属性添加get和set方法
@Data
//全参构造函数
@AllArgsConstructor
//无参构造函数
@NoArgsConstructor
//重写tostring方法
@ToString
public class Student {
private int stuID;
private String stuNum;
private String stuName;
private String stuGender;
private int stuAge;
}
4.3创建DAO接口,定义操作方法
public interface StudentDAO {
public int insertStudent(Student student);
}
4.5 在resources文件夹创建mappers文件夹,在里面mappers里创建DAO接口的mybatis_mapper.xml映射文件,就相当于接口的实现类,方法的功能是什么就用什么标签,id绑定方法名,parameterType声明参数类型,values是类的属性
insert into tb_student(stu_num,stu_name,stu_gender,stu_age) values (#{stuNum},#{stuName},#{stuGender},#{stuAge})
4.6 将映射文件添加到mybatis_config.xml文件
5.单元测试
导入测试包
junit junit4.13.2 test
在DAO接口右键选择generate,
选择test,
将所有方法添加上
自动在 生成test文件夹测试方法
@org.junit.Test
public void insertStudent() {
try {
//加载mybatis配置文件
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//会话工厂
SqlSessionFactory factory = builder.build(is);
//与数据库的连接即mybatis的操作对象,会话
SqlSession sqlSession = factory.openSession();
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
int i=studentDAO.insertStudent(new Student(0,"Y8021","小明","男",18));
// 手动提交事务
sqlSession.commit();
if (i==1){
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
} catch (IOException e) {
e.printStackTrace();
}
}
查询时
1.如果方法只有一个简单类型或者字符串类型的参数,在Mapper配置中可以直接通过#{key}获取
2.如果方法有一个对象类型的参数,在Mapper配置中可以直接通过#{属性名}获取指定属性值
在DAO中
public int deleteStudent(String stuNum);
在mapper 里
delete from tb_students where stu_num = #{stuNum}
测试:
public void deleteStudent() {
try {
//加载mybatis配置文件
InputStream is = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//会话工厂
SqlSessionFactory factory = builder.build(is);
//与数据库的连接即mybatis的操作对象,会话
SqlSession sqlSession = factory.openSession();
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
int i= studentDAO.deleteStudent("Y8021");
sqlSession.commit();
if (i==1){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
} catch (IOException e) {
e.printStackTrace();
}
3.如果方法有多个参数,可以将其转换成Map类型,在Mapper配置中可以直接通过HashMap的key值#{key}获取指定属性值
在DAO中:
public ListlistStudentPage(HashMap map);
在mapper中:
测试:
public void listStudentPage() {
try {
InputStream is=Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory= builder.build(is);
SqlSession sqlSession= factory.openSession();
StudentDAO studentDAO=sqlSession.getMapper(StudentDAO.class);
//用hashmap传参
HashMap hashMapmap=new HashMap<>();
hashMapmap.put("start",0);
hashMapmap.put("pageSize", 2);
List list = studentDAO.listStudentPage(hashMapmap);
sqlSession.commit();
assertNotNull(list);
list.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
4.如果方法有多个参数,在Mapper配置中使用arg0,arg1或者(param1,param2)...获取参数
在DAO中:
public ListlistStudentPage(int start, int pageSize);
在mapper里:
方便起见在DAO可以用@Param("start")给参数起别名,
public ListlistStudentPage(@Param("start") int start,@Param("pageSize") int pageSize);
在mapper使用别名获取
limit #{satrt},#{pageSize}
测试:
public void listStudentPage() {
try {
InputStream is=Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory= builder.build(is);
SqlSession sqlSession= factory.openSession();
StudentDAO studentDAO=sqlSession.getMapper(StudentDAO.class);
List list = studentDAO.listStudentPage(0,2);
sqlSession.commit();
assertNotNull(list);
list.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}



