新聞中心
實現(xiàn)雙向映射:mybatis反射實體和數(shù)據(jù)庫

成都創(chuàng)新互聯(lián)公司是一家朝氣蓬勃的網(wǎng)站建設(shè)公司。公司專注于為企業(yè)提供信息化建設(shè)解決方案。從事網(wǎng)站開發(fā),網(wǎng)站制作,網(wǎng)站設(shè)計,網(wǎng)站模板,微信公眾號開發(fā),軟件開發(fā),微信小程序,十年建站對紙箱等多個行業(yè),擁有豐富設(shè)計經(jīng)驗。
Mybatis是一款優(yōu)秀的ORM(對象關(guān)系映射)框架,不僅具有靈活的SQL語法,還有高效的二級緩存等特點。在開發(fā)實踐中,我們往往需要將Java對象和數(shù)據(jù)庫表進行雙向映射,這就需要用到Mybatis的反射實體和數(shù)據(jù)庫技術(shù)。
1、反射實體
反射是Java語言的一種特性,允許在程序運行時動態(tài)獲取并操作對象的屬性、方法等。Mybatis利用反射實體技術(shù),將數(shù)據(jù)庫中的每一條記錄映射為Java對象。這個過程利用Java的反射技術(shù),自動化地完成了實體類和數(shù)據(jù)庫表的映射。
反射實體中主要用到的是ResultMap對象,它用于描述一個映射關(guān)系。開發(fā)者可以通過ResultMap對象將Java類的屬性與數(shù)據(jù)庫表的列進行映射。ResultMap對象包含的屬性有id、type、autoMapping等,常見的是使用id屬性指定一個ResultMap的唯一標識,使用property屬性指定Java類的屬性,column屬性指定數(shù)據(jù)庫表的列名。
2、數(shù)據(jù)庫映射
數(shù)據(jù)庫映射是指利用Mybatis將一個數(shù)據(jù)表映射到一個Java類的過程。這個過程的實現(xiàn)需要在Mybatis配置文件中定義映射關(guān)系。從配置文件中加載映射關(guān)系,然后將Java類的屬性值賦值給數(shù)據(jù)庫表中的相應(yīng)字段,或者是將數(shù)據(jù)庫表中的數(shù)據(jù)賦值給Java類的屬性。
假設(shè)我們有一個用戶表,表格如下:
| id | name | eml | password |
|—-|——|———————–|———-|
| 1 | Tom | [email protected] | 123456 |
| 2 | Sally | [email protected] | 111111 |
| 3 | Jerry | [email protected] | 654321 |
現(xiàn)在我們可以用Mybatis將它映射成一個Java實體類,代碼如下:
public class User {
private Long id;
private String name;
private String eml;
private String password;
// getter and setter methods
}
在Mybatis配置文件中定義SQL語句和映射關(guān)系:
SELECT * FROM users WHERE id = #{id}
其中id屬性表示這個SQL語句的唯一標識。parameterType屬性表示輸入?yún)?shù)類型,resultType屬性表示結(jié)果集類型。這里我們指定查詢結(jié)果映射為User類。
在使用Mybatis時,將用戶數(shù)據(jù)與User類屬性映射的代碼如下:
User user = sqlSession.selectOne(“getUserById”, 1L);
在這句代碼中,getUserById是我們在映射文件中定義的SQL語句的id,1L是輸入?yún)?shù)。這條語句將查詢id為1的用戶信息,將結(jié)果映射到User實體類中。
3、
反射實體和數(shù)據(jù)庫映射是Mybatis中常用的技術(shù),使用它們可以實現(xiàn)Java對象和數(shù)據(jù)庫表的快速映射,方便開發(fā)者對數(shù)據(jù)進行處理。使用Mybatis時,在配置文件中定義SQL語句和映射關(guān)系,然后在代碼中調(diào)用相應(yīng)的SQL方法,即可實現(xiàn)數(shù)據(jù)訪問和操作。
相關(guān)問題拓展閱讀:
- java通過反射拿到mybatis中的sql語句并操作怎么用什么時候用?
- MyBatis解析
java通過反射拿到mybatis中的sql語句并操作怎么用什么時候用?
操作。具體的步驟如下:
獲取 MyBatis 中的 MappedStatement 對象??梢酝ㄟ^ SqlSession 的 getConfiguration() 方法獲取 Configuration 對象,然后再通過 Configuration 對象的 getMappedStatement() 方法獲取 MappedStatement 對象。
從 MappedStatement 對象中獲取 BoundSql 對象,即 SQL 語句綁定的參數(shù)對象。
從 BoundSql 對象中獲取 SQL 語句字符串。可以通過調(diào)用 getSql() 方法獲取 SQL 語句字符串。
對 SQL 語句進行相應(yīng)的操作。例如,可以對 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 語句進行相應(yīng)的操作
// …
} finally {
sqlSession.close();
}
需要注意的是,在使用反射獲族晌取 SQL 語句時,要注意保護用戶隱私和安全,以免發(fā)生 SQL 注入等問題。
使用Java反射來獲取MyBatis中的SQL語句并進行操作的需求并不常見。通常,MyBatis會處理SQL語句的執(zhí)行和結(jié)果映射。然而,如果您確實有這樣的需求,可以使用以下方法來實現(xiàn)。
首先,您需要從MyBatis的映射器接口(Mapper接口)中獲取SQL語句。這里跡掘我們假設(shè)您已經(jīng)定義了一個映射器接口和相應(yīng)的XML映射文件。例如,UserMapper接口和對應(yīng)的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文件并查找相應(yīng)的SQL語句。
獲取SQL語句后,您可以根據(jù)需求對其進行操作。然而,直接操作SQL語句可能會導(dǎo)致一些問題,例如SQL注入、難以維護等。因此,請謹慎考慮是否確實需要這樣做。
MyBatis解析
從命名上可以看出,這個是一個 Builder 模式的,用于創(chuàng)建 SqlSessionFactory 的類。SqlSessionFactoryBuilder 根據(jù)配置來構(gòu)造 SqlSessionFactory。其中配置方式有兩種:
mybatis-config.xml 就是我們的配置文件:
Java Config 相比較 XML 文件的方式而言,會有一些限制。比如修改了配置文件需要重新編譯,注解方式?jīng)]有 XML 配置項多等。所以,業(yè)界大多數(shù)情況下是選擇 XML 文件的方式。但到底選擇哪種方式,這個要取決與自己團隊的需要。比如,項目的 SQL 語句不復(fù)雜,也不需要一些高級的 SQL 特性,那么 Java Config 則會更加簡潔一點;反之,則可以選擇 XML 文件的方式。
創(chuàng)建配置文件解析器XMLConfigBuilder
解析mybatis-config.xml里的配置為Configuration對象,Mybatis的全局配置對象。
XMLConfigBuilder#parseConfiguration解析mapper下的xml
XMLMapperBuilder#bindMapperForNamespace,根據(jù)xml里的 namespace 反射出 mapper接口 的 class,如果有mapper接口,則把該mapper接口的class添加到Configuration的mapperRegistry里。
如果該接口已經(jīng)注冊,則拋出已經(jīng)綁定的異常。
為該接口注模春冊MapperProxyFactory,但這里只是注冊其創(chuàng)建MapperProxy的工廠,并不是創(chuàng)建MapperProxy。
如果Mapper對應(yīng)的xml資源未加載,觸發(fā)xml的綁定操作,將xml中的sql語句與Mapper建立關(guān)系。
addMapper方法,只是為**Mapper創(chuàng)建對應(yīng)對應(yīng)的MapperProxyFactory。
根據(jù)Mapper接口與SqlSession創(chuàng)建MapperProxy對象。
根據(jù)接口類獲取MapperProxyFactory。爛悄
調(diào)用MapperProxyFactory的newInstance創(chuàng)建MapperProxy對象。
SqlSessionFactory 顧名思義,是用于生產(chǎn) SqlSession 的工廠。 通過如下的方式來獲取 SqlSession 實例:
SqlSession 包含了執(zhí)行 SQL 的所有的方法。以下是示例:
當然,下面的方式可以做到類型安全:
MapperProxy是MapperProxyFactory使用SqlSession創(chuàng)建出來的。所以MapperProxy中包含SqlSession。
可以看到MapperProxy調(diào)用invoke方法,進而調(diào)用MapperMethod的execute(),這些MapperMethod就是和你要執(zhí)行的命令相關(guān),比如執(zhí)行select語句,則會通過SqlSession的select()方法,最饑碼渣終調(diào)用到Executor的query方法。Executor會再協(xié)調(diào)另外三個核心組件。
MapperProxy:
MapperMethod:
插件的構(gòu)建:
談原理首先要知道StatementHandler,ParameterHandler,Result Handler都是代理,他們是Configuration創(chuàng)建,在創(chuàng)建過程中會調(diào)用interceptorChain.pluginAll()方法,為四大組件組裝插件(再底層是通過Plugin.wrap(target,XX, new Plugin( interceptor))來來創(chuàng)建的)。
插件鏈是何時構(gòu)建的:
在執(zhí)行SqlSession的query或者update方法時,SqlSession會通過Configuration創(chuàng)建Executor代理,在創(chuàng)建過程中就調(diào)用interceptor的pluginAll方法組裝插件。然后executor在調(diào)用doQuery()方法的時候,也會調(diào)用Configuration的newStatementHandler方法創(chuàng)建StatemenHandler(和上面描述的一樣,這個handler就是個代理,也是通過interceptorChain的pluginAll方法構(gòu)建插件)
插件如何執(zhí)行:
以statementhandler的prepare方法的插件為例,正如前面所說,statementhandler是一個proxy,執(zhí)行他的prepare方法,將調(diào)用invokeHandler的invoke方法,而invokeHandler就是Plugin.wrap(target, xxx, new Plugin(interceptor))中的第三個參數(shù),所以很自然invokeHanlder的invoke的方法最終就會調(diào)用interceptor對象的intercept方法。
Mybatis的插件配置在configuration內(nèi)部,初始化時,會讀取這些插件,保存于Configuration對象的InterceptorChain中。
org.apache.ibatis.plugin.InterceptorChain.java源碼。
上面的for循環(huán)代表了只要是插件,都會以責任鏈的方式逐一執(zhí)行,所謂插件,其實就類似于攔截器。
插件的編寫
插件必須實現(xiàn)org.apache.ibatis.plugin.Interceptor接口。
-intercept()方法:執(zhí)行攔截內(nèi)容的地方,攔截目標對象的目標方法的執(zhí)行
-plugin()方法:決定是否觸發(fā)intercept()方法。 作用:包裝目標對象,包裝就是為目標對象創(chuàng)建一個代理對象
-setProperties()方法:給自定義的攔截器傳遞xml配置的屬性參數(shù)。將插件注冊時的property屬性設(shè)置進來
下面自定義一個攔截器:
為什么要寫Annotation注解?注解都是什么含義?
Mybatis規(guī)定插件必須編寫Annotation注解,是必須,而不是可選。@Intercepts注解:裝載一個@Signature列表,一個@Signature其實就是一個需要攔截的方法封裝。那么,一個攔截器要攔截多個方法,自然就是一個@Signature列表。
type = Executor.class, method = “query”, args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }
解釋:要攔截Executor接口內(nèi)的query()方法,參數(shù)類型為args列表。
Plugin.wrap(target, this)是干什么的?
使用JDK的動態(tài)代理,給target對象創(chuàng)建一個delegate代理對象,以此來實現(xiàn)方法攔截和增強功能,它會回調(diào)intercept()方法。
Mybatis可以攔截哪些接口對象?
Mybatis只能攔截ParameterHandler、ResultSetHandler、StatementHandler、Executor共4個接口對象內(nèi)的方法。
重新審視interceptorChain.pluginAll()方法:該方法在創(chuàng)建上述4個接口對象時調(diào)用,其含義為給這些接口對象注冊攔截器功能,注意是注冊,而不是執(zhí)行攔截。
攔截器執(zhí)行時機:plugin()方法注冊攔截器后,那么,在執(zhí)行上述4個接口對象內(nèi)的具體方法時,就會自動觸發(fā)攔截器的執(zhí)行,也就是插件的執(zhí)行。
Invocation
可以通過invocation來獲取攔截的目標方法,以及執(zhí)行目標方法。
分頁插件原理
由于Mybatis采用的是邏輯分頁,而非物理分頁,那么,市場上就出現(xiàn)了可以實現(xiàn)物理分頁的Mybatis的分頁插件。 要實現(xiàn)物理分頁,就需要對String sql進行攔截并增強,Mybatis通過BoundSql對象存儲String sql,而BoundSql則由StatementHandler對象獲取。
因此,就需要編寫一個針對StatementHandler的query方法攔截器,然后獲取到sql,對sql進行重寫增強。
關(guān)于mybatis反射實體和數(shù)據(jù)庫的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗。專業(yè)提供云主機、虛擬主機、域名注冊、VPS主機、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
當前標題:實現(xiàn)雙向映射:Mybatis反射實體和數(shù)據(jù)庫。(mybatis反射實體和數(shù)據(jù)庫)
瀏覽地址:http://fisionsoft.com.cn/article/coschii.html


咨詢
建站咨詢
