新聞中心
實現雙向映射:mybatis反射實體和數據庫

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


咨詢
建站咨詢
