基本信息
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
总体流程
(1)加载配置并初始化
触发条件:加载配置文件
处理过程:将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)接收调用请求
触发条件:调用Mybatis提供的API
传入参数:为SQL的ID和传入参数对象
处理过程:将请求传递给下层的请求处理层进行处理。
(3)处理操作请求
触发条件:API接口层传递请求过来
传入参数:为SQL的ID和传入参数对象
处理过程:
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
©获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源。
(4)返回处理结果将最终的处理结果返回。
框架架构
框架架构讲解:
mybatis结构
(1)加载配置:配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
(3)SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
(4)结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回
动态SQL
MyBatis 最强大的特性之一就是它的动态语句功能。如果您以前有使用JDBC或者类似框架的经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。
尽管与动态SQL一起工作不是在开一个party,但是MyBatis确实能通过在任何映射SQL语句中使用强大的动态SQL来改进这些状况。动态SQL元素对于任何使用过JSTL或者类似于XML之类的文本处理器的人来说,都是非常熟悉的。在上一版本中,需要了解和学习非常多的元素,但在MyBatis 3 中有了许多的改进,现在只剩下差不多二分之一的元素。MyBatis使用了基于强大的OGNL表达式来消除了大部分元素。
实操上测试代码
1. 测试代码SysTableTemplateMapper.xm
<!--需要include的代码块-->
<sql id="baseSql">
#{name}||'${name}'
</sql>
<!--property标签name属性和参数名一样,但值不同 name=name123 -->
<select id="test1" resultType="java.lang.String">
select
<include refid="baseSql">
<property name="name" value="111111"/>
</include>
from dual
</select>
<!--property标签name属性和参数名一样,但值为#号方式传值-->
<select id="test2" resultType="java.lang.String">
select
<include refid="baseSql">
<property name="name" value="#{name}"/>
</include>
from dual
</select>
<!--property标签name属性和参数名一样,但值为$方式传值-->
<select id="test3" resultType="java.lang.String">
select
<include refid="baseSql">
<property name="name" value="${name}"/>
</include>
from dual
</select>
<!--property标签name属性和参数名不同-->
<select id="test4" resultType="java.lang.String">
select
<include refid="baseSql">
<property name="name1" value="44444444"/>
</include>
from dual
</select>
<select id="test5" resultType="java.lang.String">
select
<include refid="baseSql">
</include>
from dual
</select>
<sql id="mainSql">
${mainSql}
</sql>
<!-- <select id="test6" resultType="cn.gewut.business.core.tableManagement.entity.SysTableTemplate"-->
<!-- parameterType="cn.gewut.business.core.tableManagement.entity.SysTableTemplateModel">-->
<!-- <include refid="mainSql">-->
<!-- </include>-->
<!-- <if test="tableName != null and tableName != ''">-->
<!-- and table_Name like '%'||#{tableName,jdbcType=VARCHAR}||'%'-->
<!-- </if>-->
<!-- </select>-->
<select id="test6" resultType="cn.gewut.business.core.tableManagement.entity.SysTableTemplate"
parameterType="cn.gewut.business.core.tableManagement.entity.SysTableTemplateModel">
<include refid="mainSql">
<property name="tableName" value="#{tableName,jdbcType=VARCHAR}"/>
</include>
</select>
SysTableTemplateMapper.java
String test1(@Param(value = "name") String name);
String test2(@Param(value = "name") String name);
String test3(@Param(value = "name") String name);
String test4(@Param(value = "name") String name);
String test5(@Param(value = "name") String name);
List<SysTableTemplate> test6(SysTableTemplateModel sysTableTemplateModel);
SysTableTemplateServiceImpl.java
@Override
public Object testSelect(SysTableTemplateModel templateModel) {
System.out.println(templateModel);
String test1 = "";
String test2 = "";
String test3 = "";
String test4 = "";
String test5 = "";
LinkedHashMap<String,Object> hashMap = new LinkedHashMap<>();
try {
test1 = sysTableTemplateMapper.test1("test");
hashMap.put("test1",test1);
} catch (Exception e) {
e.printStackTrace();
}
try {
test2 = sysTableTemplateMapper.test2("test");
hashMap.put("test2",test2);
} catch (Exception e) {
e.printStackTrace();
}
try {
test3 = sysTableTemplateMapper.test3("test");
hashMap.put("test3",test3);
} catch (Exception e) {
e.printStackTrace();
}
try {
test4 = sysTableTemplateMapper.test4("test");
hashMap.put("test4",test4);
} catch (Exception e) {
e.printStackTrace();
}
try {
test5 = sysTableTemplateMapper.test5("test");
hashMap.put("test5",test5);
} catch (Exception e) {
e.printStackTrace();
}
try {
List<SysTableTemplate> sysTableTemplates = sysTableTemplateMapper.test6(templateModel);
hashMap.put("test6",sysTableTemplates);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("********************************");
System.out.println(test1);
System.out.println(test2);
System.out.println(test3);
System.out.println(test4);
System.out.println(test5);
return hashMap;
}
返回:
{
"status": 200,
"result": {
"test1": "test111111",
"test3": "testtest",
"test4": "testtest",
"test5": "testtest",
"test6": [
{
"id": "195c9ba11dae1fd55a22a5ae3c3fa215",
"tableName": "表单模板管理",
"tableCode": "TB0003",
"universityCode": "00000",
"universityName": "共享联盟平台",
"routerName": "tableTemplateManagement",
"menuName": "表单管理,表单模板管理",
"mainSql": " select ID, TABLE_NAME, TABLE_CODE, UNIVERSITY_CODE,UNIVERSITY_NAME,MENU_NAME, ROUTER_NAME, MAIN_SQL, CREATE_TIME, UPDATE_TIME\n from SYS_TABLE_TEMPLATE where 1=1",
"createTime": "2022-12-15 16:02:27",
"updateTime": "2022-12-15 09:47:10"
}
]
},
"timestamp": "2022-12-15 16:26:46"
}
截图
动态表单应用:
1. 动态配置功能实现:
2. 动态配置表结构设计
-- Create table
create table SYS_TABLE_TEMPLATE
(
id VARCHAR2(64),
table_name VARCHAR2(64) not null,
table_code VARCHAR2(64) not null,
university_code VARCHAR2(64) not null,
router_name VARCHAR2(64) not null,
main_sql VARCHAR2(2000) not null,
create_time DATE,
update_time DATE default sysdate,
university_name VARCHAR2(64),
menu_name VARCHAR2(64)
)
;
-- Add comments to the table
comment on table SYS_TABLE_TEMPLATE
is '动态表单模板管理';
-- Add comments to the columns
comment on column SYS_TABLE_TEMPLATE.table_name
is '表单名称';
comment on column SYS_TABLE_TEMPLATE.table_code
is '表单编号';
comment on column SYS_TABLE_TEMPLATE.university_code
is '高校代码';
comment on column SYS_TABLE_TEMPLATE.router_name
is '菜单路由名称';
comment on column SYS_TABLE_TEMPLATE.main_sql
is '主sql';
comment on column SYS_TABLE_TEMPLATE.create_time
is '创建时间';
comment on column SYS_TABLE_TEMPLATE.update_time
is '更新时间';
comment on column SYS_TABLE_TEMPLATE.university_name
is '高校名称';
comment on column SYS_TABLE_TEMPLATE.menu_name
is '菜单名称';
-- Create table
create table SYS_TABLE_TEMPLATE_CONFIG
(
id VARCHAR2(64),
table_code VARCHAR2(64) not null,
university_code VARCHAR2(64) not null,
column_name VARCHAR2(64) not null,
column_type VARCHAR2(64) not null,
field_name VARCHAR2(64) not null,
list_is_show NUMBER(1) not null,
export_is_show NUMBER(1) not null,
query_option_is_show NUMBER(1) not null,
column_width NUMBER(8)
)
;
-- Add comments to the table
comment on table SYS_TABLE_TEMPLATE_CONFIG
is '动态表单模板配置';
-- Add comments to the columns
comment on column SYS_TABLE_TEMPLATE_CONFIG.table_code
is '表单编号';
comment on column SYS_TABLE_TEMPLATE_CONFIG.university_code
is '高校代码';
comment on column SYS_TABLE_TEMPLATE_CONFIG.column_name
is '数据库字段列名';
comment on column SYS_TABLE_TEMPLATE_CONFIG.column_type
is '数据库字段列类型';
comment on column SYS_TABLE_TEMPLATE_CONFIG.field_name
is '属性名称';
comment on column SYS_TABLE_TEMPLATE_CONFIG.list_is_show
is '列表是否显示(1显示,0不显示)';
comment on column SYS_TABLE_TEMPLATE_CONFIG.export_is_show
is '导出是否显示(1显示,0不显示)';
comment on column SYS_TABLE_TEMPLATE_CONFIG.query_option_is_show
is '查询选项是否显示(1显示,0不显示)';
comment on column SYS_TABLE_TEMPLATE_CONFIG.column_width
is '宽度';
3. 业务菜单表单改造(这里以配置表单为例)
后端改造
- 判断列表配置存在&&配置了自定义主sql
- mapper.xml改造
前端改造
that.$getMenuApi(that.$route.name)
.getsysTableListApi(req)
.then((res) => {
if (res.result.list.length != 0) {
that.tablelist = res.result.list[0].templateConfigs.filter((c) => c.listIsShow > 0);
this.showType = true;
} else {
this.showType = false;
}
});