目录
2.导入MyBatis jar包,mysql 数据库驱动包于pom.xml文件中
一、MyBatis
MyBatis历史:其原是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation 迁移到了 Google Code,随着开发团队转投Google Code 旗下, iBatis3.x正式更名为MyBatis。
功能:MyBatis 是一款优秀的持久层框架(同数据库链接交互的一层)。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
1.MyBatis环境搭建
1.创建一张数据库表以及表对应的类
2.导入MyBatis jar包,mysql 数据库驱动包于pom.xml文件中
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
3.创建MyBatis全局配置于mybatis.xml中
<!--此乃Mybatis核心全局配置文件-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 使用数据库链接池对象-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
4.注册映射文件
5.定义接口
定义接口并在接口中定义抽象方法
6.创建Sql映射文件
在配置映射的adminMapper文件中进行配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace ="com.wjc.mybatis.dao.AdminDao">
其中<mapper namespace>中记载的是接口的地址,然后再映射该接口中抽象方法。
为类配置别名
类名实际上是类的地址加名字即typeAlias type="com.wjc.mybatis.model.Admin,我们需要为其配置一个别名方可方便使用(在mybatis.xml中)
接口和映射的关系
7.测试MyBatis
2.MyBatis日志
MyBatis日志可以将我们运行的代码内容打印出来
配置在mybatis.xml中:
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
3.参数传递
在映射配置中,id为其方法名称,parameterType为其参数类型,resultType为该方法返回值类型。
3.1单一参数传递
该抽象方法findAdminById只有一个整形参数,返回结果类型为Admin,故映射中parameter为int,resultType为Admin
3.2多个参数传递
3.2.1使用@Param绑定
此方法中有两个参数String account 和 String password,对他们进行绑定
在映射中,无需写parameterType,只要在使用过程中直接写我们绑定的新名字即可
3.2.2使用对象封装数据
在传参较多时,我们可以将参数封装在一个对象中。
调用者先将参数封装在对象中
方法的形参也是为对象的类型
在配置映射的时候,parameterType为对象的类型,然后直接在方法体中调用对象中的属性,但是直接写属性名称即可,无需增加对象名调用。
4.数据库连接池
数据库连接池在初始时创建了数据库连接对象,我们可以直接对其进行使用,以提高效率。
我们定义的数据库连接对象在close后会被销毁,而连接池里的对象不会销毁,只是重新回到连接池里。
5.增删改查
其中:
useGeneratedKeys="true" 返回自增主键
keyProperty="id" 定义接收属性
keyColumn="id" 定义数据库中的主键列
将这三个添加在数据中,可以返回当前行的主键列值。
1.#{}和${}
二者底层实现不同:
#{}是一个占位符,采用预编译,可以有效防止sql注入,攻击数据库。更加安全
${}是采用字符串拼接,直接将值拼接到sql中。
使用场景不同:
#{}用于向sql进行值传递,向数据库中的列传递值
${}用于向sql中动态传递列名可以用于动态排序(order)
2.关联表查询
现有学生表和专业表,一个学生属于一个专业,一个专业有多个学生。
关联查询都需要用到resultMap来添加映射,不同的是,在处理结果集的时候,如果主表和副表是多对一的关系,那么则使用association,如果是一对多则使用collection
1.从学生表查信息
学生和专业是多对一的关系,因此使用了association
方式一:
这里有两个查询,一是只查询一组数据,一是查询多组数据,二者查询内容相同,因此采用了同一映射。
方式二:嵌套查询
逻辑顺序如下:
1.先查询主表的信息(包含用来连接副表的外键majorid)
2.对副表进行查询
2.在专业表中查信息
专业和学生是一对多的关系,因此使用了collection
方式一:
方式二
嵌套查询
6.动态Sql
动态Sql即意在Sql中添加逻辑语句
1.if语句
if test属性成立,则执行标签体,否则不执行
当if语句成立时则动态添加where语句,如果标签返回的内容是以AND 或OR 开头,它会剔除掉AND或OR.
我们向方法中传入一个teacher对象,因为他num,name和gender都非空,因此查询结果和我们输入的对象的值结果一样。
2.trim语句
trim可以自定义首部,prefixOverride="and|or"的意思是,当首部结果中出现and或者or,会自动将其覆盖剔除掉
3.when chose otherwise
当when标签中的内容成立时,则选择其中的内容,如果不成立则选择otherwise中的内容,when标签可以有多个,但是otherwise只能有一个
4.set
set标签,可以去除标签中结果的逗号
5.批量删除
6.查询某些列的元素
特殊处理符号
在mybatis的xml文件中,一些特殊符号>、<、"、'、&正常书写会被mybatis误解,因此需要进行特殊处理
1.使用转义字符
< <
> >
" "
' &apos
& &
2.使用<![CDATA[]]>将特殊字符包裹.这样就能正常显示
缓存
当我们对数据库进行查询时,如果没有缓存那么每次查询都要对数据库进行访问. 如果将本次访问的结果储存在缓存中,那么下一次查询就无需再访问数据库,直接从缓存中获得我们需要的内容即可.从而减少了查询的次数,有效的提升了数据库的性能.
sqlSession 执行 insert、update、delete 等操作 commit 提交后会清空缓存区 域,防止脏读。
1.一级缓存
一级缓存是以SqlSession为单位对缓存进行存储的,同一个SqlSession对象中的操作可以共享缓存数据.这是mybatis默认开启的.
studao和studao02都是同一SqlSession下的对象,因此在两次查询中,studao2使用了studao查询后留下的缓存,没有向数据库发送查询语句.
2.二级缓存
二级缓存储存对象级别更高,以SqlSessionFactory为单位进行存储,即同一SqlSessionFactory下的对象查询操作共享缓存数据
2.1二级缓存配置
因为mybatis默认是不开启二级缓存的,因此我们想要使用需要自己开启
1.在mybatis.xml全局核心配置文件中,添加setting标签语句
<setting name="cacheEnabled" value="true"/>
2.对象序列化
但凡查询和结果有关的类,都要进行序列化(实现Serializable接口).
3.配置映射文件
在映射文件中添加<cache>标签,以开启缓存,flushInterval表示的是缓存的保存时间单位是毫秒
2.2二级缓存示例
该方法中有两个SqlSession对象.如果是一级缓存,则会查询两次.是二级缓存则查询一次
我们看到studao和studao02属于两个不同的SqlSession对象,但是还是只进行了一次查询,原因就是他们同属于一个SqlSessionFactory对象.共享了缓存,后来者studao02并未对数据库进行查询,直接在缓存中获得了查询结果.
二级缓存并非是在查询后立刻将数据存放在SqlSessionFactory中,而是在当前SqlSession已经执行close后再将数据从SqlSession转移到SqlSessionFactory中