实现双向映射:Mybatis反射实体和数据库。 (mybatis反射实体和数据库)

实现双向映射:Mybatis反射实体和数据库

Mybatis是一款优秀的ORM(对象关系映射)框架,不仅具有灵活的SQL语法,还有高效的二级缓存等特点。在开发实践中,我们往往需要将Java对象和数据库表进行双向映射,这就需要用到Mybatis的反射实体和数据库技术。

1、反射实体

反射是Java语言的一种特性,允许在程序运行时动态获取并操作对象的属性、方法等。Mybatis利用反射实体技术,将数据库中的每一条记录映射为Java对象。这个过程利用Java的反射技术,自动化地完成了实体类和数据库表的映射。

反射实体中主要用到的是ResultMap对象,它用于描述一个映射关系。开发者可以通过ResultMap对象将Java类的属性与数据库表的列进行映射。ResultMap对象包含的属性有id、type、autoMapping等,常见的是使用id属性指定一个ResultMap的唯一标识,使用property属性指定Java类的属性,column属性指定数据库表的列名。

2、数据库映射

数据库映射是指利用Mybatis将一个数据表映射到一个Java类的过程。这个过程的实现需要在Mybatis配置文件中定义映射关系。从配置文件中加载映射关系,然后将Java类的属性值赋值给数据库表中的相应字段,或者是将数据库表中的数据赋值给Java类的属性。

假设我们有一个用户表,表格如下:

| id | name | eml | password |

|—-|——|———————–|———-|

| 1 | Tom | tom@example.com | 123456 |

| 2 | Sally | sally@example.com | 111111 |

| 3 | Jerry | jerry@example.com | 654321 |

现在我们可以用Mybatis将它映射成一个Java实体类,代码如下:

public class User {

private Long id;

private String name;

private String eml;

private String password;

// getter and setter methods

}

在Mybatis配置文件中定义SQL语句和映射关系:

SELECT * FROM users WHERE id = #{id}

其中id属性表示这个SQL语句的唯一标识。parameterType属性表示输入参数类型,resultType属性表示结果集类型。这里我们指定查询结果映射为User类。

在使用Mybatis时,将用户数据与User类属性映射的代码如下:

User user = sqlSession.selectOne(“getUserById”, 1L);

在这句代码中,getUserById是我们在映射文件中定义的SQL语句的id,1L是输入参数。这条语句将查询id为1的用户信息,将结果映射到User实体类中。

3、

反射实体和数据库映射是Mybatis中常用的技术,使用它们可以实现Java对象和数据库表的快速映射,方便开发者对数据进行处理。使用Mybatis时,在配置文件中定义SQL语句和映射关系,然后在代码中调用相应的SQL方法,即可实现数据访问和操作。

相关问题拓展阅读:

java通过反射拿到mybatis中的sql语句并操作怎么用什么时候用?

操作。具体的步骤如下:

获取 MyBatis 中的 MappedStatement 对象。可以通过 SqlSession 的 getConfiguration() 方法获取 Configuration 对象,然后再通过 Configuration 对象的 getMappedStatement() 方法获取 MappedStatement 对象。

从 MappedStatement 对象中获取 BoundSql 对象,即 SQL 语句绑定的参数对象。

从 BoundSql 对象中获取 SQL 语句字符串。可以通过调用 getSql() 方法获取 SQL 语句字符串。

对 SQL 语句进行相应的操作。例如,可以对 SQL 语句进行修改、输出等操作。

Java 通过反射获取 MyBatis 中的 SQL 语句的代码示例兆皮锋:

SqlSession sqlSession = sqlSessionFactory.openSession();

try {

// 获取 MappedStatement 对象

MappedStatement mappedStatement = sqlSession.getConfiguration().getMappedStatement(“com.example.mapper.selectUser”握并);

// 获取 BoundSql 对象

BoundSql boundSql = mappedStatement.getBoundSql(paramObject);

// 获取 SQL 语句字符串

String sql = boundSql.getSql();

// 对 SQL 语句进行相应的操作

// …

} finally {

sqlSession.close();

}

需要注意的是,在使用反射获族晌取 SQL 语句时,要注意保护用户隐私和安全,以免发生 SQL 注入等问题。

使用Java反射来获取MyBatis中的SQL语句并进行操作的需求并不常见。通常,MyBatis会处理SQL语句的执行和结果映射。然而,如果您确实有这样的需求,可以使用以下方法来实现。

首先,您需要从MyBatis的映射器接口(Mapper接口)中获取SQL语句。这里迹掘我们假设您已经定义了一个映射器接口和相应的XML映射文件。例如,UserMapper接口和对应的UserMapper.xml文件。

在MyBatis的配置文件(例如:mybatis-config.xml)中,启用映射器接口的mapperLocations属性,以便行野MyBatis可以找到XML映射文件:

xml

使用反射API,从映射器接口获取SQL语句。下面的示例代码展示了如何从UserMapper接口获取名为selectUser的SQL语句:

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class MyBatisSqlReflectionDemo {

public static void main(String args) throws Exception {

String resource = “path/to/your/mybatis-config.xml”;

InputStream inputStream = Resources.getResourceAsStream(resource);

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

// 获取 UserMapper 映射器接口的代理实例

UserMapper userMapper = sqlSessionFactory.openSession().getMapper(UserMapper.class);

// 获取 UserMapper 中名为 selectUser 的方法

Method selectUserMethod = UserMapper.class.getDeclaredMethod(“selectUser”, Integer.class);

// 获取 selectUser 方法上的 @Select 注解

Select selectAnnotation = selectUserMethod.getAnnotation(Select.class);

// 获取 @Select 注解中的 SQL 语句

String sql = selectAnnotation.value();

System.out.println(“SQL 语句: ” + sql);

}

}

请注意,这个方法只适用于使用注解配置的MyBatis映射器。如果您使用XML映射文件,您需要解析XML文件并查找相应的SQL语句。

获取SQL语句后,您可以根据需求对其进行操作。然而,直接操作SQL语句可能会导致一些问题,例如SQL注入、难以维护等。因此,请谨慎考虑是否确实需要这样做。

MyBatis解析

从命名上可以看出,这个是一个 Builder 模式的,用于创建 SqlSessionFactory 的类。SqlSessionFactoryBuilder 根据配置来构造 SqlSessionFactory。其中配置方式有两种:

mybatis-config.xml 就是我们的配置文件:

Java Config 相比较 XML 文件的方式而言,会有一些限制。比如修改了配置文件需要重新编译,注解方式没有 XML 配置项多等。所以,业界大多数情况下是选择 XML 文件的方式。但到底选择哪种方式,这个要取决与自己团队的需要。比如,项目的 SQL 语句不复杂,也不需要一些高级的 SQL 特性,那么 Java Config 则会更加简洁一点;反之,则可以选择 XML 文件的方式。

创建配置文件解析器XMLConfigBuilder

解析mybatis-config.xml里的配置为Configuration对象,Mybatis的全局配置对象。

XMLConfigBuilder#parseConfiguration解析mapper下的xml

XMLMapperBuilder#bindMapperForNamespace,根据xml里的 namespace 反射出 mapper接口 的 class,如果有mapper接口,则把该mapper接口的class添加到Configuration的mapperRegistry里。

如果该接口已经注册,则抛出已经绑定的异常。

为该接口注模春册MapperProxyFactory,但这里只是注册其创建MapperProxy的工厂,并不是创建MapperProxy。

如果Mapper对应的xml资源未加载,触发xml的绑定操作,将xml中的sql语句与Mapper建立关系。

addMapper方法,只是为**Mapper创建对应对应的MapperProxyFactory。

根据Mapper接口与SqlSession创建MapperProxy对象。

根据接口类获取MapperProxyFactory。烂悄

调用MapperProxyFactory的newInstance创建MapperProxy对象。

SqlSessionFactory 顾名思义,是用于生产 SqlSession 的工厂。 通过如下的方式来获取 SqlSession 实例:

SqlSession 包含了执行 SQL 的所有的方法。以下是示例:

当然,下面的方式可以做到类型安全:

MapperProxy是MapperProxyFactory使用SqlSession创建出来的。所以MapperProxy中包含SqlSession。

可以看到MapperProxy调用invoke方法,进而调用MapperMethod的execute(),这些MapperMethod就是和你要执行的命令相关,比如执行select语句,则会通过SqlSession的select()方法,最饥码渣终调用到Executor的query方法。Executor会再协调另外三个核心组件。

MapperProxy:

MapperMethod:

插件的构建:

谈原理首先要知道StatementHandler,ParameterHandler,Result Handler都是代理,他们是Configuration创建,在创建过程中会调用interceptorChain.pluginAll()方法,为四大组件组装插件(再底层是通过Plugin.wrap(target,XX, new Plugin( interceptor))来来创建的)。

插件链是何时构建的:

在执行SqlSession的query或者update方法时,SqlSession会通过Configuration创建Executor代理,在创建过程中就调用interceptor的pluginAll方法组装插件。然后executor在调用doQuery()方法的时候,也会调用Configuration的newStatementHandler方法创建StatemenHandler(和上面描述的一样,这个handler就是个代理,也是通过interceptorChain的pluginAll方法构建插件)

插件如何执行:

以statementhandler的prepare方法的插件为例,正如前面所说,statementhandler是一个proxy,执行他的prepare方法,将调用invokeHandler的invoke方法,而invokeHandler就是Plugin.wrap(target, , new Plugin(interceptor))中的第三个参数,所以很自然invokeHanlder的invoke的方法最终就会调用interceptor对象的intercept方法。

Mybatis的插件配置在configuration内部,初始化时,会读取这些插件,保存于Configuration对象的InterceptorChain中。

org.apache.ibatis.plugin.InterceptorChain.java源码。

上面的for循环代表了只要是插件,都会以责任链的方式逐一执行,所谓插件,其实就类似于拦截器。

插件的编写

插件必须实现org.apache.ibatis.plugin.Interceptor接口。

-intercept()方法:执行拦截内容的地方,拦截目标对象的目标方法的执行

-plugin()方法:决定是否触发intercept()方法。 作用:包装目标对象,包装就是为目标对象创建一个代理对象

-setProperties()方法:给自定义的拦截器传递xml配置的属性参数。将插件注册时的property属性设置进来

下面自定义一个拦截器:

为什么要写Annotation注解?注解都是什么含义?

Mybatis规定插件必须编写Annotation注解,是必须,而不是可选。@Intercepts注解:装载一个@Signature列表,一个@Signature其实就是一个需要拦截的方法封装。那么,一个拦截器要拦截多个方法,自然就是一个@Signature列表。

type = Executor.class, method = “query”, args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }

解释:要拦截Executor接口内的query()方法,参数类型为args列表。

Plugin.wrap(target, this)是干什么的?

使用JDK的动态代理,给target对象创建一个delegate代理对象,以此来实现方法拦截和增强功能,它会回调intercept()方法。

Mybatis可以拦截哪些接口对象?

Mybatis只能拦截ParameterHandler、ResultSetHandler、StatementHandler、Executor共4个接口对象内的方法。

重新审视interceptorChain.pluginAll()方法:该方法在创建上述4个接口对象时调用,其含义为给这些接口对象注册拦截器功能,注意是注册,而不是执行拦截。

拦截器执行时机:plugin()方法注册拦截器后,那么,在执行上述4个接口对象内的具体方法时,就会自动触发拦截器的执行,也就是插件的执行。

Invocation

可以通过invocation来获取拦截的目标方法,以及执行目标方法。

分页插件原理

由于Mybatis采用的是逻辑分页,而非物理分页,那么,市场上就出现了可以实现物理分页的Mybatis的分页插件。 要实现物理分页,就需要对String sql进行拦截并增强,Mybatis通过BoundSql对象存储String sql,而BoundSql则由StatementHandler对象获取。

因此,就需要编写一个针对StatementHandler的query方法拦截器,然后获取到sql,对sql进行重写增强。

关于mybatis反射实体和数据库的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » 实现双向映射:Mybatis反射实体和数据库。 (mybatis反射实体和数据库)