2022尚硅谷SSM框架跟学 一MyBatis
- SSM框架整合
- 课程优势
- 课程体系
- 框架图
- MyBatis
- 1、MyBatis简介
- 1.1MyBatis历史
- 1.2MyBatis特性
- 1.3MyBatis下载
- 1.4和其它持久化层技术对比
- JDBC
- Hibernate 和 JPA
- MyBatis
- 2.搭建MyBatis
- 2.1开发环境
- 2.2创建maven工程
- (1)打包方式:jar
- (2)引入依赖
- (3)创建数据库
- (4)建表
- (5)创建实体类
- 2.3创建MyBatis的核心配置文件
- 2.4创建mapper接口
- 2.5创建MyBatis的映射文件
- 2.6通过junit测试功能
- 2.7加入log4j日志功能
- (1)加入依赖
- (2)加入log4j的配置文件
- 3.核心配置文件详解
- 4.MyBatis的增删改查
- 4.1新增
- 4.2删除
- 4.3修改
- 4.4查询一个实体类对象
- 4.5查询list集合
- 4.6核心配置文件详解
- (1)环境environments、environment和数据源dataSource解释
- (2)核心配置文件mybatis-config.xml增加 ${}方式和properties
- (3)核心配置文件中标签的顺序
- (4)核心配置文件中typeAliases起别名
- (5)核心配置文件mappers
- (6)核心配置文件创建模板
- (7)Mapper配置文件模板
- (8)模板的使用
- (9)使用模板搭建MyBatis框架
- 5.MyBatis获取参数值的两种方式
- 5.1单个字面量类型的参数
- 5.2多个字面量类型的参数
- 5.3map集合类型的参数
- 5.4实体类类型的参数
- 5.5使用@Param标识参数
SSM框架整合
课程优势
课程体系
框架图
MyBatis
1、MyBatis简介
1.1MyBatis历史
1.2MyBatis特性
1.3MyBatis下载
MyBatis下载地址:下载地址
1.4和其它持久化层技术对比
JDBC
- SQL 夹杂在Java代码中耦合度高,导致硬编码内伤
- 维护不易且实际开发需求中 SQL 有变化,频繁修改的情况多见
- 代码冗长,开发效率低
Hibernate 和 JPA
- 操作简便,开发效率高
- 程序中的长难复杂 SQL 需要绕过框架
- 内部自动生产的 SQL,不容易做特殊优化
- 基于全映射的全自动框架,大量字段的 POJO 进行部分映射时比较困难。
- 反射操作太多,导致数据库性能下降
MyBatis
- 轻量级,性能出色
- SQL 和 Java 编码分开,功能边界清晰。Java代码专注业务、SQL语句专注数据
- 开发效率稍逊于HIbernate,但是完全能够接受
2.搭建MyBatis
2.1开发环境
IDE:idea 2021.3
构建工具:maven 3.6.3
MySQL版本:MySQL 5.7
MyBatis版本:MyBatis 3.5.7
MySQL不同版本的注意事项
1、驱动类driver-class-name
MySQL 5版本使用jdbc5驱动,驱动类使用:com.mysql.jdbc.Driver
MySQL 8版本使用jdbc8驱动,驱动类使用:com.mysql.cj.jdbc.Driver
2、连接地址url
MySQL 5版本的url,要注意设置编码:
jdbc:mysql://localhost:3306/ssm
MySQL 8版本的url要注意设置时区:
jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
否则运行测试用例报告如下错误:
java.sql.SQLException: The server time zone value is unrecognized or represents more
2.2创建maven工程
创建Maven工程,之后查看JDK版本
配置Maven的相关信息
配置JDK
新建一个Module
配置Module
Name:mybatis-helloworld
GroupId:com.atguigu.mybatis
ArtifactId:mybatis-helloworld
输入相关名称和Maven坐标
(1)打包方式:jar
<!-- 打包方式 -->
<packaging>jar</packaging>
配置打包方式
因为Mybatis与JDBC打交道,无需配置war包
(2)引入依赖
<dependencies>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.20</version>
</dependency>
</dependencies>
引入依赖后如果报红可以尝试如下方法:
-DarchetypeCatalog=internal
输入指令后,点击Apply后点击ok然后重启IDEA,报红消失,查看Maven中是否创建了依赖
(3)创建数据库
CREATE DATABASE `ssm`;
(4)建表
CREATE TABLE `t_user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(20) DEFAULT NULL,
`password` VARCHAR(20) DEFAULT NULL,
`age` INT(11) DEFAULT NULL,
`gender` CHAR(1) DEFAULT NULL,
`email` VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
直接用sqlyog创建也可
(5)创建实体类
com.atguigu.mybatis.pojo.User
package com.atguigu.mybatis.pojo;
/**
* @ClassName: User
* @Description:
* @Author: wty
* @Date: 2023/1/1
*/
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String gender;
private String email;
public User() {
}
public User(Integer id, String username, String password, Integer age, String gender, String email) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
this.gender = gender;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", email='" + email + '\'' +
'}';
}
}
2.3创建MyBatis的核心配置文件
习惯上命名为mybatis-config.xml,这个文件名仅仅只是建议,并非强制要求。将来整合Spring之后,这个配置文件可以省略,所以大家操作时可以直接复制、粘贴。
核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息
核心配置文件存放的位置是src/main/resources目录下
查看官网文档
如下:
<?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"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="hsp"/>
</dataSource>
</environment>
</environments>
<!-- 引入MyBatis的映射文件 -->
<mappers>
<mapper resource=""/>
</mappers>
</configuration>
标签说明
2.4创建mapper接口
MyBatis中的mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要提供实现类。
package com.atguigu.mybatis.mapper;
/**
* @InterfaceName: UserMapper
* @Description:
* @Author: wty
* @Date: 2023/1/1
*/
public interface UserMapper {
/**
* @param
* @return int
* @description //增添一条数据
* @date 2023/1/1 21:55
* @author wty
**/
int insertUser();
}
2.5创建MyBatis的映射文件
相关概念:ORM(Object Relationship Mapping)对象关系映射。
对象:Java的实体类对象
关系:关系型数据库
映射:二者之间的对应关系
Java概念 | 数据库概念 |
---|---|
类 | 表 |
属性 | 字段/列 |
对象 | 记录/行 |
1、映射文件的命名规则:
表所对应的实体类的类名+Mapper.xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
因此一个映射文件对应一个实体类,对应一张表的操作
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
MyBatis映射文件存放的位置是src/main/resources/mappers目录下
2、 MyBatis中可以面向接口操作数据,要保证两个一致:
a>mapper接口的全类名和映射文件的命名空间(namespace)保持一致
b>mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致
去官方文档查看映射文件的范例
<?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="com.atguigu.mybatis.mapper.UserMapper">
<!--
mapper接口和映射文件要保证两个一致
1.mapper接口的权和类名和映射文件的namespace一致
2.mapper接口中的方法的方法名要和映射文件中的sql的id保持一致
-->
<!-- int insertUser(); -->
<!-- 书写sql语句 -->
<insert id="insertUser">
insert into t_user
values (null, 'admin', MD5('123456'), 23, '男', 'hsp@126.com')
</insert>
</mapper>
两个一致性
配置xml文件
<!-- 引入MyBatis的映射文件 -->
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
</mappers>
2.6通过junit测试功能
创建测试类
SqlSession:代表Java程序和数据库之间的会话。(HttpSession是Java程序和浏览器之间的
会话)
SqlSessionFactory:是“生产”SqlSession的“工厂”。
工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的
相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。
package com.atguigu.mybatis.test;
import com.atguigu.mybatis.mapper.UserMapper;
import com.atguigu.mybatis.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
/**
* @ClassName: MyBatisTest
* @Description:
* @Author: wty
* @Date: 2023/1/1
*/
public class MyBatisTest {
@Test
public void testInsert() throws IOException {
// 获取核心配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 获取sql的会话对象sqlSession,是MyBatis提供的操作数据库的对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 代理模式:获取UserMapper的代理实现对象,通过获取User类对象可以获取接口的对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 调用mapper接口中的方法,实现添加用户信息的功能
int i = mapper.insertUser();
System.out.println("结果:" + i);
// 关闭会话
sqlSession.close();
}
}
测试结果
这里虽然结果是1,但是没有设置事务,所以没有提交,需要设置一下
// 提交事务
sqlSession.commit();
添加成功
sqlSession获取sql执行语句的另一种方式
package com.atguigu.mybatis.test;
import com.atguigu.mybatis.mapper.UserMapper;
import com.atguigu.mybatis.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
/**
* @ClassName: MyBatisTest
* @Description:
* @Author: wty
* @Date: 2023/1/1
*/
public class MyBatisTest {
@Test
public void testInsert() throws IOException {
// 获取核心配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 获取sql的会话对象sqlSession,是MyBatis提供的操作数据库的对象
SqlSession sqlSession = sqlSessionFactory.openSession();
/*// 代理模式:获取UserMapper的代理实现对象,通过获取User类对象可以获取接口的对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 调用mapper接口中的方法,实现添加用户信息的功能
int i = mapper.insertUser();
*/
// 提供sql的唯一标识找到sql并执行,唯一标识是namespace.id
int i = sqlSession.insert("com.atguigu.mybatis.mapper.UserMapper.insertUser");
System.out.println("结果:" + i);
// 提交事务
sqlSession.commit();
// 关闭会话
sqlSession.close();
}
}
执行前先截断表
截断表:底层删除表并创建一个一模一样的表,自增主键从1开始
清除表:会清除表中的数据,自增主键继续自增
结果
自动提交事务
package com.atguigu.mybatis.test;
import com.atguigu.mybatis.mapper.UserMapper;
import com.atguigu.mybatis.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
/**
* @ClassName: MyBatisTest
* @Description:
* @Author: wty
* @Date: 2023/1/1
*/
public class MyBatisTest {
@Test
public void testInsert() throws IOException {
// 获取核心配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 获取sql的会话对象sqlSession,是MyBatis提供的操作数据库的对象
//SqlSession sqlSession = sqlSessionFactory.openSession();
// 设置事务自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(true);
/*// 代理模式:获取UserMapper的代理实现对象,通过获取User类对象可以获取接口的对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 调用mapper接口中的方法,实现添加用户信息的功能
int i = mapper.insertUser();
*/
// 提供sql的唯一标识找到sql并执行,唯一标识是namespace.id
int i = sqlSession.insert("com.atguigu.mybatis.mapper.UserMapper.insertUser");
System.out.println("结果:" + i);
// 提交事务,上面设置了自动提交这里就可以注释了
//sqlSession.commit();
// 关闭会话
sqlSession.close();
}
}
查看结果
2.7加入log4j日志功能
(1)加入依赖
在pom.xml中加入依赖
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
(2)加入log4j的配置文件
创建配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}
%m (%F:%L) \n"/>
</layout>
</appender>
<logger name="java.sql">
<level value="debug"/>
</logger>
<logger name="org.apache.ibatis">
<level value="info"/>
</logger>
<root>
<level value="debug"/>
<appender-ref ref="STDOUT"/>
</root>
</log4j:configuration>
执行即可,查看结果
日志的级别
FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)
从左到右打印的内容越来越详细
3.核心配置文件详解
先阅读源码
// invoke 方法
public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
return this.mapperMethod.execute(sqlSession, args);
}
// execute方法
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
Object param;
switch(this.command.getType()) {
case INSERT:
param = this.method.convertArgsToSqlCommandParam(args);
result = this.rowCountResult(sqlSession.insert(this.command.getName(), param));
break;
核心配置文件中的标签必须按照固定的顺序:
properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?
4.MyBatis的增删改查
创建工具类
package com.atguigu.mybatis.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
/**
* @ClassName: SqlSessionUtil
* @Description:工具类
* @Author: wty
* @Date: 2023/1/1
*/
public class SqlSessionUtil {
/**
* @param
* @return org.apache.ibatis.session.SqlSession
* @description //获取SqlSession对象
* @date 2023/1/1 23:51
* @author wty
**/
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
InputStream is = null;
// 获取核心配置文件的输入流
try {
is = Resources.getResourceAsStream("mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
// 获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 获取sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 自动开启事务,并且创建sqlSession对象
sqlSession = sqlSessionFactory.openSession(true);
return sqlSession;
}
}
4.1新增
4.2删除
UserMapper接口中新增方法
/**
* @param
* @return int
* @description //删除id = 5 的用户信息
* @date 2023/1/2 0:07
* @author wty
**/
int deleteUser();
UserMapper.xml中添加sql语句
<!-- int deleteUser() -->
<delete id="deleteUser">
delete
from t_user
where id = 5
</delete>
MyBatisTest.java中新增删除测试类
@Test
public void deleteUser() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
// 获取mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 调用接口
int i = mapper.deleteUser();
System.out.println("结果:" + i);
sqlSession.close();
}
执行结果
数据库结果
4.3修改
UserMapper接口中新增方法
/**
* @param
* @return int
* @description //修改一条数据
* @date 2023/1/1 21:55
* @author wty
**/
int updateUser();
UserMapper.xml中添加sql语句
<!-- int updateUser(); -->
<update id="updateUser">
update t_user
set username = 'hsp',
password = '123'
where id = 1
</update>
MyBatisTest.java中新增修改测试类
@Test
public void testUpdate() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
// 代理模式:获取代理实现类
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 调用mapper接口中的方法,实现修改用户信息的功能
int i = mapper.updateUser();
System.out.println("结果:" + i);
sqlSession.close();
}
执行结果
修改结果
4.4查询一个实体类对象
UserMapper接口中新增方法
/**
* @param
* @return com.atguigu.mybatis.pojo.User
* @description //根据ID查询用户
* @date 2023/1/2 11:06
* @author wty
**/
User getUserById();
UserMapper.xml中添加sql语句
<!-- User getUserById(); -->
<select id="getUserById">
select *
from t_user
where id = 1
</select>
MyBatisTest.java中新增查询测试类
@Test
public void getUserByid() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserById();
System.out.println("对象:" + user.toString());
sqlSession.close();
}
如果是当前的代码,执行会报错
### Cause: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'com.atguigu.mybatis.mapper.UserMapper.getUserById'. It's likely that neither a Result Type nor a Result Map was specified.
更改一下UserMapper.xml的配置文件
<!-- User getUserById(); -->
<!-- resultType设置结果类型,即查询结果需要转换成的Java类型 -->
<!-- resultMap自定义映射,处理多对一或者一对多的元素关系 -->
<!-- resultType和resultMap二者必须存在一个,但是不许二者都存在 -->
<select id="getUserById" resultType="com.atguigu.mybatis.pojo.User">
select *
from t_user
where id = 1
</select>
再去MyBatisTest.java中执行一下
执行结果
4.5查询list集合
UserMapper接口中新增方法
/**
* @param
* @return java.util.List<com.atguigu.mybatis.pojo.User>
* @description //查询所有的User返回合集
* @date 2023/1/2 11:23
* @author wty
**/
List<User> getAllUser();
UserMapper.xml中添加sql语句
这里要注意查询结果需要先转换成实体类User类型,然后存放在集合List中
<!-- List<User> getAllUser(); -->
<select id="getAllUser" resultType="com.atguigu.mybatis.pojo.User">
select *
from t_user
</select>
MyBatisTest.java中新增查询测试类
@Test
public void getAllUser() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.getAllUser();
System.out.println("查询结果:");
list.forEach(System.out::println);
sqlSession.close();
}
执行结果
4.6核心配置文件详解
(1)环境environments、environment和数据源dataSource解释
核心配置文件mybatis-config.xml
配置环境environments、environment和数据源dataSource解释
<!-- 配置连接数据库的环境(多个) -->
<!-- default指定具体使用哪个环境 -->
<environments default="development">
<!-- 开发环境 -->
<!-- id:是环境的唯一标识不允许重复 -->
<environment id="development">
<!-- 事务的管理方式 事务管理器
type:JDBC MANAGED
JDBC表示使用JDBC中原生的事务管理方式
MANAGED表示被管理的,例如spring整合MyBatis的时候,交给spring管理
-->
<transactionManager type="JDBC"/>
<!-- dataSource数据源
type:设置数据源的类型
type: POOLED UNPOOLED JNDI
POOLED表示使用数据库连接池
UNPOOLED表示不适用数据库连接池
JNDI表示使用上下文中的数据源
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="hsp"/>
</dataSource>
</environment>
<!-- 测试环境 -->
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="hsp"/>
</dataSource>
</environment>
</environments>
创建数据库配置文件 jdbc.properties
配置数据库连接
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
username=root
password=hsp
(2)核心配置文件mybatis-config.xml增加 ${}方式和properties
核心配置文件mybatis-config.xml增加 ${}方式和properties映射数据库配置文件
<!-- 引入properties文件,此后可以在当前文件中使用${key}的形式访问value -->
<properties resource="jdbc.properties"></properties>
<!-- 配置连接数据库的环境(多个) -->
<!-- default指定具体使用哪个环境 -->
<environments default="development">
<!-- 开发环境 -->
<!-- id:是环境的唯一标识不允许重复 -->
<environment id="development">
<!-- 事务的管理方式 事务管理器
type:JDBC MANAGED
JDBC表示使用JDBC中原生的事务管理方式
MANAGED表示被管理的,例如spring整合MyBatis的时候,交给spring管理
-->
<transactionManager type="JDBC"/>
<!-- dataSource数据源
type:设置数据源的类型
type: POOLED UNPOOLED JNDI
POOLED表示使用数据库连接池
UNPOOLED表示不适用数据库连接池
JNDI表示使用上下文中的数据源
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
数据库配置文件和核心配置文件一一对应
(3)核心配置文件中标签的顺序
现在想给全类别设置别名标签typeAliases,结果发现报错了
MyBatis核心配置文件中的标签必须要按照指定顺序配置:
核心配置文件中configuration标签下的子标签要按照一定的顺序书写
● properties => settings => typeAliases => typeHandlers => >objectFactory =>
objectWrapperFactory => reflectorFactory => plugins => >environments =>
databaseIdProvider => mappers
下移 < typeAliases > 标签到< properties >下面
(4)核心配置文件中typeAliases起别名
<!-- 给全类名设置别名,为某个具体的类型设置一个别名
在MyBatis的范围中,可以使用别名
type:设置需要起别名的类型:全类名
alias:别名
-->
<typeAliases>
<!-- 别名方式1 -->
<!-- <typeAlias type="com.atguigu.mybatis.pojo.User" alias="User"></typeAlias>-->
<!-- 别名方式2:默认是类名不需要区分大小写 -->
<!--<typeAlias type="com.atguigu.mybatis.pojo.User"></typeAlias>-->
<!-- 别名方式3:设置包名,包下的类都是别名 -->
<package name="com.atguigu.mybatis.pojo"/>
</typeAliases>
修改UserMapper.xml配置文件把别名替换上
<select id="getUserById" resultType="User">
select *
from t_user
where id = 1
</select>
<!-- List<User> getAllUser(); -->
<select id="getAllUser" resultType="User">
select *
from t_user
</select>
注意,用方式2定义别名,无需区分大小写
<!-- 别名方式2:默认是类名不需要区分大小写 -->
<typeAlias type="com.atguigu.mybatis.pojo.User"></typeAlias>
方式3,直接给包定义,包下所有类都是别名
<typeAliases>
<!-- 别名方式3:设置包名,包下的类都是别名,且不区分大小写 -->
<package name="com.atguigu.mybatis.pojo"/>
</typeAliases>
方式3也是不区分大小写的
(5)核心配置文件mappers
<!-- 引入MyBatis的映射文件 一张表对应一个映射文件的标签 -->
<mappers>
<!-- 方式1: -->
<!--<mapper resource="mappers/UserMapper.xml"/>-->
<!-- 方式2:以包的形式引入映射文件,但是需要满足以下2点
1.mapper接口和映射文件所在的包必须一致
2.mapper接口的名字和映射文件的名字必须一致
-->
</mappers>
创建目录
目录名称:
com/atguigu/mybatis/mapper
移动UserMapper.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>
<!-- MyBatis核心配置文件中的标签必须要按照指定顺序配置:
核心配置文件中configuration标签下的子标签要按照一定的顺序书写
● properties => settings => typeAliases => typeHandlers => objectFactory =>
objectWrapperFactory => reflectorFactory => plugins => environments =>
databaseIdProvider => mappers
-->
<!-- 引入properties文件,此后可以在当前文件中使用${key}的形式访问value -->
<properties resource="jdbc.properties"></properties>
<!-- 给全类名设置别名,为某个具体的类型设置一个别名
在MyBatis的范围中,可以使用别名
type:设置需要起别名的类型:全类名
alias:别名
-->
<typeAliases>
<!-- 别名方式1 -->
<!-- <typeAlias type="com.atguigu.mybatis.pojo.User" alias="User"></typeAlias>-->
<!-- 别名方式2:默认是类名不需要区分大小写 -->
<!--<typeAlias type="com.atguigu.mybatis.pojo.User"></typeAlias>-->
<!-- 别名方式3:设置包名,包下的类都是别名,且不区分大小写 -->
<package name="com.atguigu.mybatis.pojo"/>
</typeAliases>
<!-- 配置连接数据库的环境(多个) -->
<!-- default指定具体使用哪个环境 -->
<environments default="development">
<!-- 开发环境 -->
<!-- id:是环境的唯一标识不允许重复 -->
<environment id="development">
<!-- 事务的管理方式 事务管理器
type:JDBC MANAGED
JDBC表示使用JDBC中原生的事务管理方式
MANAGED表示被管理的,例如spring整合MyBatis的时候,交给spring管理
-->
<transactionManager type="JDBC"/>
<!-- dataSource数据源
type:设置数据源的类型
type: POOLED UNPOOLED JNDI
POOLED表示使用数据库连接池
UNPOOLED表示不适用数据库连接池
JNDI表示使用上下文中的数据源
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<!-- 测试环境 -->
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="hsp"/>
</dataSource>
</environment>
</environments>
<!-- 引入MyBatis的映射文件 一张表对应一个映射文件的标签 -->
<mappers>
<!-- 方式1: -->
<!--<mapper resource="mappers/UserMapper.xml"/>-->
<!-- 方式2:以包的形式引入映射文件,但是需要满足以下2点
1.mapper接口和映射文件所在的包必须一致
2.mapper接口的名字和映射文件的名字必须一致
-->
<package name="com.atguigu.mybatis.mapper"/>
</mappers>
</configuration>
(6)核心配置文件创建模板
核心配置文件创建模板配置一次,以后可以直接使用
<?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>
<!-- MyBatis核心配置文件中的标签必须要按照指定顺序配置:
核心配置文件中configuration标签下的子标签要按照一定的顺序书写
● properties => settings => typeAliases => typeHandlers => objectFactory =>
objectWrapperFactory => reflectorFactory => plugins => environments =>
databaseIdProvider => mappers
-->
<!-- 引入properties文件,此后可以在当前文件中使用${key}的形式访问value -->
<properties resource="jdbc.properties"></properties>
<!-- 给全类名设置别名,为某个具体的类型设置一个别名
在MyBatis的范围中,可以使用别名
type:设置需要起别名的类型:全类名
alias:别名
-->
<typeAliases>
<!-- 别名方式1 -->
<!-- <typeAlias type="" alias="User"></typeAlias>-->
<!-- 别名方式2:默认是类名不需要区分大小写 -->
<!--<typeAlias type=""></typeAlias>-->
<!-- 别名方式3:设置包名,包下的类都是别名,且不区分大小写 -->
<package name=""/>
</typeAliases>
<!-- 配置连接数据库的环境(多个) -->
<!-- default指定具体使用哪个环境 -->
<environments default="development">
<!-- 开发环境 -->
<!-- id:是环境的唯一标识不允许重复 -->
<environment id="development">
<!-- 事务的管理方式 事务管理器
type:JDBC MANAGED
JDBC表示使用JDBC中原生的事务管理方式
MANAGED表示被管理的,例如spring整合MyBatis的时候,交给spring管理
-->
<transactionManager type="JDBC"/>
<!-- dataSource数据源
type:设置数据源的类型
type: POOLED UNPOOLED JNDI
POOLED表示使用数据库连接池
UNPOOLED表示不适用数据库连接池
JNDI表示使用上下文中的数据源
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<!-- 测试环境 -->
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="hsp"/>
</dataSource>
</environment>
</environments>
<!-- 引入MyBatis的映射文件 一张表对应一个映射文件的标签 -->
<mappers>
<!-- 方式1: -->
<!--<mapper resource=""/>-->
<!-- 方式2:以包的形式引入映射文件,但是需要满足以下2点
1.mapper接口和映射文件所在的包必须一致
2.mapper接口的名字和映射文件的名字必须一致
-->
<package name=""/>
</mappers>
</configuration>
模板名称:mybatis-config
(7)Mapper配置文件模板
<?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="">
<!--
mapper接口和映射文件要保证两个一致
1.mapper接口的权和类名和映射文件的namespace一致
2.mapper接口中的方法的方法名要和映射文件中的sql的id保持一致
-->
</mapper>
模板名称:mybatis-mapper
(8)模板的使用
(9)使用模板搭建MyBatis框架
创建Module
点击下一步
配置Maven信息
Name:mybatis-parameter
GroupId:com.atguigu.mybatis
pom.xml直接拷贝上一个Module的即可
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SSM</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu.mybatis</groupId>
<artifactId>mybatis-parameter</artifactId>
<!-- 打包方式 -->
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.20</version>
</dependency>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
拷贝jdbc.properties和log4j.xml
通过模板快速创建
创建接口
com.atguigu.mybatis.mapper.UserMapper
注意选择接口
创建文件夹
com/atguigu/mybatis/mapper
模板创建mapper文件,名称要一致
配置全类名
拷贝User类即可
核心配置文件配置相关路径
核心配置文件配置相关路径2
5.MyBatis获取参数值的两种方式
MyBatis获取参数值的两种方式:${}和#{}
> ${}的本质就是字符串拼接,
> #{}的本质就是占位符赋值。
${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;
但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号。
所以 #{}可以避免sql注入
UserMapper中添加方法
/**
* @param
* @return com.atguigu.mybatis.pojo.User
* @description //通过用户名查询用户信息
* @param: username
* @date 2023/1/2 16:05
* @author wty
**/
User getUserByUsername(String username);
5.1单个字面量类型的参数
若mapper接口中的方法参数为单个的字面量类型
此时可以使用 ${} 和 #{} 以任意的名称获取参数的值,
注意 ${} 需要手动加单引号
字面量:字符串、基本数据类型、基本数据类型对应的包装类 例如: int a = 1
#{}方式配置UserMapper.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="com.atguigu.mybatis.mapper.UserMapper">
<!--
mapper接口和映射文件要保证两个一致
1.mapper接口的权和类名和映射文件的namespace一致
2.mapper接口中的方法的方法名要和映射文件中的sql的id保持一致
-->
<!-- User getUserByUsername(String username); -->
<select id="getUserByUsername" resultType="User">
select *
from t_user
where username = #{username}
</select>
</mapper>
创建测试类
com.atguigu.mybatis.parameterTest
拷贝工具类
编写测试类parameterTest
package com.atguigu.mybatis;
import com.atguigu.mybatis.mapper.UserMapper;
import com.atguigu.mybatis.pojo.User;
import com.atguigu.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
/**
* @ClassName: parameterTest
* @Description:
* @Author: wty
* @Date: 2023/1/2
*/
public class parameterTest {
@Test
public void getUserByUsername() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserByUsername("hsp");
System.out.println(user);
sqlSession.close();
}
}
运行结果
注意:
这里注意,大括号内可以为任意值,
因为底层Mapper配置文件不知道参数具体是哪个属性,但是起名最好要有意义
紧接着继续修改UserMapper.xml,如果直接更改为${}
<!-- User getUserByUsername(String username); -->
<select id="getUserByUsername" resultType="User">
<!--select *
from t_user
where username = #{username}-->
select *
from t_user
where username = ${username}
</select>
运行测试类会发现报错了
所以要使用${}的时候要注意单引号的使用
<!-- User getUserByUsername(String username); -->
<select id="getUserByUsername" resultType="User">
select *
from t_user
where username = '${username}'
</select>
再次执行就没有错误了
5.2多个字面量类型的参数
若mapper接口中的方法参数为多个时
此时MyBatis会自动将这些参数放在一个map集合中,
(1)以arg0,arg1…为键,以参数为值;
(2)以param1,param2…为键,以参数为值;
因此只需要通过 ${} 和 #{} 访问map集合的键就可以获取相对应的值,
注意 ${} 需要手动加单引号
UserMapper.java增加方法
/**
* @param
* @return com.atguigu.mybatis.pojo.User
* @description //验证用户名和密码
* @param: username
* @param: password
* @date 2023/1/2 16:43
* @author wty
**/
User checkLogin(String username, String password);
UserMapper.xml新增查询语句
<!-- User checkLogin(String username, String password); -->
<select id="checkLogin" resultType="User">
select *
from t_user
where username = #{username}
and password = #{password}
</select>
编写测试类parameterTest
@Test
public void checkLogin() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.checkLogin("hsp", "123");
System.out.println(user);
sqlSession.close();
}
运行后发现报错
发现框架给出了解决方案,那就按照解决方案配置UserMapper.xml
<!-- User checkLogin(String username, String password); -->
<select id="checkLogin" resultType="User">
select *
from t_user
where username = #{arg0}
and password = #{arg1}
</select>
再次运行测试类发现运行成功
另一种框架给出的方案也试一试
<!-- User checkLogin(String username, String password); -->
<select id="checkLogin" resultType="User">
select *
from t_user
where username = #{param1}
and password = #{param2}
</select>
发现也可以正常运行结果
尝试一下${}的方式
<select id="checkLogin" resultType="User">
select *
from t_user
where username = '${arg0}'
and password = '${arg1}'
</select>
以及
<!-- User checkLogin(String username, String password); -->
<select id="checkLogin" resultType="User">
select *
from t_user
where username = '${param1}'
and password = '${param2}'
</select>
也没有问题,可以正常查询结果。
5.3map集合类型的参数
若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中只需要通过 ${} 和 #{} 访问map集合的键就可以获取相对应的值。
注意 ${} 需要手动加单引号
UserMapper.java添加方法
/**
* @param
* @return com.atguigu.mybatis.pojo.User
* @description //多条件查询
* @param: map
* @date 2023/1/2 17:16
* @author wty
**/
User checkLoginMap(Map<String, Object> map);
UserMapper.xml添加查询
<!-- User checkLoginMap(Map<String, Object> map) -->
<select id="checkLoginMap" resultType="User">
select *
from t_user
where username = #{username}
and password = #{password}
</select>
parameterTest.java添加测试类
@Test
public void checkLoginMap() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<>();
map.put("username", "hsp");
map.put("password", "123");
User user = mapper.checkLoginMap(map);
System.out.println(user);
sqlSession.close();
}
查询结果
使用${}的方式
<!-- User checkLoginMap(Map<String, Object> map) -->
<select id="checkLoginMap" resultType="User">
select *
from t_user
where username = '${username}'
and password = '${password}'
</select>
也可以正常运行
5.4实体类类型的参数
若mapper接口中的方法参数为实体类对象时
此时可以使用 ${} 和 #{} ,通过访问实体类对象中的属性名获取属性值,
注意 ${} 需要手动加单引号
UserMapper.java添加方法
/**
* @param
* @return int
* @description 添加用户信息
* @param: user
* @date 2023/1/2 17:29
* @author wty
**/
int insertUser(User user);
UserMapper.xml添加语句
<!-- int insertUser(User user); -->
<insert id="insertUser">
insert into t_user
values (null,
#{username},
#{password},
#{age},
#{gender},
#{email})
</insert>
parameterTest.java测试类中增加方法
@Test
public void insertUserTest() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(null, "tony", "456", 24, "男", "tony@126.com");
int i = mapper.insertUser(user);
System.out.println("结果:" + i);
sqlSession.close();
}
执行结果
换成${}的形式
<!-- int insertUser(User user); -->
<insert id="insertUser">
insert into t_user
values (null,
'${username}',
'${password}',
'${age}',
'${gender}',
'${email}')
</insert>
可以正常运行
5.5使用@Param标识参数
可以通过@Param注解标识mapper接口中的方法参数
此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;以param1,param2…为键,以参数为值;只需要通过 ${} 和 #{} 访问map集合的键就可以获取相对应的值,
注意 ${} 需要手动加单引号
UserMapper.java添加方法
/**
* @param
* @return com.atguigu.mybatis.pojo.User
* @description //通过注解param来查询
* @param: username
* @param: password
* @date 2023/1/3 15:51
* @author wty
**/
User checkLoginByParam(@Param("username") String username, @Param("password") String password);
UserMapper.xml添加语句
<!-- User checkLoginByParam(String username, String password); -->
<select id="checkLoginByParam" resultType="User">
select *
from t_user
where username = #{username}
and password = #{password}
</select>
parameterTest.java测试类中增加方法
@Test
public void checkLoginByParamTest() {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.checkLoginByParam("Linda", "234");
System.out.println(user);
sqlSession.close();
}
查询结果
将UserMapper.xml更改成${}
<!-- User checkLoginByParam(String username, String password); -->
<select id="checkLoginByParam" resultType="User">
select *
from t_user
where username = '${username}'
and password = '${password}'
</select>
同样可以执行成功
将UserMapper.xml参数更改成param1和param2
<!-- User checkLoginByParam(String username, String password); -->
<select id="checkLoginByParam" resultType="User">
select *
from t_user
where username = '${param1}'
and password = '${param2}'
</select>
同样可以执行成功