首先放出 https://mybatis.org/mybatis-3/zh/index.html mybatis得官方网站 可以从中学习
一直以来在开发中使用得是已经搭建好的平台,并且已经集成好mybatis等各种框架。却忽略了底层是如何实现得。之前也做过一些记录,最后却没有能坚持,从现在开始还是要加油啊。之后会坚持做一些记录
开始看看mybatis是如何使用得并且底层是如何实现得。
- 使用IDEA快速得新建一个maven项目。此处就不过多描述。
File->New Project 选择Maven ->next 对项目取一个名字重命名下GroupId Finish 即可搭建一个Maven项目。新搭建得项目可以直接删除src文件夹,将此项目做为一个父工程,在父工程下可以新建很多的子工程。子工程可以使用父工程引入得相关架包而不需要重新引入。
工程结构如下
- 引入架包
新建得项目需要配置maven指向得settings 文件也可以使用自带得路径地址,主要是方便架包得下载。
学习mybatis需要用到一下几个架包。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
我这边连接得是mysql数据库,因此使用得是mysql相关,如果使用得是oracle需要引入oracle相关。个人觉得两个数据库之间mysql较为轻量级。个人使用以及未来大多数企业得选择也将会是mysql.两者语法也较为接近。个人使用来看oracle本地安装也较为繁杂。junit架包主要用于测试。
- 文件配置
从个人使用来看需要首先在resources文件夹下创建2个文件一个是mybatis-config.xml 一个是sys.properties
具体代码如下:
mybatis-config.xml
其中需要注意得是引入得标签是存在顺序关系得,可以点进configuration去看标签得顺序。
具体的标签使用得含义也已经在标签上做了注明。
其中用户使用程序读取数据库,如果开启二级缓存则会先去二级缓存中查找,再去一级缓存中查找,依旧找不到则调取数据库查询。
logImpl可以自己选择是否配置,或者引入日志架包输出日志。
其中需要主要学习得是
- settings得各种配置,可以参考官方文档。
- typeAliases 给某个类定义别名。
- plugins定义一些分页插件或者拦截器。
- environments中可以配置多个环境default对应得ID既是开启得数据库配置。
- 如果只是单纯得mybatis项目会有事务得配置如果配合spring使用则默认是spring得事务管理。
- 最重要得是mappers映射器一共有4种映射方式。
<!-- 使用相对于类路径的资源引用 --> <mappers> <mapper resource="org/mybatis/builder/AuthorMapper.xml"/> <mapper resource="org/mybatis/builder/BlogMapper.xml"/> <mapper resource="org/mybatis/builder/PostMapper.xml"/> </mappers> <!-- 使用完全限定资源定位符(URL) --> <mappers> <mapper url="file:///var/mappers/AuthorMapper.xml"/> <mapper url="file:///var/mappers/BlogMapper.xml"/> <mapper url="file:///var/mappers/PostMapper.xml"/> </mappers> <!-- 使用映射器接口实现类的完全限定类名 --> <mappers> <mapper class="org.mybatis.builder.AuthorMapper"/> <mapper class="org.mybatis.builder.BlogMapper"/> <mapper class="org.mybatis.builder.PostMapper"/> </mappers> <!-- 将包内的映射器接口实现全部注册为映射器 --> <mappers> <package name="org.mybatis.builder"/> </mappers>
<?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="sys.properties"/>
<settings>
<!-- 使全局的映射器启用或禁用缓存。 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
<setting name="aggressiveLazyLoading" value="true"/>
<!-- 是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。 default:false -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分 FULL:全部 -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 这是默认的执行类型 (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新) -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 使用驼峰命名法转换字段。 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类型 -->
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<!-- 定义别名 -->
<typeAliases>
<!-- <typeAlias type="com.zengpc.pojo.User" alias="User"/>-->
<!--每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值-->
<package name="com.zengpc.pojo"/>
</typeAliases>
<plugins>
<!--监控 sql 埋点 分页-->
<plugin interceptor="com.zengpc.plugin.SqlPrintInterceptor"></plugin>
</plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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>
<mappers>
<mapper resource="mappings/UserDao.xml"/>
</mappers>
</configuration>
sys.properties
添加properties主要是定义常用得数据参数
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/dev
username=root
password=123
在这之后就可以在数据库中建立相应得表以及java代码中相关得实体类。
建表语句
CREATE TABLE `users` (
`ROW_ID` varchar(64) NOT NULL DEFAULT '-1' COMMENT 'ROW_ID',
`CORP_ID` varchar(64) DEFAULT '-1' COMMENT '公司ID',
`DEPT_ID` varchar(64) DEFAULT '-1' COMMENT '部门ID',
`USER_CODE` varchar(32) DEFAULT NULL COMMENT '用户编码(工号)',
`USER_NAME` varchar(100) DEFAULT NULL COMMENT '用户姓名',
`USER_PSW` varchar(100) DEFAULT NULL COMMENT '密码',
`LOGIN_METHOD` varchar(32) DEFAULT NULL COMMENT '密码认证方式',
`USER_TYPE` varchar(32) DEFAULT NULL COMMENT '用户类型',
`USER_EMAIL` varchar(100) DEFAULT NULL COMMENT '用户邮箱',
`USER_PHONE` varchar(100) DEFAULT NULL COMMENT '用户手机',
`USER_WEBCHAT` varchar(100) DEFAULT NULL COMMENT '用户微信',
`REMARK` varchar(255) DEFAULT NULL COMMENT '备注',
`CREATE_USER_ID` varchar(64) DEFAULT '-1' COMMENT '创建人',
`CREATE_DATE` timestamp(6) NULL DEFAULT NULL COMMENT '创建时间',
`UPD_USER_ID` varchar(64) DEFAULT '-1' COMMENT '更新人',
`UPD_DATE` timestamp(6) NULL DEFAULT NULL COMMENT '更新时间',
`DEL_FLAG` char(1) DEFAULT NULL COMMENT '记录删除标志',
PRIMARY KEY (`ROW_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'
实体类(由于只是为了验证数据库查询等,并没有列全所有字段)
package com.zengpc.pojo;
public class User {
private String rowId;
private String userCode;
private String userName;
@Override
public String toString() {
return "User{" +
"rowId='" + rowId + '\'' +
", userCode='" + userCode + '\'' +
", userName='" + userName + '\'' +
'}';
}
public User() {
}
public User(String rowId, String userCode, String userName) {
this.rowId = rowId;
this.userCode = userCode;
this.userName = userName;
}
public String getRowId() {
return rowId;
}
public void setRowId(String rowId) {
this.rowId = rowId;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
编写一个MybatisUtil得工具类
package com.zengpc.util;
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;
public class MybatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource ="mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
新建UserDao 以及UserDao.xml 这两者主要是有个映射关系。
package com.zengpc.dao;
import com.zengpc.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDao {
List<User> getUsers();
}
<?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.zengpc.dao.UserDao">
<sql id="userEntity">
a.row_id as "rowId",
a.user_code as "userCode",
a.user_name as "userName"
</sql>
<select id="getUsers" resultType="user">
select <include refid="userEntity"/> from users a
</select>
</mapper>
其中namespace是一个唯一标识。
mybatis得好处之一就是可以编写动态sql这个在项目中经常用到。对此不在详细描述。
其中返回值主要使用到resultType以及resultMap resultType需要查询语句中返回得字段与实体类中得定义一致。resultMap可以定义映射关系。sql标签是一个代码块得功能
之后就可以在test中编写测试用例
package com.zengpc;
import com.zengpc.dao.UserDao;
import com.zengpc.pojo.User;
import com.zengpc.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class Test {
@org.junit.Test
public void test(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> users = userDao.getUsers();
System.out.println(users.toString());
sqlSession.commit();
sqlSession.close();
}
}
mybatis得主要流程
- 以流的形式读取配置文件然后进行解析。
- SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。SqlSessionFactoryBuilder 每次创建完SqlSessionFactory后就不再需要
- 通过SqlSessionFactory构建SqlSession,SqlSessionFactory不建议多次创建,可以使用SqlSession 获取多个映射接口的实例。
- SqlSession可以用来获得映射器接口的实例。映射器是一些绑定映射语句的接口。在每次运行结束后需要关闭。
这只是mybatis一个使用流程对于动态sql标签等可以参照官网学习。接下来会探究mybatis底层实现。如有描述不对也欢迎指出。