Mybatis配置文件&SQL映射文件

1.配置文件-mybatis-config.xml

1.1基本说明

mybatis的核心配置文件(mybatis-config.xml),它的作用如配置jdbc连接信息,注册mapper等,我们需要对这个配置文件有详细的了解。

文档地址:mybatis – MyBatis 3 | 配置

配置文档的顶层结构如下:

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&amp;useUnicode=true&amp;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&amp;useUnicode=true&amp;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(设置)

mybatis – MyBatis 3 | 配置

1.4typeAliases(别名处理器)

  1. 别名是Java命名一个短名称,它只和XML配置有关,用来减少类名重复的部分
  2. 如果指定了别名,我们的xxMapper.xml文件就可以做相应的简化处理
  3. 注意指定别名后,还是可以使用全名的
  4. 如果一个包下有很多的类,我们可以直接引入包,这样该包下面的所有类名都可以直接使用。
<typeAliases>
<!--如果一个包下有很多的类,可以直接使用包的方式引入,这样包下的所有类名都可以直接使用-->
<package name="com.li.entity"/>
</typeAliases>

1.5typeHandlers(类型处理器)

  1. 用于Java类型和jdbc类型映射
  2. Mybatis的映射基本已经满足,不太需要重新定义
  3. 这个我们默认即可,也就是mybatis会自动地将java和jdbc类型进行转换
  4. 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 – MyBatis 3 | XML 映射器

  1. Mybatis 的真正强大之处在于它的语句映射(在XxxMapper.xml中配置),如果拿它和具有相同功能的 JDBC代码进行对比,你会发现立即省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于SQL 代码。

  2. SQL映射文件常用的顶级元素(按照应被定义的顺序列出):

    • cache - 该命名空间的缓存配置

    • cache-ref - 引用其他命名空间的缓存配置

    • resultMap - 描述如何从数据库的结果集 中加载对象,是最复杂也是最强大的元素

    • parameterType - 将会传入这条语句的参数的类全限定名或别名

    • sql - 可被其他语句引用的可重用语句块

    • insert - 映射插入语句

    • update - 映射更新语句

    • delete - 映射删除语句

    • select - 映射查询语句

2.2映射文件详细说明

2.2.1基本使用

  1. insert,delete,update,select 这些在之前讲过,分别对应增删查改的方法和SQL语句的映射

  2. 如果获取到刚刚添加的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

  1. 当有多个条件时,传入的参数设为POJO/Entity类型的 Java对象,这样可以通过 POJO/Entity 对象的属性来接收传入的参数
  2. 传入 POJO/Entity 类型时,如果查询时需要有多个筛选条件,怎么在映射文件中处理?一般是使用#{}的方式来获取入参的多个值(注意#{}内部的名称对应的是POJO对象的属性名,和表字段无关)
  3. 当传入的参数类型为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注意事项和细节

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

  2. 如果是MyBatis-Plus处理就比较简单,可以使用@TableField来解决实体字段名和表字段名不一致的问题,还可以使用@TableName来解决实体类名和表名不一致的问题。

day05-mybatis配置文件和SQL映射文件的更多相关文章

  1. MyBatis 创建核心配置文件和 SQL 映射文件

    Mybatis 的两个配置文件(mybatis-config.xml  和 xxxMapper.xml)都为 xml 类型,因此在 eclipse 中创建 xml 文件命名为相应的 mybatis-c ...

  2. MyBatis学习(四)XML配置文件之SQL映射的XML文件

    SQL映射文件常用的元素: 1.select 查询语句是MyBatis最常用的语句之一. 执行简单查询的select元素是非常简单的: <select id="selectUser&q ...

  3. 初始MyBatis、SQL映射文件

    MyBatis入门 1.MyBatis前身是iBatis,是Apache的一个开源项目,2010年这个项目迁移到了Google Code,改名为MyBatis,2013年迁移到GitHub.是一个基于 ...

  4. Mybatis sql映射文件浅析 Mybatis简介(三)

    简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML为载体映射SQL 之前提到过,各项配置信息将Mybatis应用的整 ...

  5. Mybatis sql映射文件浅析 Mybatis简介(三) 简介

    Mybatis sql映射文件浅析 Mybatis简介(三)   简介 除了配置相关之外,另一个核心就是SQL映射,MyBatis 的真正强大也在于它的映射语句. Mybatis创建了一套规则以XML ...

  6. MyBatis 的基本要素—SQL 映射文件

    MyBatis 真正的强大在于映射语句,相对于它强大的功能,SQL 映射文件的配置却是相当简单.对比 SQL 映射配置和 JDBC 代码,发现使用 SQL 映射文件配置可减少 50% 以上的代码,并且 ...

  7. Mybatis(二) SQL映射文件

    SQL映射文件 单条件查询 1. 在UserMapper接口添加抽象方法 //根据用户名模糊查询 List<User> getUserListByName(); 2. 在UserMappe ...

  8. Mybatis SQL映射文件详解

    Mybatis SQL映射文件详解 mybatis除了有全局配置文件,还有映射文件,在映射文件中可以编写以下的顶级元素标签: cache – 该命名空间的缓存配置. cache-ref – 引用其它命 ...

  9. MyBatis -- sql映射文件具体解释

    MyBatis 真正的力量是在映射语句中. 和对等功能的jdbc来比价,映射文件节省非常多的代码量. MyBatis的构建就是聚焦于sql的. sql映射文件有例如以下几个顶级元素:(按顺序) cac ...

  10. SSM - Mybatis SQL映射文件

    MyBatis 真正的力量是在映射语句中.和对等功能的jdbc来比价,映射文件节省很多的代码量.MyBatis的构建就是聚焦于sql的. sql映射文件有如下几个顶级元素:(按顺序) cache配置给 ...

随机推荐

  1. jquery操作内容

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. python算法初步(一)

    python算法初步(一) 冒泡排序 时间效率O(n²)原理:依次比较相邻两个位置的元素大小,然后按照要求交换位置. #从中选出一个数据(作为最小数据),然后和其他的数据依次比较,如果有更小的数据,那 ...

  3. 前缀树(Tire)—Python

    核心思想 空间换时间,是一种用于快速减速的多叉树结构,利用字符串的公共前缀来降低时间 优缺点: 优点:查询效率高,减少字符比较 缺点:内存消耗较大 每次都会从头向下一直到字符串结尾 前缀树 1 单个字 ...

  4. linux系统中安装虚拟机

    在linux系统中,利用图形化界面安装虚拟机.首先启动 virt-manager,当然没有安装 virt-manager需要先安装好. 1 $ apt-get install virt-manager ...

  5. Redis数据结构与对象

    参考<Redis设计与实现> 系列文章目录和关于我 一丶简单动态字符串 当redis需要的不仅仅是一个字符串字面量,而是一个可以被修改的字符串值时,就会使用SDS(simple dynam ...

  6. 跟光磊学Java-Windows版Java8开发环境搭建

    Java语言核心技术 如果想要开发Java程序/Java项目之前,必须要安装和配置JDK,这里的JDK表示Java8\JDK8,不过下载软件的时候,强烈推荐大家一定要去软件的官网下载,因为官网提供的软 ...

  7. 深入理解 dbt 增量模型

    想要实现数据增量写入数据库,可以选择 dbt 增量模型.通过 dbt 增量模型,我们只用专注于写日增 SQL,不用去关注于如何安全的实现增量写入. dbt 增量模型解决了什么问题 原子性写入:任何情况 ...

  8. [深度学习] CNN的基础结构与核心思想

    1. 概述 卷积神经网络是一种特殊的深层的神经网络模型,它的特殊性体现在两个方面,一方面它的神经元间的连接是非全连接的, 另一方面同一层中某些神经元之间的连接的权重是共享的(即相同的).它的非全连接和 ...

  9. JS比较数值大小

    一. 简单循环算法 代码如下: const numbers = [5, 6, 2, 3, 7]; let max = -Infinity; for (let i = 0; i < numbers ...

  10. python之路29 网络编程基础2之 两种架构 传输层常见协议 socket模块

    软件开发架构 1.C/S架构(Client:客户端和Server:服务端) 服务器-客户机,即Client-Server(C/S)结构.C/S结构通常采取两层结构.服务器负责数据的管理,客户机负责完成 ...