目录
MyBatis 框架
第一章 框架的概述
1.三层架构
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等等
2. 三层架构处理的流程
用户发起请求--->页面层--->业务逻辑层--->持久层--->数据库(mysql)
3. 为什么使用三层架构
-
结构清晰,耦合度低,各层分工明确
-
可维护性高,可扩展性高
-
有利于标准化
-
开发人员可以只关注整个结构中的其中某一层的功能实现
-
有利于各层逻辑的复用
4. 三层框架模式和框架
每一层对应着一个框架
-
界面层:---SpringMvc框架
-
业务层:---Spring框架
-
持久层:---MyBatis框架
5. 框架
-
什么是框架(framework)
框架:就是一个软件,完成了部分的功能。软件中类和类之间的方法调用都已经规定好了。通过这些可以完成某些功能。框架看作是模板。
框架是可以升级的,改造的。框架是安全的。
框架是对某一方面有用的,不是全能的。
6. 框架解决的问题
-
框架能实现技术的整合。
-
提供开发的效率。降低难度
7.jdbc访问数据库的优缺点
优点:
-
直观,好理解
缺点:
-
创建很多对象Connection,Statement,ResultSet
-
注册驱动
-
执行sql语句
-
把ResultSet转换Student,List集合
-
关闭资源
-
sql语句和业务逻辑代码混在一起
8. Mybatis框架
mybatis:是一个持久层框架,原名ibatis,2013年改名为 Mybatis。Mybatis可以操作数据库,对数据执行增删改查。看作是高级的 jdbc,解决jdbc的缺点。
mybatis能做什么?
-
注册驱动
-
创建jdbc中使用的Connection,Statement,ResultSet
-
执行sql语句,得到ResultSet
-
处理ResultSet,把记录集中的数据转为java对象,同时还能把java对象放到List集合。
-
关闭资源
-
实现sql语句和java代码的解耦合
mybatis的官网:mybatis – MyBatis 3 | 简介
第二章 Mybatis入门
1. 第一个例子
实现步骤:
-
创建student表(id,name,email,age)
-
新建maven项目
-
修改pom.xml
-
加入依赖mybatis依赖,mysql驱动,junit
-
在<build>加入资源插件
<!--资源插件:处理src/main/java目录中的xml--> <resources> <resource> <directory>src/main/java</directory><!--所在的目录--> <includes><!--包括目录下的.properties,.xml 文件都会扫描到--> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources>
-
-
创建实体类Student。定义属性,属性名和列名保持一致
-
创建Dao接口,定义操作数据库的方法
-
创建xml文件(mapper文件),写sql语句
mybatis框架推荐是把sql语句和Java代码分开
mapper文件:定义和dao接口在同一目录,一个表一个mapper文件
-
创建mybatis的主配置文件(xml文件):有一个,放在resources目录下
-
定义创建连接实例的数据源(DataSource)对象
-
指定其他mapper文件的位置
-
-
创建测试的内容
使用main方法,测试mybatis访问数据库
也可以使用junit访问数据库
2. 概念
-
自动提交:当你的sql语句执行完毕后,提交事务。数据库更新操作之间保存到数据
-
手动(手工)提交事务:在你需要提交事务的位置,执行方法,提交事务或者回滚事务。
3. Mybatis的一些重要对象
-
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()
-
4. 使用工具类和模板
-
创建模板,mapper文件模板和mybatis主配置文件模板
mapper文件模板
mybatis主配置文件模板
mapper:
<?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="dao接口的全限定名称">
<!--使用insert,update,delete,select标签写sql-->
<!-- <select id="selectBlog" resultType="Blog">-->
<!-- select * from Blog where id = #{id}-->
<!-- </select>-->
</mapper>
mapper主配置文件:
<?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>
<!--设置日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--配置数据源:创建Connection对象-->
<dataSource type="POOLED">
<!--driver:驱动的内容-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url 例如:"jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8"-->
<property name="url" value="${url}"/>
<!--用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--指定其他mapper文件的位置:
指定其他mapper文件的目的是找到其他文件sql语句-->
<mappers>
<!--
使用mapper的resource属性指定mapper文件的路径
这个路径是从target/classes路径开启的
使用注意:
resource="mapper文件路径,使用 / 分割路径"
一个mapper resource 指定一个mapper文件
-->
<!-- <mapper resource="org\example\dao\OrderDao.xml"/>-->
<!-- <mapper resource="org\example\dao\UserDao.xml"/>-->
<!--或者指定一个包
<package name="com.zd.dao"/>
-->
</mappers>
</configuration>
第三章 Mybatis代理实现数据库操作
1. dao代理
1.1 mybatis提供代理:
mybatis创建Dao接口的实现类对象,完成对sql语句的执行。mybatis创建一个对象代替你的dao实现类功能。
1.2 使用mybatis代理要求:
-
mapper文件中的namespace一定是dao接口的全限定名称
-
mapper文件中标签的id是dao接口方法名称
1.3 mybatis代理实现方式
使用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();
2. 理解参数
理解参数:通过java程序把数据传入到mapper文件中的sql语句。参数主要是指dao接口方法的形参.
2.1 priameterType
priameterType:表示参数的类型,指定dao方法的形参数据类型。这个形参的数据类型是给mybatis使用
mybatis在给sql语句的参数赋值时使用,PreparedStatement.setXXX(位置,值)
<!--
parametype:指定dao接口形参类型
这个属性的值可以使用 java类型的全限定名称或者 mybatis定义的别名
mybatis执行的sql语句:select id,name,email,age from student where id=?
? 是占位符,使用jdbc中的PreparedStatement执行这样的sql语句
PreparedStatement pst =conn.preparedStatement(select id,name,email,age from student where id=? );
给 ? 位置赋值
参数Integer,执行pst.setInt(1,1005);
参数String,执行pst.setString(1,"1005");
第一个用法:java全限定类型名称 parameterType=“java.lang.Integer”
第二个用法:mybatis定义的java类型的别名 parameterType=“int” 别名在mybatis帮助文档查看
parameterType:mybatis通过放射机制可以获取 dao接口方法方法参数的类型,可以不写
-->
<select id="selectById" parameterType="java.lang.Integer" resultType="org.example.domain.Student">
select id,name,email,age from student where id=#{studentId}
</select>
2.2 dao接口方法是一个简单类型的参数
StudentDao:
//dao接口的方法形参是一个简单类型的
//简单类型:java基本数据类型和String
Student selectByEmail(String email);
mapper文件:
<!--
dao接口是一个简单类型的参数
mapper文件,获取这个参数值,使用#{任意字符}
-->
<select id="selectByEmail" resultType="org.example.domain.Student">
select id,name,email,age from student where email=#{studentEmail}
</select>
2.3 dao接口方法有多个简单类型的参数
@Param:命名参数,在方法的形参前面使用的,定义参数名。这个名称可以用在mapper文件中。
dao接口,方法的定义
/*
多个简单类型的参数
使用@Param命名参数,注解是mybatis提供的
位置:在形参定义的前面
属性:value 自定义的参数名称
*/
List<Student> selectByNameOrAge(@Param("myname") String name,
@Param("myage") Integer age);
mapper文件:
<!--
多个简单类型的参数
当使用了@Param命名后,例如@Param("myname").
在mapper中,使用#{命名的参数},例如#{myname}
-->
<select id="selectByNameOrAge" resultType="org.example.domain.Student">
select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>
2.4 dao接口方法使用对象作为参数
方法的形参是一个java对象。这个java对象表示多个参数。使用对象的属性值作为参数使用
dao接口
/* 一个java对象作为参数(对象有属性,每个属性set,get方法) */ List<Student> selectByObject(Student student);
mapper文件
<!--
一个java对象作为方法的对象,使用对象是属性作为参数值使用
简单的语法:#{属性名},mybatis调用此属性的getXXX()方法获取属性值
-->
<select id="selectByObject" resultType="org.example.domain.Student">
select id,name,email,age from student where name=#{name} or age=#{age}
</select>
Student实体类 java对象
package org.example.domain;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
//set|get方法。。。
}
2.5 dao接口方法多个简单类型的参数,按位置
参数位置:dao接口中方法的形参列表,从左往右,参数位置是0,1,2.。。。
语法格式:#{arg0},#{arg1}.......
dao接口
/* 使用位置,获取参数 */ List<Student> selectByPosition(String name,Integer age);
mapper文件
<!-- mybatis版本3.5.1 使用位置获取参数值,dao接口方法是多个简单类型的参数 语法:#{arg0},#{arg1}....... --> <select id="selectByPosition" resultType="org.example.domain.Student"> select id,name,email,age from student where name=#{arg0} or age=#{arg1} </select>
2.6 dao接口参数是一个Map
map作为dao接口的参数,使用key获取参数值,语法格式#{key}
dao类
/* 使用Map作为参数 */ List<Student> selectStudentByMap(Map<String,Object> map);
mapper文件
<!-- 使用Map传递参数, 在mapper文件中,获取map的值,通过key获取的,语法:#{key} --> <select id="selectStudentByMap" resultType="org.example.domain.Student"> select id,name,email,age from student where name=#{myname} or age=#{myage} </select>
MyTest类
@Test public void testSelectMap(){ SqlSession session =MybatisUtil.getSqlSession(); StudentDao dao =session.getMapper(StudentDao.class); //使用map传递参数 Map<String,Object> data =new HashMap<>(); data.put("myname","李思思"); data.put("myage",20); List<Student> students = dao.selectStudentByMap(data); students.forEach(stu-> System.out.println("stu="+stu)); session.close(); }
3. #和$的区别
3.1 #占位符
语法:#{字符}
mybatis处理#{} 使用jdbc对象是PrepareStatement对象
<select id="selectById" parameterType="java.lang.Integer" resultType="org.example.domain.Student"> select id,name,email,age from student where id=#{studentId} </select> 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语句执行更安全
-
#{}常常作为列值使用的,位于等号的右侧,#{}位置的值和数据类型的值有关。
3.2 $占位符
语法:${字符}
mybatis执行${}占位符的sql语句
<select id="selectById" parameterType="java.lang.Integer" resultType="org.example.domain.Student"> select id,name,email,age from student where id=${studentId} </select> ${} 表示字符串连接符,把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注入的风险。有代码安全的问题
-
${}数据是原样使用的,不会区分数据类型。
-
${}常用作 表名或者列名,在能保证数据安全的情况下使用
4. 封装Mybatis输出结果
封装输出结果:Mybatis执行sql语句,得到ResultSet,转为java对象。
resultType,resultMap
4.1 resultType
resultType属性:在执行select时使用,作为<select>标签的属性出现的
resultType:表示结果类型,mybatis执行sql语句,得到Java对象的类型。它的值有两种
-
Java类型的全限定名称
-
使用别名
1.resultType:表示Java自定义对象
Student selectById(Integer id); <select id="selectById" parameterType="java.lang.Integer" resultType="org.example.domain.Student"> select id,name,email,age from student where id=#{studentId} </select> 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文件
<!-- 执行sql语句,得到是一个值 --> <select id="countStudent" resultType="java.lang.Long"> select count(*) from Student </select>
3.resultType:表示一个map结构
dao方法
//查询结果是一个Map Map<Object,Object> selectMap(@Param("stuid") Integer id);
mapper文件
<!-- 执行sql语句得到一个map结构数据,mabatis执行sql,把ResultSet转为map sql执行结果,列名做map的key,列值作为value sql执行得到是一行记录,转为map结构是正确的 dao接口返回是一个map,sql语句最多能获取一行记录,多余一行是错误 --> <select id="selectMap" resultType="java.util.HashMap"> select id,name from student where id=#{stuid} </select>
4.2 resultMap
resultMap:结果映射。自定义列名和java对象属性的对应关系。常用在列名和属性名不同的情况
用法:
-
先定义resultMap标签,指定列名和属性名称对应关系
-
在select标签使用resultMap属性,指定上面定义的resultMap的id值
mapper文件
<!--使用resultMap定义列和属性的关系--> <!--定义resultMap id:给resultMap的映射关系起个名称,唯一值 type:java类型的全限定名称 --> <resultMap id="customMap" type="org.example.vo.CustomObject"> <!--定义列名和属性名的对应--> <!--主键类型使用id标签--> <id column="id" property="cid"/> <!--非主键类型使用result标签--> <result column="name" property="cname"/> <!--列名和属性名相同可以不用定义--> </resultMap> <!--使用resultMap属性,指定映射关系的id resultType和resultMap不能同时用,二选一--> <select id="selectById2" resultMap="customMap"> select id,name,email,age from student where id=#{stuid} </select>
5. 使用别名
mybatis提供的对java类型定义简短,好记忆
自定义别名的步骤:
-
在mybatis主配置文件,使用typeAliase标签声明别名
-
在mapper文件中,resultType="别名"
声明别名(mybatis主配置文件):
<typeAliases> <!--第一种语法格式 type:java类型的全限定名称(自定义名称) alias:自定义别名 优点:别名可以自定义 确定:每个类型必须单独定义 --> <typeAlias type="org.example.domain.Student" alias="stu"/> <!--第二种方式 name:包名,mybatis会把这个包中所有类名作为别名(不用区分大小写) 优点:使用方便,一次给多个类定义别名 缺点:别名不能自定义,必须是类名 --> <package name="org.example.domain"/> </typeAliases>
mapper文件中使用
resultType="别名" <select id="selectById" parameterType="java.lang.Integer" resultType="stu"> select id,name,email,age from student where id=#{studentId} </select> 第二种方式: <select id="selectById" parameterType="java.lang.Integer" resultType="Student"> select id,name,email,age from student where id=#{studentId} </select>
6.列名和java对象属性名称不一样解决方式
-
使用resultMap:自定义列名和属性名称对应关系
-
使用resultType:使用列的别名,让别名和java对象属性名称一样
<!--使用列别名,解决列名和属性名不同的问题--> <select id="selectById3" resultType="org.example.vo.CustomObject"> select id as cid,name as cname,email,age from student where id=#{stuid} </select>
7.模糊查询 like
第一种方式:在java程序中,把like的内容组装好。把这个内容传入到sql语句中
dao方法
//like第一种方式 List<Student> selectLikeOne(@Param("name") String name);
mapper文件
<!--like第一种方式--> <select id="selectLikeOne" resultType="org.example.domain.Student"> select * from student where name like #{name} </select>
测试类
@Test public void testLikeOne(){ SqlSession session =MybatisUtil.getSqlSession(); StudentDao dao =session.getMapper(StudentDao.class); String name="%李%"; List<Student> students = dao.selectLikeOne(name); session.close(); students.forEach(stu-> System.out.println(stu)); }
第二种方式:在sql语句中,组织like内容。
sql语句like的格式:where name like "%"空格#{name}空格 "%"
第四章 动态sql
什么是动态sql:同一个dao的方法,根据不同的条件可以表示不同的sql语句,主要是where部分有变化
使用mybatis提供的标签,实现动态sql的能力,主要讲if,where,foreach,sql
使用动态sql的时候,dao方法的形参使用Java对象。
多条件查询时使用动态sql
1. if标签
语法:
<if test="boolean判断结果"> sql 代码 </if> 在mapper文件中 <select id="selectStudent" resultType="org.example.domain.Student"> select * from student <if test="条件"> sql语句 </if> <if test="条件"> sql语句 </if> </select>
例如:
dao:
List<Student> selectIf(Student student);
mapper文件
<select id="selectIf" resultType="org.example.domain.Student"> select * from student where id=-1 <if test="name!=null and name!=''"> or name=#{name} </if> <if test="age >0"> or age=#{age} </if> </select>
2. where标签
使用if标签时,容易引起sql语句语法错误。使用where标签解决if产生的语法问题
使用where,里面是一个或多个if标签,当有一个if标签判断条件为true,where标签会转为WHERE关键字附加到sql语句的后面。如果if没有一个条件为true,忽略where和里面的if
语法:
语法: <where> <if test="条件1">sql语句1</if> <if test="条件2">sql语句2</if> </where>
例如:
dao:
//where List<Student> selectWhere(Student student);
mapper文件
<select id="selectWhere" resultType="org.example.domain.Student"> select * from student <where> <if test="name!=null and name!=''"> or name=#{name} </if> <if test="age >0"> or age=#{age} </if> </where> </select>
3. foreach循环标签
使用foreach可以循环数据,list集合,一般使用在in语句中。
语法:
<froeach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" separtor="集合成员之间的分隔符"> #{item的值} </froeach> 标签属性: 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: List<Student> selectForeachOne(List<Integer> idlist); 测试类: @Test public void testSelectForeachOne(){ //1.获取SqlSession对象 SqlSession session = MybatisUtil.getSqlSession(); //2.获取dao的代理 StudentDao dao =session.getMapper(StudentDao.class); List<Integer> idlist =new ArrayList<>(); idlist.add(1001); idlist.add(1002); idlist.add(1003); List<Student> students = dao.selectForeachOne(idlist); students.forEach(stu -> System.out.println("stu="+stu) ); //4.关闭 session.close(); }
mapper文件
<select id="selectForeachOne" resultType="org.example.domain.Student"> select * from student <if test="list !=null and list.size>0"> where id in <foreach collection="list" open="(" close=")" separator="," item="myid"> #{myid} </foreach> </if> </select>
对象类型例子:
dao: List<Student> selectForeachTwo(List<Student> studentList); 测试类: @Test public void testSelectForeachTwo(){ //1.获取SqlSession对象 SqlSession session = MybatisUtil.getSqlSession(); //2.获取dao的代理 StudentDao dao =session.getMapper(StudentDao.class); List<Student> list =new ArrayList<>(); Student s1 =new Student(); s1.setId(1001); Student s2 =new Student(); s1.setId(1002); list.add(s1); list.add(s2); List<Student> students = dao.selectForeachTwo(list); students.forEach(stu -> System.out.println("stu="+stu) ); //4.关闭 session.close(); }
mapper文件
<!--foreach第二种方式,循环List<Student>--> <select id="selectForeachTwo" resultType="org.example.domain.Student"> select * from student <if test="list!=null and list.size>0"> where id in <foreach collection="list" open="(" close=")" separator="," item="stu"> #{stu.id} <!--stu是对象--> </foreach> </if> </select>
4. sql标签
sql标签表示一段sql代码,可以是表名,几个字段,where条件都可以,可以在其他地方复用sql标签的内容。
使用方式:
1.在mapper文件中定义sql代码片段 <sql id="唯一字符串">部分sql语句</sql> 2.在其他的位置,使用include标签引用某个代码片段 例如: <!--定义代码片段--> <sql id="selectStudent"> select * from student </sql> <sql id="studentFieldList"> id,name,email </sql> <!--if test:使用对象的属性值作为条件 --> <select id="selectIf" resultType="org.example.domain.Student"> <include refid="selectStudent"/> where id=-1 <if test="name!=null and name!=''"> or name=#{name} </if> <if test="age >0"> or age=#{age} </if> </select>
第五章 MyBatis配置文件
mybatis配置文件两大类:1 mybatis主配置文件;2 mybatis的mapper文件
-
mybatis主配置文件,提供mybatis全局设置的。包含的内容:日志,数据源,mapper文件位置
-
mapper文件:写sql语句的,一个表一个mapper文件
1. settings部分
settings是mybatis的全局设置,影响整个mybatis的运行。这个设置一般使用默认
2.typeAliase 别名
设置别名
<typeAliases> <!--第一种语法格式 type:java类型的全限定名称(自定义名称) alias:自定义别名 优点:别名可以自定义 确定:每个类型必须单独定义 --> <typeAlias type="org.example.domain.Student" alias="stu"/> <!--第二种方式 name:包名,mybatis会把这个包中所有类名作为别名(不用区分大小写) 优点:使用方便,一次给多个类定义别名 缺点:别名不能自定义,必须是类名 --> <package name="org.example.domain"/> </typeAliases>
3. environments 配置环境
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 <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <!--配置数据源:创建Connection对象--> <dataSource type="POOLED"> <!--driver:驱动的内容--> <property name="driver" value="com.mysql.jdbc.Driver"/> <!--连接数据库的url 例如:"jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8"--> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8"/> <!--用户名--> <property name="username" value="root"/> <!--密码--> <property name="password" value="123456"/> </dataSource> </environment> </environments>
4. 使用数据库属性配置文件
需要把数据库的配置信息放到一个单独文件中,独立管理。这个文件扩展名是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主配置文件:
<!--使用外部属性配置文件 resource:指定类路径下的某个属性配置文件 --> <properties resource="jdbc.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <!--配置数据源:创建Connection对象--> <dataSource type="POOLED"> <!--driver:驱动的内容--> <property name="driver" value="${jdbc.driver}"/> <!--连接数据库的url 例如:"jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8"--> <property name="url" value="${jdbc.url}"/> <!--用户名--> <property name="username" value="${jdbc.root}"/> <!--密码--> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments>
5. mapper标签
使用mapper指定其他mapper文件的位置
<!--第一种方式,resources="mapper的文件的路径" 优点:文件清晰。加载的文件是明确的。 文件的位置比较灵活。 缺点:文件比较多,代码量会比较大,管理难度大--> <mapper resources="org/example/dao/StudentDao.xml"/> <!--第二种方式,使用<package> name:包名,mapper文件所在的包名 特点:把这个包中所有的mapper文件,一次加载 使用要求: 1.mapper文件和dao接口在同一目录 2.mapper文件和dao接口名称完全一样。--> <package name="org.example.dao"/>
第六章 扩展 分页 PageHelper
1. mybatis通用分页插件
GitHub - pagehelper/Mybatis-PageHelper: Mybatis通用分页插件
PageHelper做数据分页,在你的select语句后面加入分页的sql内容,如果你使用的mysql数据库,它就是在select * from student 后面加入limit语句。
使用步骤:
-
加入依赖pagehelper依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version> </dependency>
-
在mybatis主配置文件,加入plugin声明
在<environments>之前加入 <plugins> <plugin interceptor ="com.github.pagehelper.PageInterceptor"/> </plugins>
-
在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); List<Student> students = dao.selectAllStudents(); students.forEach(stu -> System.out.println("stu="+stu) ); //4.关闭 session.close(); }