Mybatis 創(chuàng)建方法、全局配置教程詳解
總體介紹:MyBatis實(shí)際上是Ibatis3.0版本以后的持久化層框架【也就是和數(shù)據(jù)庫打交道的框架】!
和數(shù)據(jù)庫打交道的技術(shù)有:
原生的JDBC技術(shù)--->Spring的JdbcTemplate技術(shù)
這些工具都是提供簡單的SQL語句的執(zhí)行,但是和我們這里學(xué)的MyBatis框架還有些不同,
框架是一整套的東西,例如事務(wù)控制,查詢緩存,字段映射等等。
我們用原生JDBC操作數(shù)據(jù)庫的時(shí)候都會經(jīng)過:
編寫sql---->預(yù)編譯---->設(shè)置參數(shù)----->執(zhí)行sql------->封裝結(jié)果
我們之所以不使用原生的JDBC工具,是因?yàn)檫@些工具:
1.功能簡單,sql語句編寫在java代碼里面【一旦修改sql,就需要將java及sql都要重新編譯!】這屬于硬編碼高耦合的方式。
2.我們希望有開發(fā)人員自己編寫SQL語句,并且希望SQL語句與java代碼分離,將SQL語句編寫在xml配置文件中,實(shí)現(xiàn)數(shù)據(jù)表中記錄到對象之間的映射!
sql和java編碼分開,功能邊界清晰,一個(gè)專注于業(yè)務(wù),一個(gè)專注于數(shù)據(jù),可以使用簡單的XML或注解用于配置和原始映射,將接口和Java的POJO映射成數(shù)據(jù)庫中的記錄,完成業(yè)務(wù)+底層數(shù)據(jù)庫的媒介!
1.MyBatis歷史
原是Apache的一個(gè)開源項(xiàng)目iBatis, 2010年6月這 個(gè)項(xiàng)目由Apache Software Foundation 遷移
到了 Google Code,隨著開發(fā)團(tuán)隊(duì)轉(zhuǎn)投Google Code 旗下, iBatis3.x正式更名為MyBatis ,代碼于 2013年11月遷移到Github(下載地址見后)。
iBatis一詞來源于“internet”和“abatis”的組合,是 一個(gè)基于Java的持久層框架。
iBatis提供的持久 層框架包括SQL Maps和Data Access Objects、(DAO)
2.MyBatis簡介:
MyBatis 是支持定制化 SQL、存儲過程以及高級 映射的優(yōu)秀的持久層框架
MyBatis 避免了幾乎所有的 JDBC 代碼和手動設(shè)置參數(shù)以及獲取結(jié)果集
MyBatis可以使用簡單的XML或注解用于配置和原 始映射,將接口和
Java的POJO(Plain Old JavaObjects,普通的Java對象)映射成數(shù)據(jù)庫中的記錄.
3.為什么要使用MyBatis?
MyBatis是一個(gè)半自動化的輕量級的持久化層框架。
JDBC
– SQL夾在Java代碼塊里,耦合度高導(dǎo)致硬編碼內(nèi)傷
– 維護(hù)不易且實(shí)際開發(fā)需求中sql是有變化,頻繁修改的情況多見
Hibernate和JPA
– 長難復(fù)雜SQL,對于Hibernate而言處理也不容易
– 內(nèi)部自動生產(chǎn)的SQL,不容易做特殊優(yōu)化。
– 基于全映射的全自動框架,大量字段的POJO進(jìn)行部分映射時(shí)比較困難。 導(dǎo)致數(shù)據(jù)庫性能下降。
對開發(fā)人員而言,核心sql還是需要自己優(yōu)化
sql和java編碼分開,功能邊界清晰,一個(gè)專注業(yè)務(wù)、 一個(gè)專注數(shù)據(jù)。
4.去哪里找MyBatis?
https://github.com/mybatis/mybatis-3/
或者在百度直接搜索mybatis,然后找到github下的地址下載即可!
寫一個(gè) MyBatis 的 HelloWorld:
- 創(chuàng)建數(shù)據(jù)庫及數(shù)據(jù)表并插入數(shù)據(jù)
- 創(chuàng)建一個(gè)動態(tài)WEB工程,然后創(chuàng)建與上述數(shù)據(jù)表對應(yīng)的實(shí)體類
- [參考mybatis官方文檔]加入需要的jar包[mybatis所需要的jar包,和數(shù)據(jù)庫打交道的jar包,以及看打印日志所需要的log4j的jar包]:
1.log4j-1.2.17.jar 注意:log4j的jar包是需要log4j.xml文件的
2.mybatis-3.4.1.jar
3.mysql-connector-java-5.1.37-bin.jar
- 創(chuàng)建 mybatis-config.xml 文件并將 mybatis 文檔中的內(nèi)容復(fù)制過來,并將數(shù)據(jù)庫配置信息換成自己的:
mybatis-config.xml 是總控制文件,EmployeeMapper.xml 是MyBatis的 sql映射文件,在里面也 sql 語句
所有的 sql映射文件都會寫到總控文件中
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" <br>"http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="jdbc.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/neuedu/mapper/EmployeeMapper.xml" /> </mappers> </configuration>
- 創(chuàng)建測試用例,.復(fù)制mybatis官方文檔代碼,代碼如下:
public class TestMyBatis { @Test public void test() { String resource = "mybatis-config.xml"; InputStream inputStream = null; try { inputStream = Resources.getResourceAsStream(resource);//從配置文件中讀取一個(gè)流 } catch (IOException e) { e.printStackTrace(); } //利用這個(gè)流創(chuàng)建一個(gè)sqlSessionFactory對象,也就是總控文件創(chuàng)建了這個(gè)對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //和數(shù)據(jù)庫建立的一次會話,通過openSession,創(chuàng)建一個(gè)sqlsession對象 SqlSession sqlsession = sqlSessionFactory.openSession(); try { //selectOne查詢一條記錄,第一個(gè)參數(shù)時(shí)sql語句的唯一標(biāo)識,第二個(gè)參數(shù)時(shí)sql要用的參數(shù) //為了確保唯一標(biāo)識唯一,所以在前面寫上namespace,因?yàn)閚amesapce唯一 //如果第二個(gè)參數(shù)"4"在數(shù)據(jù)庫中找不到的話,不會報(bào)錯(cuò),返回null Object selectOne = sqlsession.selectOne("com.neuedu.MyBatis.EmployeeMapper.selectStudentById",4 ); System.out.println(selectOne); } finally { sqlsession.close(); } } }
- 創(chuàng)建sql語句的映射文件EmployeeMapper.xml;
<mapper namespace="com.neuedu.MyBatis.EmployeeMapper"> <!-- namespace:名稱空間,隨便起一個(gè)名,但是要唯一 id:sql 語句的唯一標(biāo)識 #{id}:接收參數(shù)傳遞過來的id值 resultType:將 sql語句返回成什么對象 --> <select id="selectStudentById" resultType="com.neuedu.entity.Employee"> select * from student where id = #{id} </select> </mapper>
總結(jié):
– 創(chuàng)建一張測試表
– 創(chuàng)建對應(yīng)的javaBean
– 創(chuàng)建mybatis配置文件,sql映射文件
– 測試
/** * 1.根據(jù)xml配置文件(全局配置文件)創(chuàng)建一個(gè)SqlSessionFactory對象 * 有數(shù)據(jù)源的一些運(yùn)行環(huán)境信息 * 2.sql映射文件,配置了每一個(gè)sql,以及sql的封裝規(guī)則等。 * 3.將sql映射文件注冊在全局配置文件中 * 4.寫代碼: * 1)根據(jù)全局配置文件得到SqlSessionFactory * 2)使用sqlSession工廠,獲取到sqlSession對象使用它來執(zhí)行增刪改查! * sqlSession就是代表和數(shù)據(jù)庫的一次會話!用完要關(guān)閉! * 3)使用sql的唯一標(biāo)識告訴MyBatis執(zhí)行哪個(gè)sql。而sql都是保存 * 在sql映射文件中的。 */
上面這種開發(fā)方式是老版本的Mybatis使用者的開發(fā)方式!而新一批的Mybatis使用者都是使用接口的方法
HelloWorld----接口式編程
- 新創(chuàng)建一個(gè) mapper包,里面包含 mapper接口,與 mapper.xml文件相對應(yīng)
public interface EmployeeMapper { /* * 增刪改查方法 * */ public Employee getEmployeeById(Integer id); } - 通過mapper.xml的 namespace 相關(guān)聯(lián) <mapper namespace="com.neuedu.mapper.EmployeeMapper"> <!-- namespace:將sql映射文件和Mapper接口進(jìn)行關(guān)聯(lián) id:要和相對應(yīng)的mapper接口的方法名保持一致 #{id}:從參數(shù)中獲取id resultType:將 sql語句返回成什么對象 --> <!-- public Employee getEmployeeById(Integer id); --> <select id="getEmployeeById" resultType="com.neuedu.entity.Employee"> select * from student where id = #{id} </select> </mapper> - sqlSession 對象表示服務(wù)器和數(shù)據(jù)庫的一次會話,是一個(gè)非線程安全的,所以不能定義在類中,定義在類中,多線程的情況下會有多個(gè)線程共用,一次使用獲取一次 ,保證時(shí)線程安全的 private SqlSessionFactory getSqlSessionFactory(){ String resource = "mybatis-config.xml"; InputStream inputStream = null; try { inputStream = Resources.getResourceAsStream(resource);//從配置文件中讀取一個(gè)流 } catch (IOException e) { e.printStackTrace(); } //利用這個(gè)流創(chuàng)建一個(gè)sqlSessionFactory對象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); return sqlSessionFactory; } - 測試 @Test public void test01(){ //1.獲取sqlSessionFactory對象 SqlSessionFactory sqlSessionFactory = getSqlSessionFactory(); //2.利用sqlSessionFactory創(chuàng)建一個(gè)session對象,表示和數(shù)據(jù)庫的一次會話 SqlSession session = sqlSessionFactory.openSession(); //3.用session對象獲取mapper接口的代理對象 //因?yàn)閟ql映射文件給相應(yīng)的接口創(chuàng)建了一個(gè)代理對象,所以mapper接口類不需要實(shí)現(xiàn)類 EmployeeMapper mapper = session.getMapper(EmployeeMapper.class); //通過mapper接口的代理對象就可以對數(shù)據(jù)庫進(jìn)行增刪改查操作 Employee employee = mapper.getEmployeeById(4); System.out.println(employee); session.close(); }
以前都是需要為接口寫一個(gè)實(shí)現(xiàn)類,但是此時(shí),mybatis提供了接口可以與sql配置文件動態(tài)綁定!
如何將兩者進(jìn)行綁定?以前sql配置文件的namespace可以隨便寫,現(xiàn)在就不能隨便寫了,需要指定為接口的全限定名!
此時(shí)接口和sql配置文件做了綁定,還要將select標(biāo)簽的id和方法名進(jìn)行綁定
總結(jié):
1.接口式編程
原生: Dao ==================> DaoImpl
mybatis: xxMapper ================> xxMapper.xml
2.SqlSession代表和數(shù)據(jù)庫的一次會話,用完必須關(guān)閉。
3.SqlSession和Connection一樣,都是非線程安全的,每次使用都是應(yīng)該去獲取新的對象,不要將這個(gè)對象定義在類變量中使用!
4.mapper接口沒有實(shí)現(xiàn)類,但是mybatis這個(gè)接口生成一個(gè)代理對象
<!--將接口與xml文件進(jìn)行綁定 --> EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
5.兩個(gè)重要的配置文件
- mybatis的全局配置文件(mybatis-config.xml):包含數(shù)據(jù)庫連接池信息,事務(wù)管理器信息等..系統(tǒng)運(yùn)行環(huán)境信息。
- sql映射文件(EmployeeMapper.xml):保存了每一個(gè)sql語句的映射信息。
Mybatis的全局配置文件
MyBatis 的配置文件包含了影響 MyBatis 行為甚深的設(shè)置(settings)和屬性(properties)信息。文檔的頂層結(jié)構(gòu)順序如下:
- configuration 配置
- properties 屬性:加載properties文件
- settings 設(shè)置
- typeAliases 類型命名
- typeHandlers 類型處理器
- objectFactory 對象工廠
- plugins 插件
- environments 環(huán)境
- environment 環(huán)境變量
- transactionManager 事務(wù)管理器
- dataSource 數(shù)據(jù)源
- databaseIdProvider 數(shù)據(jù)庫廠商標(biāo)識
- mappers 映射器
dtd文檔規(guī)定了以上順序不能變
具體介紹:
1.configuration 為全局配置文件綁定dtd約束:
1)聯(lián)網(wǎng)會自動綁定
2)沒網(wǎng)的時(shí)候【/org/apache/ibatis/builder/xml/mybatis-3-config.dtd】:解壓mybatis 的jar包然后在eclipse中綁定
Window-->Preference-->XML-->XML Catalog
2. properties屬性
<configuration> <!-- mybatis可以使用properties來引入外部properties配置文件的內(nèi)容 resource:引入類路徑下的資源 url:引入網(wǎng)絡(luò)路徑或者磁盤路徑下的資源 --> <properties resource="jdbc.properties"></properties> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.passowrd}"/> </dataSource> </environment> </environments> <!-- 將我們寫好的sql映射文件一定要注冊到全局配置文件中,文件用/,類用.,也就是如果是class就用.分隔 --> <mappers> <mapper resource="EmployeeMapper.xml"/> </mappers> </configuration>
3.settings包含很多重要的設(shè)置項(xiàng)
setting:用來設(shè)置每一個(gè)設(shè)置 - name:設(shè)置屬性名 - value:設(shè)置屬性值 <!-- settings標(biāo)簽可以設(shè)置多個(gè)屬性值 --> <settings> <!-- setting標(biāo)簽負(fù)責(zé)每一個(gè)屬性的設(shè)置 --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> - mapUnderscoreToCamelCase 可以將數(shù)據(jù)庫中帶下劃線的名稱,與類中駝峰式命名的名稱對應(yīng)起來
比如,在數(shù)據(jù)庫中名稱為 user_name,在實(shí)體類中名稱為userName,value值是true的話,也可以對應(yīng)上
4.typeAliases:起別名
<!-- typeAliases可以為多個(gè)類起別名 --> <typeAliases> <!-- 別名處理器,可以為某個(gè)java類型設(shè)置別名 默認(rèn)是該類名的首字母小寫,別名不區(qū)分大小寫 alias:可以通過該屬性單獨(dú)指定別名--> <!-- <typeAlias type="com.neuedu.entity.Employee" alias="asd"/> --> <!-- 用package可以批量為類起別名 --> <!-- 批量起別名的情況下,使用@Alias注解為某個(gè)實(shí)體類指定新的別名 --> <package name="com.neuedu.entity"/> </typeAliases>
雖然有這么多的別名可以使用:但是建議還是使用全類名,看SQL語句是怎么被封裝為JAVA 對象的時(shí)候簡單!
5.typeHandlers:類型處理器
類型處理器:負(fù)責(zé)如何將數(shù)據(jù)庫的類型和java對象類型之間轉(zhuǎn)換的工具類
6.environments:環(huán)境們
<!-- environments:環(huán)境們,mybatis可以配置多種環(huán)境,default指定使用某種環(huán)境??梢赃_(dá)到快速切換環(huán)境。 environment:配置一個(gè)具體的環(huán)境信息;必須有兩個(gè)標(biāo)簽;id代表當(dāng)前環(huán)境的唯一標(biāo)識 transactionManager:事務(wù)管理器 type:事務(wù)管理器的類型;type="[JDBC|MANAGED]"),這兩個(gè)都是別名,在Configuration類中可以查看具體類!但是Spring對事務(wù)的控制才是最終的管理方案! 當(dāng)然也可以自定義事務(wù)管理器:只需要和人家一樣實(shí)現(xiàn)TransactionFactory接口,type指定為全類名。 dataSource:數(shù)據(jù)源 type:type="[UNPOOLED|POOLED|JNDI]" 自定義數(shù)據(jù)源:實(shí)現(xiàn)DataSourceFactory接口,type也是全類名 但是我們也說了,無論是事務(wù)管理器的配置還是數(shù)據(jù)源的配置我們都會使用spring來做,這里只需要了解一下即可! --> <environments default="development"> <environment id="test"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.passowrd}"/> </dataSource> </environment> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.passowrd}"/> </dataSource> </environment> </environments>
7.databaseIdProvider環(huán)境
MyBatis 可以根據(jù)不同的數(shù)據(jù)庫廠商執(zhí)行不同的語句
<databaseIdProvider type="DB_VENDOR"> <property name="SQL Server" value="sqlserver"/> <property name="DB2" value="db2"/> <property name="Oracle" value="oracle"/> <property name="MySQL" value="mysql"/> </databaseIdProvider>
Type: DB_VENDOR
– 使用MyBatis提供的VendorDatabaseIdProvider解析數(shù)據(jù)庫 廠商標(biāo)識。也可以實(shí)現(xiàn)DatabaseIdProvider接口來自定義。
Property-name:數(shù)據(jù)庫廠商標(biāo)識
Property-value:為標(biāo)識起一個(gè)別名,方便SQL語句使用
在mybatis的全局配置文件配置了這個(gè)之后,我們只需要在sql映射文件中通過在執(zhí)行語句的標(biāo)簽上加一個(gè)屬性databaseId即可!
databaseId 與 value 值對應(yīng)
<select id="getEmployeeById" resultType="emp"> select * from tbl_employee where id = #{id} </select> <select id="getEmployeeById" resultType="emp" databaseId="mysql"> select * from tbl_employee where id = #{id} </select> <select id="getEmployeeById" resultType="emp" databaseId="oracle"> select * from tbl_employee where id = #{id} </select>
這樣在執(zhí)行不同數(shù)據(jù)庫的時(shí)候,就會執(zhí)行不同數(shù)據(jù)庫的語句了
當(dāng)然如上所示:當(dāng)有指定了databaseId屬性的和沒有指定databaseId屬性的,都有的情況下那就按著有指定databaseId屬性的sql語句執(zhí)行!
<environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> <environment id="dev_oracle"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments>
8.mapper映射
<!-- mappers:將sql映射注冊到全局配置中 --> <mappers> <!-- mapper:注冊一個(gè)sql映射 注冊配置文件: resource:引用類路徑下的sql映射文件 mybatis/mapper/EmployeeMapper.xml url:引用網(wǎng)絡(luò)路徑下或者磁盤路徑下的sql映射文件 url="file:///var/mappers/AuthorMapper.xml" 注冊接口 class:引用(注冊)接口: 1.有sql映射文件,映射文件名必須和接口同名,并且放在與接口同一個(gè)目錄下(可以在conf下見一個(gè)同名的包,放在里面); 2.沒有sql映射文件,所有的sql都是利用注解寫在接口方法上; 推薦: 比較重要的,復(fù)雜的Dao接口我們來寫sql映射文件 不重要,見到的Dao接口為了開發(fā)快速可以使用注解 --> <!-- <mapper class="com.neuedu.mapper.EmployeeMapper"/> --> <mapper resource="com/neuedu/mapper/EmployeeMapper.xml"/> <!-- 批量注冊: 對于sql 映射文件和接口需要保證在同一個(gè)包下,且名字必須相同 --> <package name="com.neuedu.mapper"/> </mappers>
class:當(dāng)映射文件和接口文件不在同一目錄下時(shí),用注解
但是不建議使用注解,建議使用sql映射文件
public interface EmployeeMapper { /* * 增刪改查方法 * */ @Select("select * from student where id = #{id}") public Employee getEmployeeById(Integer id); }
9.最后就是全局配置文件中標(biāo)簽實(shí)際上是有順序的!
使用自定義的數(shù)據(jù)源
- 導(dǎo)包:C3P0 - 新建類繼承 UnpooledDataSourceFactory - 提供無參構(gòu)造器,并將 dataSource屬性設(shè)置成想要連接的數(shù)據(jù)庫連接池 public class C3P0DateSource extends UnpooledDataSourceFactory{ public C3P0DateSource() { this.dataSource = new ComboPooledDataSource(); } } - 在總控文件 mybatis-config.xml 中修改 dataSource 路徑
將 property 中的 name 換做 C3P0 中的寫法
<environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="com.neuedu.datasource.C3P0DateSource"> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments>
總結(jié)
以上所述是小編給大家介紹的Mybatis 創(chuàng)建方法、全局配置教程詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
解析ConcurrentHashMap: get、remove方法分析
ConcurrentHashMap是由Segment數(shù)組結(jié)構(gòu)和HashEntry數(shù)組結(jié)構(gòu)組成。Segment的結(jié)構(gòu)和HashMap類似,是一種數(shù)組和鏈表結(jié)構(gòu),今天給大家普及java面試常見問題---ConcurrentHashMap知識,一起看看吧2021-06-06java并發(fā)編程專題(十一)----(JUC原子類)數(shù)組類型詳解
這篇文章主要介紹了JAVA JUC原子類 數(shù)組類型詳解的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07Java實(shí)現(xiàn)文件上傳到服務(wù)器本地并通過url訪問的方法步驟
最近項(xiàng)目中使用到了文件上傳到服務(wù)器的功能,下面這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)文件上傳到服務(wù)器本地并通過url訪問的方法步驟,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04在idea2023中使用SpringBoot整合Lombok全過程及詳細(xì)用法
Lombok項(xiàng)目是一個(gè)java庫,它可以自動插入到編輯器和構(gòu)建工具中,增強(qiáng)java的性能,本文詳細(xì)給大家介紹了在idea2023中使用SpringBoot整合Lombok全過程及詳細(xì)用法,需要的朋友可以參考下2023-09-09Java?axios與spring前后端分離傳參規(guī)范總結(jié)
這篇文章主要介紹了Java?axios與spring前后端分離傳參規(guī)范總結(jié),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-08-08Java實(shí)現(xiàn)注冊登錄跳轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)注冊登錄跳轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06