IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MyBatis框架_学习笔记 -> 正文阅读

[大数据]MyBatis框架_学习笔记

MyBatis框架

  • 早期叫做 ibatis,代理在 Github
  • MyBatis 全称为 MyBatis SQL Mapper Framework for Java(基于Java 的 SQL 映射框架)

MyBatis 提供的功能

  • 提供了创建Connection,Statement,ResultSet等对象的能力,不需要开发人员重复创建

  • 提供了执行 SQL 语句的功能

  • 提供了循环 SQL,将结果转换为List对象的能力,不再需要开发人员进行迭代

  • 提供了关闭资源的能力

MyBatis 的使用

XXXMapper.xml 映射文件

<?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="name">

?? ?<!--parameterType可以是简单类型、引用类型、Map类型-->
?? ?<!--resultType可以是简单类型、引用类型、Map类型-->
?? ?<select id="" parameterType="" resultType=""></select>
?? ?
?? ?<!--模糊查询-->
?? ?<select id="" parameterType="" resultType="">
?? ??? ?select * from table where id like '%' #{id} '%';
?? ??? ?<!--'%'和#{}中的空格不能省去,相当于加号,拼接作用-->
?? ?</select>?? ?
</mapper>

文件解读

  1. 1.指定的约束文件
    <?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">
  2. 约束文件作用:用于限制和检查当前文件中出现的标签、属性是否符合语法规范
  3. namespace 应该使用 dao 接口的全限定名称(包名 + 类名)
  4. resultType 应该使用 domian 中的类全限定名称

mybatis.xml 主配置文件(用于连接数据库,放于src目录下)

<?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>
? ? <properties resource="db.properties"/><!--加载配置文件-->
? ? <!--
? ? ? ? 设置与数据库交互环境,例如二级缓存
? ? ? ? 在实际开发中,基本没用,因为优化效率太低
? ? -->
? ? <settings>
? ? ? ? <setting name="cacheEnabled" value="true"/><!--二级缓存-->
? ? ? ? <setting name="lazyLoadingEnabled" value="true"/><!--延迟加载-->
? ? ? ? <setting name="logImpl" value="STDOUT_LOGGING"/><!--开启日志-->
? ? </settings>

? ? <!--为domain起别名-->
? ? <typeAliases>
? ? ? ? <!--方式1-->
? ? ? ? <typeAlias type="全路径名称" alias="别名"/>

? ? ? ? <!--方式2-->
? ? ? ? <!--为一个包下所有domain起好了别名,别名为类名且不区分大小写-->
? ? ? ? <package name="包路径名">
? ? </typeAliases>

? ? <!--环境配置-->
? ? <environments default="development"> <!-- default必须与下列某一个id相同,表示当前使用的配置信息-->
? ? ? ? <environment id="development"> ?<!-- id为配置名称,可以随便取-->
? ? ? ? ? ? <transactionManager type="JDBC"/>
? ? ? ? ? ? <dataSource type="POOLED">
? ? ? ? ? ? ? ? <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
? ? ? ? ? ? ? ? <property name="url" value="jdbc:mysql://localhost:3306/framework?useSSL=false&amp;serverTimezone=UTC"/>
?? ?<!-- MySQL是8.0以上的版本,driver 和 url 的value 和以前不同,&amp; 等同于 &符号-->
? ? ? ? ? ? ? ? <property name="username" value="root"/>
? ? ? ? ? ? ? ? <property name="password" value="feifei123"/>
? ? ? ? ? ? </dataSource>
? ? ? ? </environment>
? ? </environments>

? ? <mappers>
? ? ? ? <!--适用于xml文件和dao文件不在一个目录下-->
? ? ? ? <mapper resource="xxx.Xxx.xml"/>
? ? ? ? <!--适用于xml文件和dao文件在一个目录下-->
? ? ? ? <mapper package="xxx"/>
? ? </mappers>
</configuration>

注意:

主配置文件的路径是以 / 为分隔,但是Mapper文件是以 . 分隔

各标签的先后顺序:

properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,

reflectorFactory,plugins,environments,databaseIdProvider,mappers

属性配置文件

  • 把数据库连接信息单独放置在一个文件中,和主配置文件分开

格式key=value
key和=和value之间不可用有空格隔开
key一般使用 . 做多级目录,例:java.driver

利用<properties resource=" ">在主配置文件中指定相关的配置文件
而在主配置文件中只用使用 ${key} 来获取相关的配置信息即可

关于transactionManager : 负责MyBatis的事物提交
type 的两种类型

  1. JDBC : 表示MyBatis底层调用JDBC的Connection对象进行commit 和 rollback
  2. MANAGED : 把MyBatis事物处理委托给其他容器(可以是一个服务器,也可以是一个框架(Spring框架))

关于dataSource :表示数据源
type的两种类型

  1. POOLED : 使用连接池
  2. UPOOLED : 不使用连接池
  3. JNDI:java命名和目录服务(类似Windows注册表)

由于XXXMapper文件与 dao 文件一同放在了 java 文件夹下,而不在resources 文件夹下,Maven在进行编译时是会自动跳过java文件夹下的资源文件的,因此我们需要手动的进行调整,让Maven将java文件夹下的资源文件也打包如target/classes中
解决方法??在pom.xml 中加入如下代码:

<build>
? ? <resources>
? ? ? ? ?<resource>
? ? ? ? ? ? ?<directory>src/main/java</directory>
? ? ? ? ? ? ? ? <includes>
? ? ? ? ? ? ? ? ? ? <include>**/*.properties</include>
? ? ? ? ? ? ? ? ? ? <include>**/*.xml</include>
? ? ? ? ? ? ? ? </includes>
? ? ? ? ? ? ?<filtering>false</filtering>
? ? ? ? ?</resource>
? ? ?</resources>
</build>

MyBatis 使用方法

public static void main(String[] args) throws Exception{
? ? ? ? InputStream in = Resources.getResourceAsStream("mybatis.xml");
? ? ? ? SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
? ? ? ? SqlSessionFactory factory = builder.build(in);
? ? ? ? SqlSession ?sqlSession = factory.openSession();
? ? ? ? String sqlId = "dao.StudentDao.selectAll";
? ? ? ? List<Student> students = sqlSession.selectList(sqlId);
? ? ? ? students.forEach(student -> System.out.println(student));
? ? ? ? sqlSession.close();
}

代码解读:

Resources: 负责读取主配置文件

Inputstream in = Resources.getResourceAsstrean ( "mybatis.xml");

SqlSessionFactoryBuilder :创建SqlSessionFactory对象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder (); //创建sqlsessionFactory对象
SqlSessionFactory factory = builder. build(in) ;

SqlSessionFactory :重量级对象,程序创建该对象耗时比较长,使用资源比较多。在整个项目中,有一个就够用了。(单例模式)

SqlSession sqlSession = factory.openSession() ;

openSession()方法说明:

  1. openSession() :无参数的,获取是非自动提交事务的sqlsession对象
  2. openSession (boolean): openSession (true)获取自动提交事务的sqlsession.

SqlSession :
SqlSession接口∶定义了操作数据的方法例如selectone(),selectList() ,insert () , update?()
注意:SqlSession 对象不是线程安全的,因此执行sql语句之前,和使用之后要分别开启和关闭保证其线程安全性。

Mybatis 默认手动提交事务

sqlSession.commit();?

在IDEA中添加模板文件

  • 选中 File --> Settings --> Editor --> File and Code Templates在其中添加一个文件并命名

MyBatis 动态代理

  • MyBatis 中为我们提供了一套动态代理机制

public static void main(String[] args){
? ? ? ? SqlSession sqlSession = MyBatis.getSqlSession();
? ? ? ? StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
? ? ? ? Student student = new Student("024","花木兰",22,"女");
? ? ? ? int num = studentDao.insertStudent(student);
? ? ? ? sqlSession.commit();
? ? ? ? System.out.println("影响行数:"+num);
}

sqlSession.getMapper(StudentDao.class) 通过反射机制获取到StudentDao接口的动态代理类
而在 studentDao.insertStudent(student) 直接使用动态代理接口的方法即可
方法的名字应该与 XXXMapper.xml 文件中的某个 id 相同

参数传递

  • parameterType:传入SQL语句的数据类型因为 MyBatis 具有反射机制,能够识别出数据类型,因此开发中一般不写

MyBatis 四种传值方式

使用@Param传值
接口方法:

List<Student> select(@Param("myid") String id)

sql 语句:

select * from table where id = #{myid};

不推荐使用,参数多时,一个一个命名困难

使用对象传值

select * from table where id = #{id} and name = #{name};

推荐使用,但是{ }中的名字必须是 domain 对象的属性名

按位置传值
按接口中的参数列表中参数的位置进行传输

select * from table where id = #{arg0} and name = #{arg1}

不推荐使用,可读性低,难以维护

Map传值
接口方法:

List<Student> select(Map<String,Object> map)

sql语句:

select * from table where id = #{id} and name = #{name};

推荐使用,但是{ }中的名字必须是 Map 中已有的 key

缺点:光看接口方法难以看出map中有几个参数,参数类型又是什么,并且保证key的正确性

# 和 $ 的区别

  • # 相当于 sql语句中的 ?,使用的是PrepareStatement对象,可以防止sql注入
  • $ 使用的是字符串拼接,一般用于替换列名或表名(即便如此也有可能被注入)

例如:select * from table order by ${colName};?
select * from ${tableName};

简单类型 (String + 基本数据类型) 可以直接写简写,不需要包名,不区分大小写
Map类型无法迭代,可以先使用 map.keySet() 获取 map集合的关键字集合,再对关键字集合进行迭代获取 value
当使用分组查询的时候,只能使用map来封装查询结果,而不能用domain,因为domain没有count属性

resultMap

  • 用于指定列名与java对象的属性对应的关系(支持复用)

使用情况:

  1. 自定义赋值给某个属性时
  2. SQL列名与对象属性名不相同时
<resultMap id="mapName" type="java全限定名">
?? ?<id column="id" property="id"/>?? ??? ??? ?<!--主键列-->
?? ?<result column="age" property="peopleAge"/>?? ??? ?<!--非主键列-->
</resultMap>
<select id="selectCount" resultMap="mapName">
?? ?select * from student;
</select>

PS:在sql 语句中用 as 来调整列名,也可以解决SQL列名与对象属性名不相同的问题

模糊查询

方法一

select * from table where name like #{name};

需要在接口方法中传入一个name的字符串,推荐使用

方法二

select * from table where name like "%" #{name} "%";

还是需要在接口方法中传入一个name的字符串,只是内容不同

动态 SQL

sql 的内容是变化的,可以根据条件不同获取到不同的sql语句
主要是where部分的变化
使用的是MyBatis提供的标签,<if> <where> <foreach>

<if> 标签

<if test="name != null and name != '' ">
?? ?and name = #{name}
</if>

当一个条件满足时,但是前面又没有其他条件时,多出来的and会导致sql语句报错(where and name = #{name})
因此我们会在where后面加入一个无关紧要的条件例如 1=1 这样来改善代码

where 1=1 and name = #{name};?

这样代码自然就不会报错了

<where> 标签

<where>
?? ?<if test="name != null and name != '' ">
?? ??? ?and name = #{name}
?? ?</if>
</where>

where 会将第一个多余的无效字符去除<foreach>标签

<froeach collection="" item="" open="" close="" separator="">
</foreach>

collection:表示接口方法中参数类型,如果是数组用array,如果是List用list
item:是自定义的集合成员变量(如果成员变量是对象,则用#{对象.属性}即可)
open:循环开始字符
close:循环结束字符
separator:集合成员之间的分隔符

open,close,separator 可以直接写在sql语句内,因此可以省去不写

代码片段

定义片段

<sql id="sql_1">
?? ?select * from table_1
</sql>

调用片段

<include refid="sql_1"> where id=#{id}

不推荐使用,可读性低

PageHelper(不属于MyBatis框架,国内作者创作)

maven

<dependency>
?? ?<groupId>com.github.pagehelper</groupId>
?? ?<artiactId>pagehelper</artiactId>
?? ?<version>5.1.10</version>
</dependency>

主配置文件

<plugins>
?? ?<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>

在进行查询前使用

PageHelper.startPage(页数,行数);
List<Student> students = dao.selectAll();
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:32:57  更:2021-12-24 18:34:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:31:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码