目录
MyBatis 框架
第一章 框架的概述
1.三层架构
2. 三层架构处理的流程
3. 为什么使用三层架构
4. 三层框架模式和框架
5. 框架
6. 框架解决的问题
7.jdbc访问数据库的优缺点
8. Mybatis框架
第二章 Mybatis入门
1. 第一个例子
2. 概念
3. Mybatis的一些重要对象
4. 使用工具类和模板
第三章 Mybatis代理实现数据库操作
1. dao代理
1.1 mybatis提供代理:
1.2 使用mybatis代理要求:
1.3 mybatis代理实现方式
2. 理解参数
2.1 priameterType
2.2 dao接口方法是一个简单类型的参数
2.3 dao接口方法有多个简单类型的参数
2.4 dao接口方法使用对象作为参数
2.5 dao接口方法多个简单类型的参数,按位置
2.6 dao接口参数是一个Map
3. #和$的区别
3.1 #占位符
3.2 $占位符
4. 封装Mybatis输出结果
4.1 resultType
4.2 resultMap
5. 使用别名
6.列名和java对象属性名称不一样解决方式
7.模糊查询 like
第四章 动态sql
1. if标签
2. where标签
3. foreach循环标签
4. sql标签
第五章 MyBatis配置文件
1. settings部分
2.typeAliase 别名
3. environments 配置环境
4. 使用数据库属性配置文件
5. mapper标签
第六章 扩展 分页 PageHelper
1. mybatis通用分页插件
mvc:web开发中,使用mvc架构模式。m:数据,v:视图,c:控制器
c控制器:接收请求,调用service对象,显示请求的处理结果。当前使用servlet作为控制器
v视图:现在使用jsp,html,css,js。显示请求的处理结果,把m中数据显示出来
m数据:来自数据库mysql,来自文件,来自网路
mvc作用:
1. 实现解耦合 2. 让mvc各负其职。 3. 使得系统扩展更好。更容易维护
三层架构:
界面层(视图层):接收用户的请求,调用service,显示请求的处理结果。包含了jsp,html,servlet等对象。对应的包controller
业务逻辑层:处理业务逻辑,使用算法处理数据的,把数据返回给界面层。对应的是service包,和包中的很多的xxxSercive类。
例如:StudentService,OrderService,ShopService
持久层(数据访问层):访问数据库,或者是读取文件,访问网络。获取数据。对应的包是dao。dao包中很对的StudentDao,OrderDao,ShopDao等等
用户发起请求--->页面层--->业务逻辑层--->持久层--->数据库(mysql)
结构清晰,耦合度低,各层分工明确
可维护性高,可扩展性高
有利于标准化
开发人员可以只关注整个结构中的其中某一层的功能实现
有利于各层逻辑的复用
每一层对应着一个框架
界面层:---SpringMvc框架
业务层:---Spring框架
持久层:---MyBatis框架
什么是框架(framework)
框架:就是一个软件,完成了部分的功能。软件中类和类之间的方法调用都已经规定好了。通过这些可以完成某些功能。框架看作是模板。
框架是可以升级的,改造的。框架是安全的。
框架是对某一方面有用的,不是全能的。
框架能实现技术的整合。
提供开发的效率。降低难度
优点:
直观,好理解
缺点:
创建很多对象Connection,Statement,ResultSet
注册驱动
执行sql语句
把ResultSet转换Student,List集合
关闭资源
sql语句和业务逻辑代码混在一起
mybatis:是一个持久层框架,原名ibatis,2013年改名为 Mybatis。Mybatis可以操作数据库,对数据执行增删改查。看作是高级的 jdbc,解决jdbc的缺点。
mybatis能做什么?
注册驱动
创建jdbc中使用的Connection,Statement,ResultSet
执行sql语句,得到ResultSet
处理ResultSet,把记录集中的数据转为java对象,同时还能把java对象放到List集合。
关闭资源
实现sql语句和java代码的解耦合
mybatis的官网:mybatis – MyBatis 3 | 简介
实现步骤:
创建student表(id,name,email,age)
新建maven项目
修改pom.xml
加入依赖mybatis依赖,mysql驱动,junit
在
src/main/java
**/*.properties
**/*.xml
false
创建实体类Student。定义属性,属性名和列名保持一致
创建Dao接口,定义操作数据库的方法
创建xml文件(mapper文件),写sql语句
mybatis框架推荐是把sql语句和Java代码分开
mapper文件:定义和dao接口在同一目录,一个表一个mapper文件
创建mybatis的主配置文件(xml文件):有一个,放在resources目录下
定义创建连接实例的数据源(DataSource)对象
指定其他mapper文件的位置
创建测试的内容
使用main方法,测试mybatis访问数据库
也可以使用junit访问数据库
自动提交:当你的sql语句执行完毕后,提交事务。数据库更新操作之间保存到数据
手动(手工)提交事务:在你需要提交事务的位置,执行方法,提交事务或者回滚事务。
Resources: mybatis框架的重要对象,一个作用:读取主配置信息
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml(主配置文件)")
SqlSessionFactoryBuilder:负责创建SqlSessionFactory对象
SqlSessionFactory factory =new SqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactory:重要对象
SqlSeeionFactory是重量级对象:创建此对象需要使用更对的资源和时间。在项目中有一个就可以了
SqlSessionFactory接口:作用是SqlSession的工厂,就是创建SqlSession对象
DefaultSqlSessionFactory实现类:
public class DefaultSqlSessionFactory implements SqlSessionFactory {}
SqlSessionFactory接口中的方法:
openSession():获取一个默认的SqlSession对象,默认是需要手工提交事务的。
openSession(boolean):boolean参数表示是否自动提交事务
true:创建一个自动提交事务的SqlSession
false:等同于没有参数的openSession
SqlSession对象
SqlSession对象是通过SqlSessionFactory获取的。SqlSession本身是接口
DefailtSqlSession实现类:
public class DefaultSqlSession implements SqlSession {}
SqlSession作用是通过提供了大量的执行sql语句的方法
selectOne:执行sql语句,最多得到一行,多余一行是错误 selectList:执行sql语句,返回多行数据 selectMap:执行sql语句,得到一个Map结果 insert:执行insert语句 update:执行update语句 delete:执行delete语句 commit:提交事务 rollback:回滚事务
注意:SqlSession对象不是线程安全的,使用步骤:
在方法的内部,执行sql语句之前,先获取SqlSession对象
调用SqlSession的方法,执行sql语句
关闭SqlSession对象,执行SqlSession.close()
mybatis主配置文件模板
mapper:
mapper主配置文件:
mybatis创建Dao接口的实现类对象,完成对sql语句的执行。mybatis创建一个对象代替你的dao实现类功能。
mapper文件中的namespace一定是dao接口的全限定名称
mapper文件中标签的id是dao接口方法名称
使用SqlSession对象的方法 getMapper(dao.class)
例如:现在由StudentDao接口 MyBatisUtils工具类
SqlSession session =MyBatisUtils.getSqlSession();
StudenDao dao =session.getMapper(StudentDao.class);
Student student=dao.selectById(1001);
//上面代码中
StudenDao dao =session.getMapper(StudentDao.class);
等同于
StudentDao dao =new StudentDaoImpl();
理解参数:通过java程序把数据传入到mapper文件中的sql语句。参数主要是指dao接口方法的形参.
priameterType:表示参数的类型,指定dao方法的形参数据类型。这个形参的数据类型是给mybatis使用
mybatis在给sql语句的参数赋值时使用,PreparedStatement.setXXX(位置,值)
StudentDao:
//dao接口的方法形参是一个简单类型的
//简单类型:java基本数据类型和String
Student selectByEmail(String email);
mapper文件:
@Param:命名参数,在方法的形参前面使用的,定义参数名。这个名称可以用在mapper文件中。
dao接口,方法的定义
/*
多个简单类型的参数
使用@Param命名参数,注解是mybatis提供的
位置:在形参定义的前面
属性:value 自定义的参数名称
*/
List selectByNameOrAge(@Param("myname") String name,
@Param("myage") Integer age);
mapper文件:
方法的形参是一个java对象。这个java对象表示多个参数。使用对象的属性值作为参数使用
dao接口
/* 一个java对象作为参数(对象有属性,每个属性set,get方法) */ ListselectByObject(Student student);
mapper文件
Student实体类 java对象
package org.example.domain;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
//set|get方法。。。
}
参数位置:dao接口中方法的形参列表,从左往右,参数位置是0,1,2.。。。
语法格式:#{arg0},#{arg1}.......
dao接口
/* 使用位置,获取参数 */ ListselectByPosition(String name,Integer age);
mapper文件
map作为dao接口的参数,使用key获取参数值,语法格式#{key}
dao类
/* 使用Map作为参数 */ ListselectStudentByMap(Map map);
mapper文件
MyTest类
@Test public void testSelectMap(){ SqlSession session =MybatisUtil.getSqlSession(); StudentDao dao =session.getMapper(StudentDao.class); //使用map传递参数 Mapdata =new HashMap<>(); data.put("myname","李思思"); data.put("myage",20); List students = dao.selectStudentByMap(data); students.forEach(stu-> System.out.println("stu="+stu)); session.close(); }
语法:#{字符}
mybatis处理#{} 使用jdbc对象是PrepareStatement对象
mybatis创建PrepareStatement对象,执行sql语句 String sql="select id,name,email,age from student where id=?"; PrepareStatement pst =conn.prepareStatement(sql); pst.setInt(1,1001); //传递参数 ResulSet rs = pst.executeQuery();//执行sql语句
#{}特点:
使用的PrepareStatement对象,执行sql语句,效率高。
使用的PrepareStatement对象,能避免sql语句,SQL语句执行更安全
#{}常常作为列值使用的,位于等号的右侧,#{}位置的值和数据类型的值有关。
语法:${字符}
mybatis执行${}占位符的sql语句
${} 表示字符串连接符,把sql语句的其他内容和${}内容使用字符串(+)连接的方式连在一起 String sql="select id,name,email,age from student where id="+"1001"; mybatis创建Statement对象,执行sql语句 Statement stmt =conn.createStatement(sql); Resultset rs =pst.executedQuery();
${}特点:
使用sStatement对象,执行sql语句,效率低
${}占位符的值,使用的字符串连接方式,有sql注入的风险。有代码安全的问题
${}数据是原样使用的,不会区分数据类型。
${}常用作 表名或者列名,在能保证数据安全的情况下使用
封装输出结果:Mybatis执行sql语句,得到ResultSet,转为java对象。
resultType,resultMap
resultType属性:在执行select时使用,作为
resultType:表示结果类型,mybatis执行sql语句,得到Java对象的类型。它的值有两种
Java类型的全限定名称
使用别名
1.resultType:表示Java自定义对象
Student selectById(Integer id); resultType:现在使用java类型的全限定名称。表示的意思:mybatis执行sql,把ResultSet中的数据转为Student类型的对象 mybatis会做以下操作: 1.调用org.example.domain.Student的无参构造方法,创建对象 Student student =new Student();//使用反射创建对象 2.同名的列赋值给同名的属性 student.setId(rs.getInt("id")); student.setName(rs.getString("name")); 3.得到java对象,如果dao接口返回值是List集合,mybatis把student对象放入到List集合 所以执行Student mystudent =dao.selectById(1001); 得到数据库中 id=1001这行数据,这行数据的列值,赋给mystudent对象的属性。你能得到mystudent对象,就相当于是 id=1001这行数据。
2.用resultType表示简单类型
dao方法
long countStudent();
mapper文件
3.resultType:表示一个map结构
dao方法
//查询结果是一个Map Map
mapper文件
resultMap:结果映射。自定义列名和java对象属性的对应关系。常用在列名和属性名不同的情况
用法:
先定义resultMap标签,指定列名和属性名称对应关系
在select标签使用resultMap属性,指定上面定义的resultMap的id值
mapper文件
mybatis提供的对java类型定义简短,好记忆
自定义别名的步骤:
在mybatis主配置文件,使用typeAliase标签声明别名
在mapper文件中,resultType="别名"
声明别名(mybatis主配置文件):
mapper文件中使用
resultType="别名" 第二种方式:
使用resultMap:自定义列名和属性名称对应关系
使用resultType:使用列的别名,让别名和java对象属性名称一样
第一种方式:在java程序中,把like的内容组装好。把这个内容传入到sql语句中
dao方法
//like第一种方式 ListselectLikeOne(@Param("name") String name);
mapper文件
测试类
@Test public void testLikeOne(){ SqlSession session =MybatisUtil.getSqlSession(); StudentDao dao =session.getMapper(StudentDao.class); String name="%李%"; Liststudents = dao.selectLikeOne(name); session.close(); students.forEach(stu-> System.out.println(stu)); }
第二种方式:在sql语句中,组织like内容。
sql语句like的格式:where name like "%"空格#{name}空格 "%"
什么是动态sql:同一个dao的方法,根据不同的条件可以表示不同的sql语句,主要是where部分有变化
使用mybatis提供的标签,实现动态sql的能力,主要讲if,where,foreach,sql
使用动态sql的时候,dao方法的形参使用Java对象。
多条件查询时使用动态sql
语法:
sql 代码 在mapper文件中
例如:
dao:
ListselectIf(Student student);
mapper文件
使用if标签时,容易引起sql语句语法错误。使用where标签解决if产生的语法问题
使用where,里面是一个或多个if标签,当有一个if标签判断条件为true,where标签会转为WHERE关键字附加到sql语句的后面。如果if没有一个条件为true,忽略where和里面的if
语法:
语法:sql语句1 sql语句2
例如:
dao:
//where ListselectWhere(Student student);
mapper文件
使用foreach可以循环数据,list集合,一般使用在in语句中。
语法:
#{item的值} 标签属性: collection:表示,循环的对象是 数组,还是list集合。如果dao接口方法的形参是 数组,collection="array"。 List,collection="list" open:循环开始时的字符。sql.append("(");//select * from student where id in (1001,1002,1003) close:循环结束时的字符。sql.append(")"); item:集合成员,自定义变量。Itnteger item=idlist.get(i); separtor:集合成员之间的分隔符。sql.append(",") #{item的值}:获取集合成员的值。
简单类型例子:
dao: ListselectForeachOne(List idlist); 测试类: @Test public void testSelectForeachOne(){ //1.获取SqlSession对象 SqlSession session = MybatisUtil.getSqlSession(); //2.获取dao的代理 StudentDao dao =session.getMapper(StudentDao.class); List idlist =new ArrayList<>(); idlist.add(1001); idlist.add(1002); idlist.add(1003); List students = dao.selectForeachOne(idlist); students.forEach(stu -> System.out.println("stu="+stu) ); //4.关闭 session.close(); }
mapper文件
对象类型例子:
dao: ListselectForeachTwo(List studentList); 测试类: @Test public void testSelectForeachTwo(){ //1.获取SqlSession对象 SqlSession session = MybatisUtil.getSqlSession(); //2.获取dao的代理 StudentDao dao =session.getMapper(StudentDao.class); List list =new ArrayList<>(); Student s1 =new Student(); s1.setId(1001); Student s2 =new Student(); s1.setId(1002); list.add(s1); list.add(s2); List students = dao.selectForeachTwo(list); students.forEach(stu -> System.out.println("stu="+stu) ); //4.关闭 session.close(); }
mapper文件
sql标签表示一段sql代码,可以是表名,几个字段,where条件都可以,可以在其他地方复用sql标签的内容。
使用方式:
1.在mapper文件中定义sql代码片段部分sql语句 2.在其他的位置,使用include标签引用某个代码片段 例如:select * from student id,name,email
mybatis配置文件两大类:1 mybatis主配置文件;2 mybatis的mapper文件
mybatis主配置文件,提供mybatis全局设置的。包含的内容:日志,数据源,mapper文件位置
mapper文件:写sql语句的,一个表一个mapper文件
settings是mybatis的全局设置,影响整个mybatis的运行。这个设置一般使用默认
设置别名
environments:环境标签,在他里面可以配置多个environment 属性:default。必须是某个environment的id名 environment:表示一个数据库的连接信息。 属性:id:自定义的环境的标识。唯一值 transactionManager:事务管理器 属性:type 表示事务管理器的类型 属性值:1.JDBC:使用Connection对象,由mybatis自己完成事务的处理 2.MANAGED:管理,表示把事务的处理交给容器实现(有其他软件完成事务的提交,回滚) dataSource:数据源,创建的Connection对象,连接数据库。 属性:type:数据源的类型 属性值:1.POOLED,mybatis会在内存中创建PooledDataSource类,管理多个Connection连接对象,使用的连接池 2.UNPOOLED,不使用连接池,mybatis创建一个UnPooledDataSource这个类,每次执行sql语句先创建Connection对 象,再执行sql语句,最后关闭Connection 3.JNDI:java的命名和目录服务e
需要把数据库的配置信息放到一个单独文件中,独立管理。这个文件扩展名是properties.在这个文件中,使用自定义的key=value的格式表示数据
使用步骤:
在resources目录中,创建xxxx.properties
在文件中,使用ley=value的格式定义数据。
例如:jdbc.url=jdbc:mysql://localhost:3306/springdb
在mybatis主配置文件,使用properties标签引用外部的属性配置文件
在使用值的位置,使用${key}获取对应的value(等号右侧的值)例如:value="${jdbc.url}";
例子:
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8 jdbc.username=root jdbc.password=123456
mybatis主配置文件:
使用mapper指定其他mapper文件的位置
GitHub - pagehelper/Mybatis-PageHelper: Mybatis通用分页插件
PageHelper做数据分页,在你的select语句后面加入分页的sql内容,如果你使用的mysql数据库,它就是在select * from student 后面加入limit语句。
使用步骤:
加入依赖pagehelper依赖
com.github.pagehelper pagehelper 5.1.10
在mybatis主配置文件,加入plugin声明
在之前加入
在select语句之前,调用PageHelper.startPage(页码,每页大小)
@Test public void testPageHelper(){ //1.获取SqlSession对象 SqlSession session = MybatisUtil.getSqlSession(); //2.获取dao的代理 StudentDao dao =session.getMapper(StudentDao.class); //调用PageHelper的方法 PageHelper.startPage(1,3); Liststudents = dao.selectAllStudents(); students.forEach(stu -> System.out.println("stu="+stu) ); //4.关闭 session.close(); }