day05-mybatis配置文件和SQL映射文件
Mybatis配置文件&SQL映射文件
1.配置文件-mybatis-config.xml
1.1基本说明
mybatis的核心配置文件(mybatis-config.xml),它的作用如配置jdbc连接信息,注册mapper等,我们需要对这个配置文件有详细的了解。
配置文档的顶层结构如下:

1.2properties(属性)
属性可以在外部进行配置,并可以进行动态替换(使用${})。既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。
(1)直接在properties元素的子元素中配置
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?
useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
(2)在外部配置,进行动态替换
jdbc.properties 属性文件:
.properties 属性文件需要统一放在 resource 目录/类加载路径
# The key value is arbitrary
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
jdbc.user=root
jdbc.pwd=123456
mybatis 配置文件:
要先引入 .properties 文件
<configuration>
<!--引入外部的jdbc.properties-->
<properties resource="jdbc.properties"/>
<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.pwd}"/>
</dataSource>
</configuration>
1.3settings(设置)
1.4typeAliases(别名处理器)
- 别名是Java命名一个短名称,它只和XML配置有关,用来减少类名重复的部分
- 如果指定了别名,我们的xxMapper.xml文件就可以做相应的简化处理
- 注意指定别名后,还是可以使用全名的
- 如果一个包下有很多的类,我们可以直接引入包,这样该包下面的所有类名都可以直接使用。
<typeAliases>
<!--如果一个包下有很多的类,可以直接使用包的方式引入,这样包下的所有类名都可以直接使用-->
<package name="com.li.entity"/>
</typeAliases>
1.5typeHandlers(类型处理器)
- 用于Java类型和jdbc类型映射
- Mybatis的映射基本已经满足,不太需要重新定义
- 这个我们默认即可,也就是mybatis会自动地将java和jdbc类型进行转换
- Java类型和jdbc类型映射关系一览 mybatis – MyBatis 3 | 配置

1.6environments(环境)
environments 元素定义了如何配置环境。
注意一些关键点:
- 默认使用的环境 ID(比如:default="development")。
- 每个 environment 元素定义的环境 ID(比如:id="development")。
- 事务管理器的配置(比如:type="JDBC")。
- 数据源的配置(比如:type="POOLED")。
默认环境和环境 ID 顾名思义。 环境可以随意命名,但务必保证默认的环境 ID 要匹配其中一个环境 ID。
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
1.7mappers(映射器)
现在就要来定义 SQL 映射语句了。 首先,我们需要告诉 MyBatis 到哪里去找到这些语句。你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:/// 形式的 URL),或类名和包名等。
(1)使用相对于类路基的资源引用
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
(2)使用完全限定资源定位符(URL),不推荐使用
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
(3)使用映射器接口实现类的完全限定类名
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
(4)将包内的映射器接口全部注册为映射器
<!-- 将包内的映射器接口全部注册为映射器
1.当一个包下有很多的xxMapper.xml文件和基于注解实现的接口时,为了方便,可以用包方式进行引用
2.将下面的所有xml文件和注解接口都进行注册-->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
2.SQL映射文件-xxMapper.xml
2.1基本介绍
Mybatis 的真正强大之处在于它的语句映射(在XxxMapper.xml中配置),如果拿它和具有相同功能的 JDBC代码进行对比,你会发现立即省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于SQL 代码。
SQL映射文件常用的顶级元素(按照应被定义的顺序列出):
cache - 该命名空间的缓存配置
cache-ref - 引用其他命名空间的缓存配置
resultMap - 描述如何从数据库的结果集 中加载对象,是最复杂也是最强大的元素
parameterType - 将会传入这条语句的参数的类全限定名或别名
sql - 可被其他语句引用的可重用语句块
insert - 映射插入语句
update - 映射更新语句
delete - 映射删除语句
select - 映射查询语句
2.2映射文件详细说明
2.2.1基本使用
insert,delete,update,select 这些在之前讲过,分别对应增删查改的方法和SQL语句的映射
如果获取到刚刚添加的Monster对象的id主键(获取自增长)也讲过了
<insert id="addMonster" parameterType="Monster" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `monster`
(`age`,`birthday`,`email`,`gender`,`name`,`salary`)
VALUES (#{age},#{birthday},#{email},#{gender},#{name},#{salary})
</insert>
2.2.2传入类型-POJO或String
- 当有多个条件时,传入的参数设为POJO/Entity类型的 Java对象,这样可以通过 POJO/Entity 对象的属性来接收传入的参数
- 传入 POJO/Entity 类型时,如果查询时需要有多个筛选条件,怎么在映射文件中处理?一般是使用
#{}的方式来获取入参的多个值(注意#{}内部的名称对应的是POJO对象的属性名,和表字段无关) - 当传入的参数类型为String时,则使用
${}的方式来接收传入的参数
应用案例
(1)MonsterMapper.java 接口
package com.li.mapper;
import com.li.entity.Monster;
import java.util.List;
/**
* @author 李
* @version 1.0
*/
public interface MonsterMapper {
//通过id或者名字查询
public List<Monster> findMonsterByNameOrId(Monster monster);
//查询名字中含有‘精’的妖怪
public List<Monster> findMonsterByName(String name);
}
(2)映射文件MonsterMapper.xml 实现接口方法
<mapper namespace="com.li.mapper.MonsterMapper">
<!--这里 #{}的值是从传入的参数的属性中获取的,`id`表示表的字段名,
这里的parameterType可以直接使用类名,是因为在mybatis的配置文件中配置了别名-->
<select id="findMonsterByNameOrId" parameterType="Monster" resultType="Monster">
SELECT * FROM `monster` WHERE `id` = #{id} OR `name` = #{name}
</select>
<!--当传入的参数类型为String时,使用${}的方式来接收参数-->
<select id="findMonsterByName" parameterType="String" resultType="Monster">
SELECT * FROM `monster` WHERE `name` LIKE '%${name}%'
</select>
</mapper>
(3)测试
package com.li.mapper;
import com.li.entity.Monster;
import com.li.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
/**
* @author 李
* @version 1.0
*/
public class MonsterMapperTest {
//属性
private SqlSession sqlSession;
private MonsterMapper monsterMapper;
//初始化
@Before
public void init() {
sqlSession = MybatisUtils.getSqlSession();
monsterMapper = sqlSession.getMapper(MonsterMapper.class);
System.out.println("monsterMapper=" + monsterMapper.getClass());
}
@Test
public void findMonsterByNameOrId() {
Monster monster = new Monster();
monster.setId(1);
monster.setName("狐狸精");
List<Monster> monsters =
monsterMapper.findMonsterByNameOrId(monster);
for (Monster m : monsters) {
System.out.println("m=" + m);
}
if (sqlSession != null) {
sqlSession.close();
}
System.out.println("findMonsterByNameOrId() 查询成功!");
}
@Test
public void findMonsterByName() {
List<Monster> monsters = monsterMapper.findMonsterByName("精");
for (Monster monster : monsters) {
System.out.println("monster=" + monster);
}
if (sqlSession != null) {
sqlSession.close();
}
System.out.println("findMonsterByName() 查询成功!");
}
}


2.2.3传入类型-Map
HashMap传入参数更加灵活,比如可以灵活地增加查询的属性,而不受POJO/Entity 类型本身属性的限制(因为POJO/Entity 类型的属性数量有限而且#{}中的名称必须为属性名)
例子-演示如何遍历一个List<Map<String,Object>> 的数据类型
(1)修改MonsterMapper.java,增加方法接口
//声明一个方法,传入参数是HashMap,查询 id>10 并且 salary>40 的所有妖怪
public List<Monster> findMonsterByIdAndSalary(Map<String, Object> map);
(2)修改MonsterMapper.xml映射文件,实现该方法
<!--声明一个方法,传入参数是HashMap,查询 id>5 并且 salary>40 的所有妖怪
这里使用 #{id}和 #{salary} 来获取入参 map的值时,意味着你的map需要有key为id和salary的键值对
事实上,map的 key 只要和 #{}中的 key一样即可,和表字段无关-->
<select id="findMonsterByIdAndSalary" parameterType="map" resultType="Monster">
SELECT * FROM `monster` WHERE `id`>#{id} AND `salary` > #{salary}
</select>
(3)测试
@Test
public void findMonsterByIdAndSalary() {
Map<String, Object> map = new HashMap<>();
map.put("id", 5);//这里设置的key只要和#{key}的key值一样即可,和表字段无关
map.put("salary", 40);
List<Monster> monsters = monsterMapper.findMonsterByIdAndSalary(map);
for (Monster monster : monsters) {
System.out.println("monster=" + monster);
}
if (sqlSession != null) {
sqlSession.close();
}
System.out.println("findMonsterByIdAndSalary() 查询成功!");
}

2.2.4传入&返回的类型都是Map
(1)修改MonsterMapper.java,增加方法接口
//传入和返回的类型都是Map
public List<Map<String, Object>> findMonsterByIdAndSalary2(Map<String, Object> map);
(2)修改MonsterMapper.xml映射文件,实现该方法
<!--查询 id>5 并且 salary>40 的所有妖怪,要求传入和返回的参数都是Map类型-->
<select id="findMonsterByIdAndSalary2" parameterType="map" resultType="map">
SELECT * FROM `monster` WHERE `id`>#{id} AND `salary` > #{salary}
</select>
(3)测试
@Test
public void findMonsterByIdAndSalary2() {
Map<String, Object> map = new HashMap<>();
map.put("id", 5);
map.put("salary", 40);
List<Map<String, Object>> monstersList = monsterMapper.findMonsterByIdAndSalary2(map);
//取出返回的结果-以map的形式
for (Map<String, Object> monsterMap : monstersList) {
System.out.println("monsterMap=" + monsterMap);
//遍历monsterMap,取出属性和对应的值
for (Map.Entry<String, Object> entry : monsterMap.entrySet()) {
System.out.println("key=" + entry.getKey() + "=>value=" + entry.getValue());
}
}
if (sqlSession != null) {
sqlSession.close();
}
System.out.println("findMonsterByIdAndSalary2() 查询成功!");
}

2.2.5resultMap结果集映射
当实体类属性和表的字段名字不一样时,我们可以通过resultMap进行映射,从而屏蔽实体类属性名和表的字段不一致可能出现的问题。
例子
(1)表user
-- 创建user表
CREATE TABLE `user`(
`user_id` INT NOT NULL AUTO_INCREMENT,
`user_email` VARCHAR(255) DEFAULT '',
`user_name` VARCHAR(255) DEFAULT '',
PRIMARY KEY(`user_id`)
)CHARSET=utf8
(2)创建实体类和表映射,这里故意设置和表字段不一样的属性名
package com.li.entity;
/**
* @author 李
* @version 1.0
*/
public class User {
private Integer userId;
private String userName;
private String userEmail;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", userEmail='" + userEmail + '\'' +
'}';
}
}
(3)创建接口 UserMapper.java
package com.li.mapper;
import com.li.entity.User;
import java.util.List;
/**
* @author 李
* @version 1.0
*/
public interface UserMapper {
//添加
public void addUser(User user);
//查询所有的User
public List<User> findAllUsers();
}
(4)创建映射文件 UserMapper.xm
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace指定该xml文件和哪个接口对应-->
<mapper namespace="com.li.mapper.UserMapper">
<!--完成添加用户的任务,注意这里的user属性和表的字段名不一致
这里的parameterType可以直接使用类名,是因为在mybatis的配置文件中配置了别名-->
<insert id="addUser" parameterType="User">
INSERT INTO `user`(`user_email`,`user_name`)
VALUE(#{userEmail},#{userName});
</insert>
<!--因为表字段的名称和实体类型的名称不一致
1.如果对象属性名和表字段不一样是,那么返回的数据就保存不进去,就会是对象的属性就是默认值
2.要解决这个问题,可以使用resultMap来解决这个问题
3.定义一个resultMap,它的id由你指定id,通过id可以引用这个resultMap
4.type 为返回的数据类型(可以使用别名)
5.column为表的字段,property为对象的属性名-->
<resultMap id="findAllUserMap" type="User">
<!--指定映射关系-->
<result column="user_email" property="userEmail"/>
<result column="user_name" property="userName"/>
</resultMap>
<select id="findAllUsers" resultMap="findAllUserMap">
SELECT * FROM `user`
</select>
</mapper>
(5)测试
package com.li.mapper;
import com.li.entity.User;
import com.li.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
/**
* @author 李
* @version 1.0
*/
public class UserMapperTest {
//属性
private SqlSession sqlSession;
private UserMapper userMapper;
//初始化
@Before
public void init() {
sqlSession = MybatisUtils.getSqlSession();
userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void addUser(){
User user = new User();
user.setUserName("marry");
user.setUserEmail("marry@qq.com");
userMapper.addUser(user);
if (sqlSession != null) {
//需要手动提交事务,因为mybatis事务默认为false
sqlSession.commit();
sqlSession.close();
}
System.out.println("插入成功!");
}
@Test
public void findAllUsers(){
List<User> allUsers = userMapper.findAllUsers();
for (User user : allUsers) {
System.out.println("user="+user);
}
if (sqlSession != null) {
sqlSession.close();
}
System.out.println("查询成功!");
}
}


resultMap注意事项和细节
除了使用resultMap,也可以使用字段别名解决表字段和对象属性不一致的问题,但是它的复用性不好,因此不推荐使用字段别名

如果是MyBatis-Plus处理就比较简单,可以使用@TableField来解决实体字段名和表字段名不一致的问题,还可以使用@TableName来解决实体类名和表名不一致的问题。
day05-mybatis配置文件和SQL映射文件的更多相关文章
- MyBatis 创建核心配置文件和 SQL 映射文件
Mybatis 的两个配置文件(mybatis-config.xml 和 xxxMapper.xml)都为 xml 类型,因此在 eclipse 中创建 xml 文件命名为相应的 mybatis-c ...
- MyBatis学习(四)XML配置文件之SQL映射的XML文件
SQL映射文件常用的元素: 1.select 查询语句是MyBatis最常用的语句之一. 执行简单查询的select元素是非常简单的: <select id="selectUser&q ...
- 初始MyBatis、SQL映射文件
MyBatis入门 1.MyBatis前身是iBatis,是Apache的一个开源项目,2010年这个项目迁移到了Google Code,改名为MyBatis,2013年迁移到GitHub.是一个基于 ...
- Mybatis sql映射文件浅析 Mybatis简介(三)
简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML为载体映射SQL 之前提到过,各项配置信息将Mybatis应用的整 ...
- Mybatis sql映射文件浅析 Mybatis简介(三) 简介
Mybatis sql映射文件浅析 Mybatis简介(三) 简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML ...
- MyBatis 的基本要素—SQL 映射文件
MyBatis 真正的强大在于映射语句,相对于它强大的功能,SQL 映射文件的配置却是相当简单.对比 SQL 映射配置和 JDBC 代码,发现使用 SQL 映射文件配置可减少 50% 以上的代码,并且 ...
- Mybatis(二) SQL映射文件
SQL映射文件 单条件查询 1. 在UserMapper接口添加抽象方法 //根据用户名模糊查询 List<User> getUserListByName(); 2. 在UserMappe ...
- Mybatis SQL映射文件详解
Mybatis SQL映射文件详解 mybatis除了有全局配置文件,还有映射文件,在映射文件中可以编写以下的顶级元素标签: cache – 该命名空间的缓存配置. cache-ref – 引用其它命 ...
- MyBatis -- sql映射文件具体解释
MyBatis 真正的力量是在映射语句中. 和对等功能的jdbc来比价,映射文件节省非常多的代码量. MyBatis的构建就是聚焦于sql的. sql映射文件有例如以下几个顶级元素:(按顺序) cac ...
- SSM - Mybatis SQL映射文件
MyBatis 真正的力量是在映射语句中.和对等功能的jdbc来比价,映射文件节省很多的代码量.MyBatis的构建就是聚焦于sql的. sql映射文件有如下几个顶级元素:(按顺序) cache配置给 ...
随机推荐
- 【Java EE】Day07 HTML
一.WEB概念 1.软件架构 C/S:安卓.QQ.迅雷,开发两端 B/S 2.资源分类 静态资源:浏览器内置解析引擎 HTML:展示内容 CSS:页面布局 JavaScript:控制页面元素,产生动态 ...
- 【每日一题】【排序sort重载】【工具类】2021年12月23日-31. 下一个排列
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数). 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须 ...
- Scanner例题讲解
Scanner例题讲解 题:输入多个平均数,求其总和与平均数;每输入一个数用回车确认,通过输入非数字来结束输入并输出执行结果 public class Demo05 { //输入多个平均数, ...
- 【Java】【数据库】B树
B-树的形式 (B-树就是B树, 而且'-'是一个连接符号,不是减号.) B树的结构如下 不同于B+树(关于B+树,我的这篇博客里有写:B+树)的一些特点: 数据 \(K_i\) 左边的树不会将 \( ...
- Sqlserver分布式跨数据库查询、Join,以及分布式事务
简言: 这篇文章我要谈一谈SQL Server分布式跨服务器查询,多表Join,以及分布式事务的处理 SqlServer跨服务器查询的方式 以往自己才疏学浅,学习了一波之后,在这记录下来. 1. 使用 ...
- CH32V307以太网(芯片内部10M)-针对新固件的Lib库
沁恒的CH32V307网络库在前段时间做了一个更新,相对于以前的Lib,主要的功能没有什么特别大的变化,但是底层的一些操作仔细看的话,还是不少的区别的. 首先,官方提供的例程,工程结构以及头文件优一些 ...
- MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(1)-后端项目框架搭建
前言: 前面的四个章节我们主要讲解了MongoDB的相关基础知识,接下来我们就开始进入使用.NET7操作MongoDB开发一个ToDoList系统实战教程. MongoDB从入门到实战的相关教程 Mo ...
- JUC源码学习笔记7——FutureTask源码解析,人生亦如是,run起来才有结果
系列文章目录和关于我 一丶我们在哪里会使用到FutureTask 基本上工作中和Future接口 打交道比较多,比如线程池ThreadPoolExecutor#sumbit方法,返回值就是一个Futu ...
- [cocos2d-x]关于屏幕适配
第一步:理解屏幕分辨率和设计分辨率 通过这个图可以很容易理解,设计分辨率就是你能够进行纹理绘制的大小,而屏幕分辨率就是你的画框大小.而两者之间的适配,通过cocos2dx自带的几种适配方案来进行适配, ...
- 02-RTL代码分析思路
RTL代码分析思路(这里不进行具体代码的分析) verilog文件是以.v结尾的 1 RTL代码示例 //Date : 2023-01-09 //E-mail : xxxxxx@163.com //c ...