MyBatis学习笔记总结
Posted ascto
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis学习笔记总结相关的知识,希望对你有一定的参考价值。
MyBatis
一、框架概述
1.1软件开发常用结构
三层架构包含的三层:
界面层、业务逻辑层、数据访问层
三层的职责
1.界面层(表示层,视图层):主要功能是接受用户的数据,显示请求的处理结果。使用web页面和用户交互,手机app也就是表示层的,用户在app中操作,业务逻辑在服务器端处理。
2.业务逻辑层:接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。
3.数据访问层: 与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。
三层对应的包:
界面层:controller包(servlet类)
业务逻辑层:service包(各种xxxservice类)
数据访问层:dao包(xxDao类)
三层中类的交互
用户使用界面层—>业务逻辑层---->数据访问层(持久层)—>mysql
三层对应的框架
界面层:servlet---->SpringMVC
业务逻辑层:service类----->Spring
数据访问层:Dao----->MyBatis
1.2框架概念
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种认为,框架是可被应用开发者定制的应用骨架、模板。
简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来说框架一个舞台, 你在舞台上做表演。在框架基础上加入你要完成的功能。
框架安全的,可复用的,不断升级的软件。
框架是一个舞台,是一个模版
模版:
- 已经事先规定好了一些条款和内容
- 加入自己的东西
框架是一个模版
- 框架中定义好了一些功能,这些功能是可用的。
- 可以加入自己项目的功能,这些功能可以利用框架中写好的功能。
框架是一个半成品软件,定义好了一些基础的功能,需要加入你的功能就是完整的。
基础功能是公用的,可重复使用的,可升级的。
框架特点:
- 框架一般不是全能的,不可以做所有的事情。
- 框架一般针对于某一个领域,特长在某一个方面,比如MyBatis做数据库操作强,但是它不可以做其他的。
- 框架是一个软件。
1.3JDBC编程
- 代码比较多,开发效率低
- 需要关注Connection,Statement,ResultSet创建对象和销毁
- 对ResultSet查询结果,需要自己封装为List
- 重复的代码比较多
- 业务代码和数据库的操作混在一起
1.4MyBatis框架概述
MyBatis框架:
MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013 年11月迁移到Github。
iBATIS 一词来源于“internet" 和“abatis"的组合,是一个基于Java 的持久层框架。
iBATIS提供的持久层框架包括SQL Maps和Data Access Objects ( DAOs)。当前,最新版本是MyBatis3.5.1,其发布时间是2019年4月8日。
mybatis框架
一个框架,早期叫做ibatis, 代码在github。
mybatis是MyBatis SQL Mapper Framework for Java( sql映射框架)
- sql mapper : sql映射
可以把数据库表中的一行数据映射为一个 java对象。行数据可以看做是一个java对象。操作这个对象,就相当于操作表中的数据 - Data Access Objects (dAOs) :数据访问,对数据库执行增删改查。
MyBatis解决的主要问题
- 提供了创建Connection,Statement,ResultSet的能力,不用开发人员创建这些对象了。
- 提供了执行sql语句的能力,不用你执行sql。
- 提供了循环sql,把sql的结果转换为java对象,List集合的能力。
- 提供了关闭资源的能力
开发人员需要做的:提供sql语句。
最后:开发人员提供sql语句----MyBatis处理sql语句----开发人员得到List集合或者Java对象
总结:mybatis是一个sql映射框架,提供数据库的操作能力,增强的jdbc,使用mybatis让我们的开发人员集中精神写sql语句就可以了,不必关心connection,statement,resultset的创建、销毁、sql语句的执行。
二、MyBatis框架快速入门
2.1入门案例
2.1.1使用MyBatis的准备
到github上下载对应zip包,地址为:点击这里
2.1.2搭建MyBatis开发环境
实现步骤:
1.新建的students表。
2.加入maven的mybatis坐标、mysql驱动的坐标。
3.创建实体类,Student----用来保存表中的一行数据的。
4.创建持久层的DAO接口,定义操作数据库的方法。
5.创建一个MyBatis使用的配置文件,叫做sql映射文件:写sql语句的,一般是一个表一个sql映射文件。这个文件是xml类型文件
6.创建一个mybatis的主配置文件:一个项目就一个主配置文件。主配置文件提供了数据库的连接信息和sql映射文件的位置信息。
7.创建使用mybatis类,通过mybatis去访问数据库
pom中设置依赖
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
创建studentDao.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="cqutlc.dao.studentDao">
<!--
select表示查询操作
id:你要执行sql语句的唯一标识,mybatis会使用这个id的值,找到要执行的sql语句
可以自定义,但是要求你使用接口方法中名称
resultType:表示结果类型,是sql语句执行后得到的ResultSet,遍历这个ResultSet得到Java对象的类型
值写的是类型的全限定名称
-->
<select id="selectStudents" resultType="cqutlc.domain.Students">
select id,name,email,age from school.students order by id
</select>
</mapper>
<!--
sql映射文件:写sql语句的,mybatis会执行这些sql
1.指定约束文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3-mapper.dtd是约束文件的名称,扩展名是dtd的
约束文件的作用:限制、检查在当前文件中出现的标签、属性必须符合mybatis的要求
2.mapper 是当前文件的根标签,必须的。
namespace:叫做命名空间,唯一值的,可以是自定义的字符串
要求你使用dao的全限定名称
3.在当前文件中,可以使用特定的标签,表示数据库的特定操作
<select>:表示执行查询
<update>:表示更新数据库操作
<insert>:表示插入
<delete>:表示删除
-->
mybatis连接数据库
<?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="mydev">
<!--environment:一个数据库信息配置,环境
id:一个唯一值,自定义,表示环境名称
-->
<environment id="mydev">
<!--
transactionManager:mybatis的事务类型
type:jdbc(表示jdbc事务处理)
-->
<transactionManager type="JDBC"/>
<!-- 数据源的配置,URL,用户名 密码 数据库 -->
<!--
dataSource表示数据源
type:表示数据源的类型,POOLED表示使用连接数据池
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisTest?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="131138"/>
</dataSource>
</environment>
<!--在线数据库-->
<environment id="online">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisTest?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="131138"/>
</dataSource>
</environment>
</environments>
<!--sql mapper(sql映射文件)的位置-->
<mappers>
<!--
一个mapper标签指定一个文件的位置
从类路径开始的路径信息。target/class
-->
<mapper resource="cqutlc\\dao\\studentDao.xml"/>
</mappers>
</configuration>
<!--
mybatis的主配置文件:主要定义了数据库的配置信息,sql映射文件的位置
1.约束文件
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
mybatis-3-config.dtd 约束文件的名称
2.
-->
package cqutlc;
import cqutlc.domain.Students;
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 java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
public class test {
public static void main(String[] args) throws IOException {
//访问mybatis读取student数据
//1.定义mybatis主配置文件的名称,从类路径的根开始(target/class)
String config="mybatis.xml";
//2.读取这个config表示的文件
InputStream in= Resources.getResourceAsStream(config);
//3.创建了sqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory=builder.build(in);
//5.获取sqlSession对象,从sqlSessionFactory中获取sqlSession
SqlSession sqlSession=factory.openSession();
//6.【重要】指定要执行的sql语句的标识。sql映射文件中的namespace+“.”+标签的id值
String sqlId="cqutlc.dao.studentDao"+"."+"selectStudents";
//7.执行sql语句,通过sqlId找到语句
List<Students> studentsList=sqlSession.selectList(sqlId);
//8.输出结果
studentsList.forEach(System.out::println);
//9.关闭sqlSession对象
sqlSession.close();
}
}
输出:
2.1.3insert操作
package cqutlc;
import cqutlc.domain.Students;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class testMybatis {
//测试代码
@Test
public void testMybatis() throws IOException {
//访问mybatis读取student数据
//1.定义mybatis主配置文件的名称,从类路径的根开始(target/class)
String config="mybatis.xml";
//2.读取这个config表示的文件
InputStream in= Resources.getResourceAsStream(config);
//3.创建了sqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory=builder.build(in);
//5.获取sqlSession对象,从sqlSessionFactory中获取sqlSession
SqlSession sqlSession=factory.openSession();
//6.【重要】指定要执行的sql语句的标识。sql映射文件中的namespace+“.”+标签的id值
String sqlId="cqutlc.dao.studentDao"+"."+"insertStudent";
//7.执行sql语句,通过sqlId找到语句
Students students=new Students(1003,"张飞","1231@qq.com",19);
int num=sqlSession.insert(sqlId,students);
sqlSession.commit();
//8.输出结果
System.out.println("执行insert结果:"+num);
//9.关闭sqlSession对象
sqlSession.close();
}
}
2.2MyBatis对象分析
主要类的介绍
1.Resources:mybatis中的一个类,负责读取主配置文件
InputStream in= Resources.getResourceAsStream(config);
2.SqlSessionFactoryBuilder:创建SqlSessionFactory对象
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); SqlSessionFactory factory=builder.build(in);
3.SqlSessionFactory:重量级对象,程序创建一个这样的对象耗时较长,使用资源较多。在整个项目中,有一个就够了。
SqlSessionFactory作用:获取SqlSession对象,SqlSession sqlSession=factory.openSession();
4.SqlSession
SqlSession接口:定义了操作数据的方法,delete(),commit(),update()等
使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,使用openSession获取SqlSession
在执行完sql语句之后,需要关闭它,执行SqlSession.close(),这样才可以保证它的使用是安全的。
三、MyBatis框架Dao代理
3.1Dao代理实现数据库操作
传统Dao实现select操作
studentDao.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="cqutlc.dao.studentDao">
<select id="selectStudents" resultType="cqutlc.domain.Student">
select id,name,email,age from school.students order by id
</select>
</mapper>
studentDao
package cqutlc.dao;
import cqutlc.domain.Student;
import java.util.List;
public interface studentDao {
List<Student> selectStudents();
}
studentDaoImpl
package cqutlc.dao.impl;
import cqutlc.MyBatisUtils;
import cqutlc.dao.studentDao;
import cqutlc.domain.Student;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class studentDaoImpl implements studentDao {
@Override
public List<Student> selectStudents() {
//获取sqlSession对象
SqlSession sqlSession= MyBatisUtils.getSqlSession();
String sqlId="cqutlc.dao.studentDao.selectStudents";
//执行sql语句
List<Student> students= sqlSession.selectList(sqlId);
students.forEach(student -> System.out.println());
sqlSession.close();
return students;
}
}
测试类
package cqutlc;
import cqutlc.dao.impl.studentDaoImpl;
import cqutlc.dao.studentDao;
import cqutlc.domain.Student;
import org.junit.Test;
import java.util.List;
public class TestMybaits {
@Test
public void testStudent(){
studentDao dao=new studentDaoImpl();
List<Student> studentList=dao.selectStudents();
studentList.forEach(student -> System.out.println());
}
}
利用动态代理实现(重点)
mybatis根据dao的方法调用,获取执行sql语句的信息。mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的对象,完成sqlSession调用方法,访问数据库。
package cqutlc;
import cqutlc.dao.studentDao;
import cqutlc.domain.Student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class TestMybaits {
@Test
public void testSelectStudent(){
/*
* 使用动态代理的机制,使用SqlSession.getMapper(dao接口)
* getMapper能够获取dao接口对应的实现类对象。
* */
SqlSession sqlSession=MyBatisUtils.getSqlSession();//StudentDao.xml生效
studentDao dao=sqlSession.getMapper(studentDao.class);//studentDao接口与sqlSession语句关联
//调用dao方法,执行数据库操作
List<Student> students=dao.selectStudents();//执行xml中selectStudent方法
students.forEach(student -> System.out.println());
}
}
3.2深入理解传入参数
传入参数:从Java代码中把数据传入到mapper文件的sql语句中。
parameterType:写在mapper文件中的一个属性,它是表示dao接口中方法的参数的数据类型。(不是强制要写,因为mybatis通过反射机制能够发现接口参数的数据类型)
ps:#{}=?(没有sql注入风险)
多个参数
1.@Param
语法:
xxx(@Param("myname") String name,Integer age)
mapper文件对应写法
<select>
select * from student where name=#{myname}
</select>
2.传入的参数是一个对象类型
语法:#{属性名,javaType=类型名称,jdbcType=数据类型}
简化方式 #{属性名}
3.按位置
语法:#{arg位置}
#和$的区别
#:占位符,告诉mybatis使用实际的参数值代替。(不会存在注入问题,用?替代了)
: 字 符 串 替 换 , 告 诉 m y b a t i s 使 用 :字符串替换,告诉mybatis使用 :字符串替换,告诉mybatis使用包含的“字符串”替换所在位置。(存在注入风险,因为直接填入了,没有用?代替)
$一般用于替换列名 order by ${xxx}
3.3封装MyBatis输出结果
resultType
结果类型,指sql语句执行完后,数据转为的Java对象(类型任意)。
处理方式:
1.mybatis执行sql语句,然后mybatis调用类的无参构造方法,创建对象
2.mybatis把ResultSet指定列值付给同名的属性。
当然也可以返回简单类型,如:int。(全限定名称或者别名都可以,最好用全限定名称:java.lang.Integer)
定义自定义类型的别名
方法一:
1.在mybatis主配置文件中定义,使用 <typeAlians>
。
2.可以在resultType中使用自定义别名。
方法二:
<package>name是包名
,这个包中的所有类,类名就是别名(类名不区分大小写)
模糊like
<!--第一种like,Java中指定like的内容-->
<select id="selectLikeOne" resultType="cqutlc.domain.Student">
select id,name,email,age from school.students where name like #{name}
</select>
@Test
public void testSelectLikeOne(){
SqlSession sqlSession=MyBatisUtils.getSqlSession();
studentDao dao=sqlSession.getMapper(studentDao.class);
String name="%李%";
List<Student> students=dao.selectLikeOne(name);
students.forEach(student -> System.out.println());
sqlSession.close();
}
四、MyBatis框架动态SQL
动态sql:sql的内容是变化的,可以根据条件获取到不同的sql语句。主要是where的部分发生变化。
动态sql的实现使用的是mybatis提供的各种标签。
4.1动态SQL之 <if>
语法:
<if test="判断Java对象的属性值">
部分sql语句
</if>
对于该标签的执行,当test的值为true时,会将其包含的SQL片断拼接到其所在的sql语句中。
<select id="selectStudentIf" resultType="cqutlc.domain.Student">
select id,name,email,age from school.students
where
<if test="name!=null and name!='' ">
name = #{name}
</if>
<if test="age>0">
and age > #{age}
</if>
</select>
@Test
public void testSelectStudentIf()以上是关于MyBatis学习笔记总结的主要内容,如果未能解决你的问题,请参考以下文章