系列文章目录
本文章是在学完Mybatis之后,对知识点的一些相关的梳理。
文章目录
前言
1. 三层框架
- 界面层(视图层):完成与用户的交互,并向后台传输数据
- 业务逻辑层:主要用来处理业务逻辑,完成一定的业务功能
- 数据访问层:也可以称为持久层,主要用来进行数据库操作
对应的流行框架
- 界面层:SpringMVC
- 业务逻辑层:Spring
- 数据访问层:Mybatis
一、概述
简介:MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录[1]。
Mybatis中文文档
作用:增强的jdbc,用来访问数据库,进行增删查改等操作
二、新建Mybatis项目基本步骤
详细步骤参见文章Mybis简单示例入门
- 首先加入Maven的依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
- 创建dao接口,定义操作数据库的方法
- 新建Mapper文件,又被称为sql映射语句,注意写sql语句的时候需要和接口的方法相对应
- 创建Mybatis主配置文件,里面的内容不可缺少1)连接数据库需要的参数2)需要指定Mapper文件的位置
- 使用:利用得到的sqlSession对象的getMapper方法,得到接口对象,调用接口的方法操作数据库。
三、动态代理
这里的动态代理指的是Mybatis会根据配置文件找到对应的方法,通过反射拿到dao接口对象,再调用dao接口的方法就可以操作数据库。
使用方式
- 获取SqlSession对象
SqlSession s = SqlSessionFactory.openSession();
- 使用getMapper方法获取某个接口的对象
接口 sqldao = s.getMapper(接口.class)
- 使用dao接口的方法,调用方法就执行了mapper文件中对应的sql语句。
使用要求
1.dao接口和mapper文件放在同一个目录
2.dao接口名称和mapper文件名称一致
3.mapper文件中的namespace的值是dao接口的全限定名称
4.mapper文件中的<select>,<insert>,<update>,<delete>标签的id是接口中的方法名称
5.dao接口中不要使用重载方法,即同名不同参数的方法
四、参数
这里的参数指的是Mapper映射文件中写的sql语句,由于一般我们写的时候要预留很多可改变的参数,例如select * from stuEmp where id = ? or name=?
,这种形式的语句,写在Mapper映射文件中需要用#{}或者${}代替?。
使用要点
- 一个简单类型的参数:#{任意非关键字字符}
<select id="findById" resultType="com.lqz.jdbc.entity.Student">
select * from stuEmp where id = #{id}
</select>
- 多个简单类型的参数:使用@Param(“自定义名称”)
<select id="findByIdName" resultType="com.lqz.jdbc.entity.Student" >
select * from stuEmp where id=#{i} or name=#{n}
</select>
- 使用一个java对象
1)java对象的属性名直接放入#{}中,因为Mybatis可以通过反射取到相对应的属性名
2)使用参数的位置,语法#(arg0),#(arg1),如果Mybatis的版本是3.4之前,使用的是#(0),#(1)<select id="findByIdNameObject" resultType="com.lqz.jdbc.entity.Student" > select * from stuEmp where id=#{id} or name=#{name} </select>
<select id="findByIdNamePosition" resultType="com.lqz.jdbc.entity.Student" > select * from stuEmp where id=#{arg0} or name=#{arg1} </select>
- 使用Map对象作为参数,在语句中使用#{Map中的key}
Student findByNameId(Map<String,?> map);
<select id="findByNameId" resultType="student">
select * from stuEmp where id=#{aid} and name=#{aname}
</select>
@Test
public void test10(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StuDao mapper = sqlSession.getMapper(StuDao.class);
Map<String, String> map = new HashMap<>();
map.put("aid","1003");
map.put("aname","zhangsan");
Student byNameId = mapper.findByNameId(map);
System.out.println(byNameId);
}
五、#和$的区别
在Mapper文件中#和$都可以实现相对应的功能,可是俩者有什么区别。
- #是占位符形式,相当于java中的preparedstatement语句
- $是字符串拼接符形式,相当于java中的statement语句
- #的用法决定了该符号安全,并且执行效率高
- $有sql注入的风险,且执行效率低
- $唯一的优点,可以直接使用列名
六、Mybatis返回结果
在Mapper文件中,有<select>,<update>,<delete>,<insert>标签中有id,resultType,还有parameterType等,这里的resultType就是标签内部的sql语句返回的结果类型。
resultType
resultType里面要写类型的全限定名称
如果使用别名,可以在主配置文件中自定义别名
使用<typeAlias>或者使用<package name=“包名的全限定名称”/>
<configuration>
<typeAliases>
<!-- <typeAlias type="com.lqz.jdbc.entity.Student" alias="stu"/>-->
<package name="com.lqz.jdbc.entity"/>
</typeAliases>
</configuration>
resultMap
可以自定义列名和java对象的属性名的对应关系
列名和java对象属性名不一致的解决办法:
1.在sql语句中使用别名
2.使用resultMap定义
<mapper>
<resultMap id="resultMap" type="student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="password" property="password"/>
</resultMap>
</mapper>
七、动态sql语句
动态sql语句指的是利用Mybatis内置的标签<where>,<if>,<foreach>等可以灵活的根据条件拼接sql语句
标签
- if
判断条件,当条件为true,才会拼接if标签内部的sql语句 - where
在where标签内部可以内嵌多个if语句,并且可以灵活的根据条件去掉if里面多余的and或者or等。 - foreach
循环数组标签,一般用于Mysql语句多个同类型参数1.collection:表示接口中方法参数的类型,如果是数组就使用array,如果是list集合就使用list
2.item:自定义名称,表示数组或者集合的成员
3.open:拼接好的sql语句前面的字符,例如(1001,1002,1003),我们open的变量就是(。
4.close:循环结束的字符
5.separator:集合成员之间的分隔符
<select id="findStu" resultType="student">
select * from stuEmp
<where>
<if test="name!=null||name!='' ">
name=#{name}
</if>
<if test="password>0">
and password=#{password}
</if>
</where>
</select>
复用sql代码片段
用法:
- 先定义<sql id=“自定义名称”>sql语句,表名或者字段</sql>
- 使用的时候直接使用标签<include refid=“id的值”/>
<mapper>
<sql id="studentSql" >
select id,name,password from stuEmp
</sql>
</mapper>
八、Mybatis的主配置文件
1. 配置数据库相关参数
1)在resource目录中定义一个属性配置文件,xxx.properties
2)在mybatis主配置文件中使用标签<property>指定文件的位置,在需要使用的地方中使用${key}
<configuration>
<properties resource="jdbc.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
2. 配置Mapper文件位置
适用于在同一个目录下有多个mapper文件,在原本标识mapper文件的位置使用<package name="目标目录的全限定名/>
基于此,需要注意:
1.mapper文件名称需要和接口名称一致,并区分大小写
2.mapper文件和dao接口需要在同一个目录
<configuration>
<mappers>
<!-- <mapper resource="StuDao.xml"/>-->
<package name="com.lqz.jdbc.dao"/>
</mappers>
</configuration>
九、PageHelper分页
功能:实现多种数据库的分页功能,其实是调用了mysql的limit用法。
使用步骤
- 加入maven依赖
<dependency>
<groupId>com.githubpagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
- 在Mybatis主配置文件中加入plugin插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
- 在使用时,只需要在查询方法之前,加入PageHelper的startPage()方法,Mybatis就会自动调用。
@Test
public void test1(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StuDao mapper = sqlSession.getMapper(StuDao.class);
PageHelper.startPage(1,3);
List<Student> stuList = mapper.query();
stuList.forEach(System.out::println);
}