MyBatis-2
https://shimo.im/sheets/vCvGqWVX6RQRHy8C/MODOC/
sqlMapConfig.xml元素概述
功能:
-
xml申明
-
DTD约束
-
configuration核心根标签
-
environments配置数据库环境,可以有多个,default属性指定使用是哪一个
-
environment id id配置数据库环境,属性唯一标识
-
transactionManager type事务管理
-
datasource type 数据源信息
-
property name获取数据库连接信息
数据库连接配置文件引入
传递配置文件$符号
properties
- 作用:加载peoperties配置文件,并在核心配置文件中使用
- 使用:
- 利用properties标签加载propertie文件
- 利用$直接对应配置文件中的key
加载db.properties属性资源文件
<!--
加载外部的属性文件,自动在类路径下去找,将属性文件中所有的键和值加载到内存中
下面就可以通过${键名}获取值
resource:读取类路径下属性文件
url: 在网络上或本地其它路径读取属性文件
<properties url="file:///d:/db.properties"/>
<properties resource="db.properties"/>
如果内部和外部有同名键,先加载内部的,再加载外部,外部后加载会覆盖先加载的
-->
<properties resource="db.properties">
<!--在文档内定义键和值-->
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/day25"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/>
</properties>
sqlMapConfig.xml
<?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>
<!--在控制台显示SQL语句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--定义实体类别名-->
<typeAliases>
<package name="com.itheima.entity"/>
</typeAliases>
<!--
可以配置多个环境,每个环境配置有自己的id
类似于c3p0,可以有默认的配置,也可以有命名的配置.
创建会话工厂对象的时候,default表示默认使用哪个配置
-->
<environments default="default">
<!--环境变量-->
<environment id="default">
<!--
事务管理器:
1. JDBC:由JDBC来管理事务
2. MANAGED:由容器去管理事务,其实什么也没有做,事务由容器去操作(Spring等,Web服务器)
-->
<transactionManager type="JDBC"/>
<!--
数据源
1. POOLED:表示使用mybatis的数据源
2. UNPOOLED:不使用连接池,每次都自己创建连接,并且关闭连接
3. JNDI:Java Naming and Directory Interface 它是一种通过名字来获取web容器中资源的方式
-->
<dataSource type="POOLED">
<!--数据库的连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/${DataBase}"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载其它映射文件-->
<mapper resource="com/itheima/dao/UserMapper.xml"/>
<!-- <package name="com.itheima.dao"/>-->
</mappers>
</configuration>
起别名-TypeAliases
在实体类映射文件中,编写SQL语句属性
resultType=“com.itheima.entity.User”
可以在核心配置文件中使用typeAliaes来给实体类定义别名
- 类别名
- 包别名
<!--
给类型定义别名
子元素 typeAlias 属性:
type:指定实体类的完全限定名
alias:表示类的别名,可以省略。省略后默认就是类名,别名不区分大小
<typeAlias type="com.itheima.entity.User"/>
子元素:package 给整个包下实体类定义别名,别名就是类名
1. name属性指定要扫描包名
2. 如果有多个包在同一个父包下,只要配置父包就可以了,所有的子包会自动扫描
3. 也可以指定多个package来设置不同的名
-->
<typeAliases>
<package name="com.itheima.entity"/>
</typeAliases>
mappers
作用:加载外部的实体类映射文件,是XML配置文件
<!-- 加载其它映射文件 -->
<mappers>
<!--
子元素:mapper
属性:
resource:加载类路径下指定的配置文件,注:分隔符是/,而不是点号
url: 读取指定路径下配置文件,或者网络的配置文件
<mapper url="file:///d:/UserMapper.xml"/>
class: 指定接口的完全限定名,用于注解的配置,不需要XML文件。
<mapper class="com.itheima.dao.UserMapper"/>
子元素:package
1. 指定扫描哪个包下所有的DAO接口,如果使用这种写法,接口名与配置文件名字要相同。
如:接口名UserMapper.java 配置文件名:UserMapper.xml
2. 接口与配置文件必须放在同一个包下
-->
<package name="com.itheima.dao"/>
配置标签名称 | 功能 | 属性或子元素 |
---|---|---|
properties | 加载外部的配置文件 | 属性 resource:加载类路径下配置文件 属性 url:加载网络上或其它地址配置文件 子元素:property:在文档内部定义键和值, 同名的键会被外面的文件覆盖 |
typeAliases | 给实体类定义别名 | 子元素 typeAliase: 每一行定义一个类别名 子元素 package: 对整个包和子包定义别名,别名就是类名 |
mappers | 加载实体类映射文件路径 | 子元素 mapper: 每一行加载一个外面的映射文件 子元素 package: 对整个包扫描,加载所有的映射文件 |
三层架构
- 控制层(web,controller,servlet)
- 业务层(service:参数校验)
- 持久层(dao,mapper)
Log4J
作用:能够输出执行的sql信息
使用:
- 导包
- 修改配置文件
- mabatis
- log4j
级别:
-
debug:用于开发的级别,所有的信息全部输出
-
info:只输出一般的信息
-
warn:只输出警告的信息
-
error:只输出错误的信息
-
fatal:只输出致命的错误信息
动态代理
代理模式的组成
作用:对真实角色功能的增强,真实角色和代理角色都是抽象角色的子类
- 抽象角色:定义了要实现的功能,通常使用接口。这个案例中就是UserMapper接口
- 真实角色:可以不存在的,这里没有
- 代理角色:也实现了接口中方法,使用动态代理来实现UserMapper接口,并且重写其中方法: findAllUsers()
动态代理的好处
- 接口的代理对象由程序在执行的过程中动态生成,不用我们自己去写一个类实现接口中所有的方法
- 可以动态生成任意接口的对象
接口代理
Dao层接口实现代理方式
传统方式实现 Dao 层,我们既要写接口,还要写实现类。而 MyBatis 框架可以帮助我们省略编写 Dao 层接 口实现类的步骤。程序员只需要编写接口,由 MyBatis 框架根据接口的定义来创建该接口的动态代理对象。
实现规则
- 映射配置文件中的名称空间必须和 Dao 层接口的全类名相同。
- 映射配置文件中的增删改查标签的 id 属性必须和 Dao 层接口的方法名相同。
- 映射配置文件中的增删改查标签的 parameterType 属性必须和 Dao 层接口方法的参数相同。
- 映射配置文件中的增删改查标签的 resultType 属性必须和 Dao 层接口方法的返回值相同。
代码实现
- 删除 mapper 层接口的实现类。
- 修改映射配置文件。
- 修改 service 层接口的实现类,采用接口代理方式实现功能。
- 获取动态代理对象 SqlSession 功能类中的 getMapper() 方法。
代码问题
不同点
- sql的id不同
- 返回值不同
- 参数可能不同
解决重复代码
实现dao层
实现规则
动态sql
- 动态 SQL 指的就是 SQL 语句可以根据条件或者参数的不同进行动态的变化。
- 条件标签。
- :条件判断的标签。
- 循环遍历的标签。
- :抽取 SQL 片段的标签。
- :引入 SQL 片段的标签。
//eg:
<select id="selectCondition" resultType="student" parameterType="student">
<include refid="select"/>
<where>
<if test="sid != null">
sid = #{sid}
</if>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
<select id="selectByIds" resultType="student" parameterType="list">
<include refid="select"/>
<where>
<foreach collection="list" open="sid IN (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
sql片段抽取
我们可以将一些重复性的 SQL 语句进行抽取,以达到复用的效果
:抽取 SQL 语句标签。
抽取的 SQL 语句
:引入 SQL 片段标签。
<include refid==“片段唯一标识”/>
分页插件
-
在企业级开发中,分页也是一种常见的技术。而目前使用的 MyBatis 是不带分页功能的,如果想实现分页的 功能,需要我们手动编写 LIMIT 语句。但是不同的数据库实现分页的 SQL 语句也是不同的,所以手写分页 成本较高。这个时候就可以借助分页插件来帮助我们实现分页功能。
-
PageHelper:第三方分页助手。将复杂的分页操作进行封装,从而让分页功能变得非常简单。
实现步骤
- 导入 jar 包。
- 在核心配置文件中集成分页助手插件。
- 在测试类中使用分页助手相关 API 实现分页功能。
相关参数
PageInfo:封装分页相关参数的功能类。
核心方法:
- long getTotal() 获取总条数
- int getPages() 获取总页数
- int getPageNum() 获取当前页
- int getPageSize() 获取每页显示条数
- int getPrePage() 获取上一页
- int getNextPage() 获取下一页
- boolean isIsFirstPage() 获取是否是第一页
- boolean isIsLastPage() 获取是否是最后一页
idea实用小技巧
-
查看idea中的文件的历史记录
右键文件
localhistory
local…
-
ctrl F ctrl r 查找替换文件
l() 获取总条数
- int getPages() 获取总页数
- int getPageNum() 获取当前页
- int getPageSize() 获取每页显示条数
- int getPrePage() 获取上一页
- int getNextPage() 获取下一页
- boolean isIsFirstPage() 获取是否是第一页
- boolean isIsLastPage() 获取是否是最后一页
idea实用小技巧
-
查看idea中的文件的历史记录
右键文件
localhistory
local…
-
ctrl F ctrl r 查找替换文件