简介:
mybatis是对jdbc功能进行封装:
1.提供统一数据库信息配置,统一放在xml文件
2.将sql提取到一个xml文件,提供动态sql功能
3.提供结果自动映射,封装
4.对jdbc原生接口进行封装,提供mybatis接口和类
环境搭建
1.创建对应的表以及表对应的实体类
2.导入 MyBatis jar 包,mysql 数据库驱动包,添加相关依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
</dependencies>
3.创建Mybatis全局配置文件
<?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>
<!--配置的是数据库连接信息-->
<environments default="development">
<environment id="development">
<!--数据库事务管理配置-->
<transactionManager type="JDBC"/>
<!--
数据源配置 type="POOLED" 使用数据库连接池
-->
<dataSource type="POOLED">
<property name="driver" value="${classDriverName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${uname}"/>
<property name="password" value="${pwd}"/>
</dataSource>
</environment>
</environments>
</configuration>
4.创建sql映射文件
<?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="接口地址">
定义 sql 语句
</mapper>
5.定义接口,在接口中定义方法
6.测试Mybatis
读取配置文件
//读取核心配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
创建 SqlSessionFactory
//创建SqlSessionFactory,用来封装配置信息,由于SqlSessionFactory对象创建开销较大,所以一个项目只创建一个
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
创建 SqlSession
//SqlSession用来每次与数据库会话使用,每交互一次创建一个SqlSession
SqlSession sqlSession = sessionFactory.openSession();
获得接口代理对象
//AdminDao.class(拿到类被加载到内存中的class对象)
//创建了接口的代理对象
AdminDao adminDao = sqlSession.getMapper(AdminDao.class);
//由代理对象调用与接口方法中相同id的sql
Admin admin = adminDao.findAdminById(1);
System.out.println(admin);
//关闭sqlsession
sqlSession.close();
单元测试插件:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>provided</scope>
</dependency>
添加注解标签即可正常执行
public class Test1 {
@Test
public void find(){
System.out.println("aaa");
}
@Test
public void save(){
System.out.println("bbb");
}
}
· Mybatis日志
Mybatis 内置的日志工厂提供日志功能,具体的日志实现有以下几种方式:
SLF4J|LOG4J|JDK_LOGGINGCOMMONS_LOGGING|STDOUT_LOGGING
配置日志
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
参数传递
1.单个参数直接传递
<select id="findAdminById" parameterType="int" resultType="Admin">
select id,account,password from admin where id = #{id}
</select>
2.多个参数使用@Param(“id”)绑定
@Test
public void login(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
AdminDao adminDao = sqlSession.getMapper(AdminDao.class);
Admin admin = adminDao.login("admin", "111");
sqlSession.close();
}
public interface AdminDao {
Admin login(@Param("acc") String account, @Param("pwd") String password);
}
<mapper namespace="com.dao.AdminDao" >
<select id="login" resultType="com.model.Admin">
select * from admin where account=#{acc} and password=#{pwd}
</select>
</mapper>
3.如果传入一个复杂的对象,就需要使用 parameterType 参数进行类型定义
Admin login1(Admin admin);
@Test
public void login(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
AdminDao adminDao = sqlSession.getMapper(AdminDao.class);
adminDao.login("admin", "111");
Admin admin = new Admin();
admin.setAccount("admin");
admin.setPassword("111");
adminDao.login1(admin);
sqlSession.close();
}
<select id="login1" parameterType="Admin" resultType="Admin">
select * from admin where account=#{account} and password=#{password}
</select>-->
· #{} 和 ${} 区别
#{} 占位符,是经过预编译的,编译好 SQL 语句再取值,#方式能够防止 sql 注入
#{}:select * from t_user where uid=#{uid}
${} 拼接符,会传入参数字符串,取值以后再去编译 SQL 语句,$方式无法防止 Sql
注入 ${}
${}:select * from t_user where uid= '1'
注意:MyBatis 排序时使用 order by 动态参数时需要注意,用$而不是#
· resultType、resultmap的区别?
一、对象不同
1、resultmap:resultMap如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列
名和pojo属性名之间作一个映射关系。
2、resultType:resultType使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一
致,该列才可以映射成功。
二、描述不同
1、resultmap:resultMap对于一对一表连接的处理方式通常为在主表的pojo中添加嵌套另一个表的
pojo,然后在mapper.xml中采用association节点元素进行对另一个表的连接处理。
2、resulTtype:resultType无法查询结果映射到pojo对象的pojo属性中,根据对结构集查询遍历的需
要选择使用resultType还是resultMap。适用于单表查询。
三、类型适用不同
1、resultmap:mybatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用
resultMap。
2、resulttype:resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,但是
resultType跟resultMap不能同时存在。
@Select("select num,name from student where id = #{id}")
void selectStudent(int id);
@Update("update student set num=1003 where id = #{id}")
void updateStudent(int id);
@Delete : 删除 sql, 和 xml delete sql 语法完全一样
@Delete("delete from student where id = #{id}")
void deleteStudnet(int id);
动态SQL
Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动
态拼接sql的功能,Mybatis提供了9种动态sql标签
trim|where|set|foreach|if|choose|when|otherwise|bind。
执行原理:使用ognl从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来
完成动态sql的功能。
·特殊符号处理
标记语言中,特殊符号处理
方式 1:使用一些转义符号处理
特殊字符 转义字符
< < > > " " ’ ' & &
方式 2:可以使用<![CDATA[]]>来包裹特殊字符。
<if test="id != null"> AND <![CDATA[ id <> #{id} ]]> </if>
<![CDATA[ ]]>是 XML 语法。在 CDATA 内部的所有内容都会被解析器忽略
<if> </if>
<where> </where>
<choose> </choose>
<trim> </trim>
等这些标签都不会被解析,所以 我们只把有特殊字符的语句放在 <![CDATA[ ]]> 尽量缩小<![CDATA[ ]]>
的范围。
·缓存(Cache)
为了见去数据库的压力,提高查询性能。缓存实现的原理 是从数据库中查询出来的对象在使用完后不要销毁,而是存储在内存(缓存)中, 当再次需要获取该对象时,直接从内存(缓存)中直接获取,不再向数据库执行 select 语句,从而减少了对数据库的查询次数,因此提高了数据库的性能。将一些数据临时存储,为了更快的获取到数据。
缓存功能:因为mysql数据存储在硬盘中,访问量过大(IO次数大),可能会导致数据库崩溃,可以将一些数据存储在内存中,这样就可以从内存中直接获取数据,速度快。
Mybatis有一级缓存和二级缓存,默认开启了一级缓存。
一级缓存:
同一个Sqlsession中若有两次相同的查询只发送一次sql,它将查询到的数据默认缓存到sqlsession中。从而提高查询效率。若中间执行了增删改等操作,一级缓存也会清空。当一个 sqlSession 结束后sqlSession 中的一级缓存也就不存在了。
sqlSession.clearCache(); //清除一级缓存
二级缓存:
二级缓存是SqlSessionFactory级别的,SqlSessionFactory只有一个。SqlSession1创建,查询到的数据放在SqlSessionFactory中,SqlSession1销毁。
SqlSession2创建,仍然可以拿到SqlSessionFactory中的数据