目录
- 持久化与ORM
- ORM(Object Relational Mapping)
- ORM解决方案包含下面四个部分
- MyBatis简介
- 特点
- MyBatis框架优缺点
- 优点
- 缺点
- 搭建MyBatis开发环境步骤
- 1. 创建Maven工程,导入MyBatis依赖的组件
- 2. 编写MyBatis核心配置文件(mybatis-config.xml)
- 示例
- properties
- settings元素
- typeAliases
- environments
- mappers
- 3. 创建实体类-POJO
- 4. 创建SQL映射文件(mapper.xml)
- 5. 创建测试类
- 6. 读取核心配置文件mybatis-config.xml
- mybatis基本要素
- MyBatis的核心对象
- mybatis-config.xml 系统核心配置文件
- mapper.xml SQL映射文件
- 7. 创建SqlSessionFactory对象,读取配置文件
- SqlSessionFactoryBuilder
- SqlSessionFactory
- 8. 创建SqlSession对象
- 9. 调用mapper文件进行数据操作
- SqlSession的两种使用方式
- 日志配置文件
- 测试代码
- 通过SqlSession实例直接运行映射的SQL语句
- 控制台输出结果
- sqlSession常用方法
- XXapper.xml
- namespace:命名空间
- 1.创建持久层Mapper接口
- 2.修改UserMapper.xml
- 3.测试(基于Mapper接口方式操作数据)
- mapper.xml中的常用标签(本章先列举基本的CRUD)
- select
- insert
- 代码案例
- 主键回填
- 方式一
- 方式二
- 测试
- update
- 代码案例
- delete
- 代码案例
- 关于parameterType与resultType的值
- mybatis工作原理
- 步骤解析
- Mybatis封装JDBC与解析XML的源码概览
框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展。
持久化与ORM
- 持久化是程序数据在瞬时状态和持久状态间转换的过程
ORM(Object Relational Mapping)
- 即对象/关系映射,是一种数据持久化技术。
- 它在对象模型和关系型数据库之间建立起对应关系,并且提供了一种机制,通过JavaBean对象去操作数据库表中的数据。
- 编写程序的时候,以面向对象的方式处理数据
- 保存数据的时候,却以关系型数据库的方式存储
ORM解决方案包含下面四个部分
- 在持久化对象上执行基本的增、删、改、查操作
- 对持久化对象提供一种查询语言或者API
- 对象关系映射工具
- 提供与事务对象交互、执行检查、延迟加载以及其他优化功能
MyBatis简介
官方网站:http://mybatis.org
- MyBatis 本是Apache的一个开源项目iBatis, 2010年项目由Apache迁移到了Google Code,并且改名为MyBatis 。2013年11月迁移到GitHub。
- MyBatis通过实体类和SQL语句之间建立映射关系,是半自动化的ORM框架,是一款优秀的基于Java的数据持久层框架
特点
- 基于SQL语法,简单易学
- 能了解底层封装过程,内部通过JDBC访问数据库的操作
- SQL语句封装在配置文件中,便于统一管理与维护,降低程序的耦合度
- 方便程序代码调试
MyBatis框架优缺点
优点
- 与JDBC相比,减少了50%以上的代码量
- 最简单的持久化框架,小巧并简单易学
- SQL代码从程序代码中彻底分离,可重用
- 提供XML标签,支持编写动态SQL
- 提供映射标签,支持对象与数据库的ORM字段映射
缺点
- SQL语句编写工作量大,对开发人员有一定要求
- 数据库移植性差
MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案,适用于性能要求较高或者需求多变的互联网项目
搭建MyBatis开发环境步骤
1. 创建Maven工程,导入MyBatis依赖的组件
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!--日志包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2. 编写MyBatis核心配置文件(mybatis-config.xml)
示例
database.properties
driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/smbms?useSSL=false&characterEncoding=utf-8
username = root
password = 123456
mybatis-config.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">
<!-- Mybatis核心配置文件 -->
<configuration>
<properties resource="database.properties"></properties>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<package name="com.zjl.pojo"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
properties
通过外部指定的方式(database.properties),实现动态配置
settings元素
是设置一些非常重要的设置选项,用来设置和改变MyBatis运行时的行为方式
设置参数 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 该配置影响所有映射器中配置的缓存全局开关。 | true/false | true |
lazyLoadingEnabled | 延迟加载的全局开关。开启时,所有关联对象都会延迟加载。特定关联关系中可以通过设置fetchType属性来覆盖该项的开关状态。 | true/false | false |
aggressiveLazyLoading | 关联对象属性的延迟加载开关。当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性会按需加载。 | true/false | true |
multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要兼容驱动)。 | true/false | true |
useColumnLabel | 使用列标签代替列名。不同的驱动在这方面有不同的表现。具体可参考驱动文档或通过测试两种模式来观察所用驱动的行为。 | true/false | true |
useGeneratedKeys | 允许JDBC支持自动生成主键,需要驱动兼容。如果设置为true,则这个设置强制使用自动生成主键,尽管一些驱动不兼容但仍可正常工作。 | true/false | false |
autoMappingBehavior | 指定MyBatis应如何自动映射列到字段或属性。NONE表示取消自动映射; PARTIAL只会自动映射没有定义嵌套结果集映射的结果集; FULL会自动映射任意复杂的结果集(无论是否嵌套)。 | NONE、 PARTIAL、 FULL | PARTIAL |
defaultExecutorType | 配置默认的执行器。SIMPLE就是普通的执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新。 | SIMPLE、 REUSE、 BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数。当没有设置的时候,它取的就是驱动默认的时间。 | 任何正整数 | 没有设置 |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射 | true/false | false |
jdbcTypeForNull | 当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型。某些驱动需要指定列的JDBC类型,多数情况直接用一般类型即可,比如NULL、VARCHAR或OTHER。 | NULL、 VARCHAR、 OTHER | OTHER |
typeAliases
配置类型别名,通过与MyBatis的SQL映射文件相关联,减少输入 多余的完整类名,以简化操作。
environments
- 表示配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上
- 子元素节点:environment,但是必须指定其中一个为默认运行环境(通过default指定)
- 每个SqlSessionFactory实例只能选择一个运行环境
mappers
- 映射器,定义SQL映射语句。须在配置中引用mapper映射文件
- 使用类资源路径获取资源
<!-- 将mapper映射文件加入到系统核心配置文件中 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
3. 创建实体类-POJO
根据数据库表创建对应的实体类
package com.smbms.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author: zjl
* @datetime: 2024/3/23
* @desc:
*/
@Data
@ToString
@NoArgsConstructor
public class User implements Serializable {
private long id;
private String userCode;
private String userName;
private String userPassword;
private int gender;
private Date birthday;
private String phone;
private String address;
private int userRole;
}
4. 创建SQL映射文件(mapper.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="userMapperSQlxml">
<select id="getUserCount" resultType="int">
SELECT COUNT(1) FROM SMBMS_USER
</select>
</mapper>
5. 创建测试类
6. 读取核心配置文件mybatis-config.xml
mybatis基本要素
MyBatis的核心对象
- SqlSessionFactoryBuilder
- SqlSessionFactory
- SqlSession
mybatis-config.xml 系统核心配置文件
mapper.xml SQL映射文件
7. 创建SqlSessionFactory对象,读取配置文件
SqlSessionFactoryBuilder
- 用过即丢,其生命周期只存在于方法体内
- 可重用其来创建多个 SqlSessionFactory 实例
- 负责构建SqlSessionFactory,并提供多个build方法的重载
SqlSessionFactory
- SqlSessionFactory是每个MyBatis应用的核心
- 作用:创建SqlSession实例
- 作用域:Application
- 生命周期与应用的生命周期相同
- 单例:存在于整个应用运行时,并且同时只存在一个对象实例
SqlSession session = sqlSessionFactory.openSession(boolean autoCommit);
- autoCommit为true:关闭事务控制(默认)
- autoCommit为false:开启事务控制
8. 创建SqlSession对象
SqlSession:
- 包含了执行SQL所需的所有方法
- 对应一次数据库会话,会话结束必须关闭
- 线程级别,不能共享
- 在SqlSession里可以执行多次SQL语句,但一旦关闭了SqlSession就需要重新创建
9. 调用mapper文件进行数据操作
SqlSession的两种使用方式
- 通过SqlSession实例直接运行映射的SQL语句
- 基于Mapper接口方式操作数据(推荐)
日志配置文件
log4j.rootLogger=DEBUG,CONSOLE,file
#log4j.rootLogger=ERROR,ROLLING_FILE
log4j.logger.cn.smbms.dao=debug
log4j.logger.com.ibatis=debug
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
log4j.logger.java.sql.Connection=debug
log4j.logger.java.sql.Statement=debug
log4j.logger.java.sql.PreparedStatement=debug
log4j.logger.java.sql.ResultSet=debug
log4j.logger.org.tuckey.web.filters.urlrewrite.UrlRewriteFilter=debug
######################################################################################
# Console Appender \u65e5\u5fd7\u5728\u63a7\u5236\u8f93\u51fa\u914d\u7f6e
######################################################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=error
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= [%p] %d %c - %m%n
######################################################################################
# DailyRolling File \u6bcf\u5929\u4ea7\u751f\u4e00\u4e2a\u65e5\u5fd7\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u683c\u5f0f:log2009-09-11
######################################################################################
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern=yyyy-MM-dd
log4j.appender.file.File=log.log
log4j.appender.file.Append=true
log4j.appender.file.Threshold=error
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
log4j.logger.com.opensymphony.xwork2=error
测试代码
通过SqlSession实例直接运行映射的SQL语句
package com.zjl.test;
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.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import java.io.IOException;
import java.io.InputStream;
/**
* @author: zjl
* @datetime: 2024/4/15
* @desc:
*/
public class MybatisTest {
private static SqlSessionFactory factory = null;
@BeforeAll
public static void init(){
//1.定义mybatis核心配置文件的路径
String path = "mybatis-config.xml";
//2.转字节流接收
try {
InputStream is = Resources.getResourceAsStream(path);
//3.创建SqlSessionFactory对象
factory = new SqlSessionFactoryBuilder().build(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test(){
SqlSession session = factory.openSession();
int count = session.selectOne("userMapperSQlxml.getUserCount");
System.out.println(count);
session.close();
}
}
控制台输出结果
[DEBUG] 2024-04-15 10:58:26,978 org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[DEBUG] 2024-04-15 10:58:26,979 org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[DEBUG] 2024-04-15 10:58:26,979 org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[DEBUG] 2024-04-15 10:58:26,980 org.apache.ibatis.datasource.pooled.PooledDataSource - PooledDataSource forcefully closed/removed all connections.
[DEBUG] 2024-04-15 10:58:27,066 org.apache.ibatis.transaction.jdbc.JdbcTransaction - Opening JDBC Connection
[DEBUG] 2024-04-15 10:58:27,308 org.apache.ibatis.datasource.pooled.PooledDataSource - Created connection 1579132337.
[DEBUG] 2024-04-15 10:58:27,308 org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e1fa5b1]
[DEBUG] 2024-04-15 10:58:27,312 userMapperSQlxml.getUserCount - ==> Preparing: SELECT COUNT(1) FROM SMBMS_USER
[DEBUG] 2024-04-15 10:58:27,332 userMapperSQlxml.getUserCount - ==> Parameters:
[DEBUG] 2024-04-15 10:58:27,423 userMapperSQlxml.getUserCount - <== Total: 1
14
[DEBUG] 2024-04-15 10:58:27,424 org.apache.ibatis.transaction.jdbc.JdbcTransaction - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e1fa5b1]
[DEBUG] 2024-04-15 10:58:27,424 org.apache.ibatis.transaction.jdbc.JdbcTransaction - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e1fa5b1]
[DEBUG] 2024-04-15 10:58:27,424 org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 1579132337 to pool.
sqlSession常用方法
方法 | 说明 |
---|---|
int insert(String statement)。 | 插入方法,参数statement是在配置文件中定义的<insert…/>元素的id,返回执行SQL语句所影响的行数。 |
int insert(String statement,Object parameter)。 | 插入方法,参数statement是在配置文件中定义的<insert…/>元素的id,parameter是插入所需的参数,通常是对象或者Map,返回执行SQL语句所影响的行数。 |
int update(String statement) 。 | 更新方法,参数statement是在配置文件中定义的<update…/>元素的id,返回执行SQL语句所影响的行数。 |
int update(String statement,Object parameter)。 | 更新方法,参数statement是在配置文件中定义的<update…/>元素的id,parameter是插入所需的参数,通常是对象或者Map,返回执行SQL语句所影响的行数。 |
int delete(String statement) 。 | 删除方法,参数statement是在配置文件中定义的<delete…/>元素的id。返回执行SQL语句所影响的行数。 |
int delete(String statement,Object parameter)。 | 删除方法,参数statement 是在配置文件中定义的<delete…/>元素的id,parameter是插入所需的参数,通常是对象或者Map,返回执行SQL语句所影响的行数。 |
T selectOne(String slatement)。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,返回执行SQL语句查询结果的泛型对象,通常查询结果只有一条数据时才使用。 |
T selectOne(String statement,Object parameter)。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,parameter是查询所需的参数,通常是对象或者Map,返回执行SQL语句查询结果的泛型对象,通常查询结具只有一条数据时才使用。 |
List selectList(String statemenl)。 | 查询方法,参数是在配置文件中定义的<select…/>素的id,返回执行SQL话句查询结果的泛型对象的集合。 |
List selectList(String statement,Object parameter)。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,parameter是查询所需的参数,通常是对象或者Map,返回执行SQL语句查询结果的泛型对象的集合。 |
List selectList(String statement,Object parameter,RowBounds rowBounds)。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,parameter是查询所需的参数,通常是对象或者Map,RowBounds对象用于分页,它的两个属性: offset指查询的当前页数; limit指当前页显示多少条数据。返回执行SQL语句查询结果的泛型对象的集合。 |
<K,V> Map<K,V> selectMap(String statement,String mapKey) 。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,mapKey是返回数据的其中一个列名,执行SQL语句查询结果将会被封装成一个Map集合返回,key就是参数mapKey传入的列名,value是封装的对象。 |
<K,V> Map<K,V> selectMap(String statement,0bject parameler,Sting mapKey)。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,parameter是查询所需的参数,通常是对象或者Map,mapKey 是返回数据的其中一个列名,执行SQL语句查询结果将会被封装成一个Map集合返回,key就是参数mapKey传入的列名,value是封装的对象。 |
<K,V> Map<K,V>selectMap(Sting statement,Object parameter,Sting mapKey,RowBounds rowBounds)。 | 查询方法,参数statement 是在配置文件中定义的<select…/>元素的id,parameter 是否询所需的参数,通常是对象或者Map,mapKey 是返回数据的其中一个列名,RowBounds 对象用于分页。执行SQL 语句查询结果将会被封装成一个Map集合返回,key就是参数mapKey传入的列名,value是封装的对象。 |
void select(String statement,ResultHandler handler)。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,ResultHandler对象用来处理查询返回的复杂结果集,通常用于多表查询。 |
void select(String statement,Object parameter,ResultHander handler)。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,parameter 是查询所需的参数,通常是对象或者Map, ResultHandler对象用来处理查询返回的复杂结果集,通常用于多表查询。 |
void select(String statement,Object parameter,RowBounds rowBounds,ResultHandr handler)。 | 查询方法,参数statement是在配置文件中定义的<select…/>元素的id,是查询所需的参数,通常是对象或者Map,RowBounds 对象用于分页,ResultHandr对象用来处理查询返回的复杂结果集,通常用于多表查询。 |
void commit()。 | 提交事务。 |
void rollback()。 | 回滚事务。 |
void close()。 | 关闭SqlSession对象。 |
Connection getConnection()。 | 获得JDBC的数据库连接对象。 |
T getMapper(Class type)。 | 返回mapper接口的代理对象,该对象关联了SqlSession对象,开发者可以通过该对象直接调用方法操作数据库,参数type是Mapper的接口类型。Mybatis官方手册建议通过mapper对象访问MyBatis。 |
XXapper.xml
namespace:命名空间
- namespace和子元素的id联合保证唯一,区别不同的mapper
- 绑定DAO接口
- namespace的命名必须跟某个接口同名
- 接口中的方法与映射文件中SQL语句id一一对应
1.创建持久层Mapper接口
package com.zjl.mapper;
public interface UserMapper {
int getUserCount();
}
2.修改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.zjl.mapper.UserMapper">
<select id="getUserCount" resultType="int">
SELECT COUNT(1) FROM SMBMS_USER
</select>
</mapper>
3.测试(基于Mapper接口方式操作数据)
@Test
public void getUserCountForMapper(){
SqlSession session = factory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
int count = userMapper.getUserCount();
System.out.println(count);
session.close();
}
mapper.xml中的常用标签(本章先列举基本的CRUD)
select
- select是MyBatis中最常用的元素之一
- select语句有很多属性可以详细配置每一条语句
- id
- 命名空间中唯一的标识符
- 接口中的方法与映射文件中的SQL语句id一一对应
- parameterType
- 表示sql语句传入参数的类型的完全限定名和别名
- 支持基础数据类型和复杂数据类型
- resultType
- SQL语句返回值类型的完整限定名或别名
- id
insert
- Mybatis中执行添加操作SQL的标签
- id属性:同select
- parameterType同select
- 没有resultType属性
- 返回结果表示影响行数
- useGeneratedKeys属性, 设置添加操作是否需要回填生成的主键
- keyProperty属性,指定回填的id设置到参数对象中的哪个属性
- timeout属性,设置此操作的超时时间,如果不设置则一直等待
代码案例
//返回结果表示影响行数
int insertUser(User user);
<insert id="insertUser" parameterType="com.zjl.pojo.User">
INSERT INTO SMBMS_USER(id,userCode,userName,birthday)
VALUES(default,#{userCode},#{userName},#{birthday})
</insert>
@Test
public void insertUser(){
SqlSession session = factory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User("zjl","周杰伦",new Date());
int lint = userMapper.insertUser(user);
System.out.println(lint > 0 ? "添加成功" : "添加失败");
//factory.openSession();创建的sqlSession默认不自动提交,因此需要commit
//但是我这里只是测试,因此就不提交了
//session.commit();
session.close();
}
主键回填
主键回填:对于自增主键的表,插入数据后返回该记录自动生成的主键
方式一
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO SMBMS_USER(id,userCode,userName,birthday)
VALUES(default,#{userCode},#{userName},#{birthday})
</insert>
方式二
<insert id="insertUser" >
<selectKey keyProperty="id" resultType="int">
select last_insert_id()
</selectKey>
INSERT INTO SMBMS_USER(id,userCode,userName,birthday)
VALUES(default,#{userCode},#{userName},#{birthday})
</insert>
测试
@Test
public void insertUser(){
SqlSession session = factory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User("zjl","周杰伦",new Date());
int lint = userMapper.insertUser(user);
System.out.println(lint > 0 ? "添加成功" : "添加失败");
System.out.println("新纪录的主键是:" + user.getId());
session.commit();
session.close();
}
update
- Mybatis中执行添加修改SQL的标签
- id属性:同select
- parameterType同select
- 没有resultType属性
- 返回结果表示影响行数
代码案例
int updateUser(User user);
<update id="updateUser" parameterType="com.zjl.pojo.User">
UPDATE SMBMS_USER SET
userCode=#{userCode},
userName=#{userName},
birthday=#{birthday}
WHERE id=#{id}
</update>
@Test
public void updateUser(){
SqlSession session = factory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User("zjl","周杰伦",new Date());
int lint = userMapper.insertUser(user);
System.out.println(lint > 0 ? "修改成功" : "修改失败");
//session.commit();
session.close();
}
delete
- Mybatis中执行添加删除SQL的标签
- id属性:同select
- parameterType同select
- 没有resultType属性
- 返回结果表示影响行数
代码案例
int deleteUserById(int id);
<delte id="deleteUserById" parameterType="int">
DELETE FROM SMBMS_USER WHERE id=#{id}
</delte >
@Test
public void deleteUser(){
SqlSession session = factory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
int lint = userMapper.deleteUserById(66);
System.out.println(lint > 0 ? "删除成功" : "删除失败");
//session.commit();
session.close();
}
关于parameterType与resultType的值
别名 | 映射的类型 |
---|---|
string | String |
byte | Byte |
long | Long |
short | Short |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
int | Integer |
integer | Integer |
arraylist | ArrayList |
map | Map |
hashmap | HashMap |
list | List |
collection | Collection |
iterator | Iterator |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
…… | …… |
如果maybatis-config.xml中配置了实体类别名,那么mapper.xml中就也可以简写了,比如:
mybatis-config.xml
<typeAliases>
<package name="com.zjl.pojo"/>
</typeAliases>
UserMapper.xml
<update id="updateUser" parameterType="User">
UPDATE SMBMS_USER SET
userCode=#{userCode},
userName=#{userName},
birthday=#{birthday}
WHERE id=#{id}
</update>
mybatis工作原理
步骤解析
- 读取 Mybatis 配置文件 mybatis-config.xml,该配置文件作为 Mybatis 的全局配置文件,配置了 Mybatis 的运行环境和数据库连接等信息。
- 加载映射文件 mapper.xml,该文件中配置了操作数据库的 sql 语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml 可以加载多个配置文件,每个配置文件对应数据库中的一张表。
- 通过 SqlSessionFactoryBuilder 对象的 build() 方法构建会话工厂,且 build() 方法参数为 mybatis-config.xml 配置文件的输入流,通过 Mybatis 的环境等配置信息构建会话工厂 SqlSessionFactory - 工厂设计模式。
//build方法源码:将mybatis-config.xml 配置文件输入流解析成xml配置对象
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
- 创建 SqlSession 对象,由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 的所有方法。
- Mybatis 的底层定义了一个 Executor 接口来操作数据库,它会根据 SqlSession 传递的参数动态的生成需要执行的 SQL 语句,同时负责查询缓存的维护。
- 在 Executor 接口的方法中,包含一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等。Mapper.xml 文件中的一个SQL对应一个 MappedStatement 对象,SQL 的 id 即是 MappedStatement 的 id。
- 输入映射参数,在执行方法时 MappedStatement 对象会对用户执行 SQL 语句的输入参数进行定义(可以定义为 Map、List 类型、基本类型和 POJO 类型),Executor 执行器会通过 MappedStatement 对象在执行 SQL 前,将输入的 java 对象映射到 SQL 语句中。这里对输入参数的映射过程就类似于 JDBC 编程中对 preparedStatement 对象设置参数的过程。
- 输出结果映射,在数据库中执行完SQL语句后 MappedStatement 对象会对 SQL 执行输出的结果进行定义(可以定义为 Map、List 类型、基本类型、POJO类型),Executor 执行器会通过 MappedStatement 对象在执行 SQL 语句后,将输出结果映射到 java 对象中。这种将输出结果映射到 java 对象的过程就类似于 JDBC 编程中对结果的解析处理过程。