<table><tbody><tr><td>為什么要使用框架?使用軟件框架的優(yōu)點(diǎn)總結(jié)</td></tr></tbody></table>
思維導(dǎo)圖
導(dǎo)學(xué)
MyBatis是一個大名鼎鼎的ORM框架,對于我們進(jìn)行數(shù)據(jù)庫開發(fā)有著非常優(yōu)秀的支持。 首先我們要了解,什么是框架?框架,即 framework。其實(shí)就是某種應(yīng)用的半成品,就是一組組件,供你選用完成你自己的系統(tǒng)。簡單說就是使用別人搭好的舞臺,你來做表演。而且,框架一般是成熟的,不斷升級的軟件。
【資料圖】
打個比方,Java 框架跟建筑中的框架式結(jié)構(gòu)是一樣的。使用了框架(鋼筋+混凝土)以后,你所專著的只是業(yè)務(wù)(非承重墻構(gòu)建不同格局),當(dāng)然是在遵守框架的協(xié)議上開發(fā)業(yè)務(wù)。
為什么要使用框架? 因?yàn)檐浖到y(tǒng)發(fā)展到今天已經(jīng)很復(fù)雜了,特別是服務(wù)器端軟件,涉及到的知識,內(nèi)容,問題太多。在某些方面使用別人成熟的框架,就相當(dāng)于讓別人幫你完成一些基礎(chǔ)工作,你只需要集中精力完成系統(tǒng)的業(yè)務(wù)邏輯設(shè)計(jì)。而且框架一般是成熟,穩(wěn)健的,你可以處理系統(tǒng)很多細(xì)節(jié)問題,比如,事物處理,安全性,數(shù)據(jù)流控制等問題。還有框架一般都經(jīng)過很多人使用,所以結(jié)構(gòu)很好,所以擴(kuò)展性也很好,而且它是不斷升級的,你可以直接享受別人升級代碼帶來的好處。 比如,我們可以自己DIY一臺電腦,這就是因?yàn)槲覀兛梢允褂靡粋€現(xiàn)成的主板,在這個主板上有著許多規(guī)范的接口可供其他設(shè)備加入。軟件開發(fā)中的框架
框架是可被應(yīng)用開發(fā)者定制的應(yīng)用骨架框架是一種規(guī)則,保證開發(fā)者遵守相同的方式開發(fā)程序框架提倡“不要重復(fù)造輪子”,對基礎(chǔ)功能進(jìn)行封裝
使用軟件框架的優(yōu)點(diǎn)總結(jié)
極大的提高了開發(fā)的效率統(tǒng)一的編碼規(guī)則,利于團(tuán)隊(duì)管理靈活配置的應(yīng)用,擁有更好的維護(hù)性
SSM框架介紹
Spring 對象容器框架,提供底層的對象管理,是框架的框架,其他的框架都要基于該框架進(jìn)行開發(fā)。Spring MVC web開發(fā)框架,用于替代servlet,提供Web底層的交互,進(jìn)行更有效的web開發(fā)。Mybatis 數(shù)據(jù)庫框架,用于簡化數(shù)據(jù)庫操作,對JDBC進(jìn)行了封裝及擴(kuò)展,提供了數(shù)據(jù)庫的增刪改查的便捷操作
補(bǔ)充介紹:SSH框架其實(shí)指的是Spring+Struts2+Hibernate框架,該框架更貼近于我們之前的Java Web學(xué)習(xí)內(nèi)容,較為老舊,需要較多的配置文件,并不怎么方便。
補(bǔ)充介紹:常用的數(shù)據(jù)庫框架其實(shí)還有MyBatis Plus和iBatis框架等。
MyBatis框架介紹
MyBatis是優(yōu)秀的持久層框架 --將內(nèi)存中的數(shù)據(jù)保存在數(shù)據(jù)庫中MyBatis使用XML將SQL與程序解耦,便于維護(hù)MyBatis學(xué)習(xí)簡單,執(zhí)行高效,是JDBC的延伸
對象的兩種狀態(tài):
瞬時狀態(tài):程序中運(yùn)行的對象,對象保存在內(nèi)存中,當(dāng)程序中斷或者結(jié)束(計(jì)算機(jī)關(guān)閉或重啟),該狀態(tài)對象不會保留。持久化狀態(tài):把對象數(shù)據(jù)保留在文件中,文件存儲在永久的存儲介質(zhì)里(光盤、硬盤),當(dāng)程序中斷或者計(jì)算機(jī)重啟斷電,該狀態(tài)的對象會永久保留。 所謂的持久化就是把瞬時狀態(tài)的對象轉(zhuǎn)換為持久化狀態(tài)的對象。
MyBatis開發(fā)流程-非xml形式
引入MyBatis依賴創(chuàng)建核心配置文件創(chuàng)建實(shí)體(Entity)類創(chuàng)建Mapper映射文件初始化SessionFactory利用SqlSession對象操作數(shù)據(jù)
ORM框架
O:java Object 即 Java 中的對象; R:relationship 即關(guān)系數(shù)據(jù)庫; M:mapping 將JAVA中的對象映射成關(guān)系型數(shù)據(jù)庫中的表;
MyBatis 框架是一個可以自定義 SQL 和 OR 映射的持久化框架; 框架拋棄了大部分的 JDBC 代碼,也不需要手工設(shè)置參數(shù)以及結(jié)果集的操作; 框架使用簡單的 XML 配置或者注解來映射數(shù)據(jù)類型和關(guān)系,相對于 Hibernate 框架,MyBatis 是一種半自動化的 ORM 實(shí)現(xiàn)。
MyBatis配置
在本課程中,MyBatis將依賴于Maven進(jìn)行管理。 在MyBatis中,使用xml進(jìn)行配置,有一個約定俗成的文件名叫做mybatis-config.xml,它是mybatis的一個核心配置文件。
1. Mybatis采用xml文件配置數(shù)據(jù)庫環(huán)境信息2. Mybatis環(huán)境配置標(biāo)簽3. environment配置包含數(shù)據(jù)庫驅(qū)動,URL,用戶名和密碼
前期準(zhǔn)備-新建項(xiàng)目pom.xml
4.0.0<groupId>com.dodoke</groupId><artifactId>mybatis</artifactId><version>1.0.0-SNAPSHOT</version><repositories> <repository> <id>aliyun</id> <name>aliyun</name> <!-- 可能阿里云倉庫的地址會發(fā)生變化,需要查找最新的地址 --> <url>https://maven.aliyun.com/repository/public</url> </repository></repositories><dependencies> <!-- 數(shù)據(jù)庫驅(qū)動依賴 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> </dependency> <!-- mybatis依賴 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.5</version> </dependency></dependencies>
前期準(zhǔn)備-數(shù)據(jù)庫設(shè)計(jì)下載地址https://pan.baidu.com/s/1xgxXH9tPn0O_Qf5QfmmbBg 提取碼 mso3設(shè)置idea連接數(shù)據(jù)庫resources目錄下設(shè)置mybatis的核心配置文件mybatis-config.xml
SqlSessionFactory & SqlSession
SqlSessionFactory是MyBatis中的一個重要的對象,它是用來創(chuàng)建SqlSession對象的,而SqlSession用來操作數(shù)據(jù)庫的。介紹:
SqlSessionFactory是MyBatis的核心對象SqlSessionFactory用于初始化MyBatis,讀取配置文件。是一個工廠方法,用于創(chuàng)建SqlSession對象。要保證SqlSessionFactory在應(yīng)用全局中只存在唯一的對象,通常會使用靜態(tài)類的方式對其進(jìn)行初始化。
SqlSession是MyBatis用來操作數(shù)據(jù)庫的一個核心對象,不那么嚴(yán)謹(jǐn)?shù)恼f,可以將SqlSession看做類似于我們之前學(xué)習(xí)過的JDBC的連接接口對象(Connection)執(zhí)行接口對象(PreparedStatement)的組合,用來執(zhí)行CRUD操作。介紹:
SqlSession是MyBatis操作數(shù)據(jù)庫的核心對象SqlSession使用JDBC的方式與數(shù)據(jù)庫交互SqlSession對象提供了數(shù)據(jù)表的CRUD方法
示例引入Junit組件進(jìn)行測試應(yīng)用 依賴:
junitjunit4.12
測試代碼:
package com.dodoke.mybatistest;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test;
import java.io.IOException; import java.io.Reader; import java.sql.Connection;
/**
Junit單元測試用例類
規(guī)范存放在maven項(xiàng)目的test文件夾中 */ public class MyBatisTest {
@Test public void sqlSessionFactoryTest() throws IOException {//通過MyBatis提供的資源類,獲取對應(yīng)的配置文件作為字符流讀取 //getResourceAsReader方法會默認(rèn)的從當(dāng)前classpath類路徑下加載文件 Reader reader = Resources.getResourceAsReader(“mybatis-config.xml”); //初始化SqlSessionFactory,并同時解析mybatis-config.xml文件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); System.out.println(“SqlSessionFactory對象加載成功”); //創(chuàng)建SqlSession對象,用于與數(shù)據(jù)庫產(chǎn)生交互,注意SqlSession它是JDBC的擴(kuò)展類 SqlSession sqlSession = null; try {sqlSession = sqlSessionFactory.openSession(); //在SqlSession對象底層存在Connection(java.sql)連接對象,可以通過getConnection方法得到該對象 Connection connection = sqlSession.getConnection(); //該connection對象的創(chuàng)建僅做演示測試用,在mybatis中,無需使用任何與JDBC有關(guān)的類 System.out.println(connection); } catch (Exception e) {e.printStackTrace(); } finally {if(sqlSession != null) {//在mybatis-config.xml文件中,dataSource節(jié)點(diǎn)type屬性: //如果type=“POOLED”,代表使用連接池,close則是將連接回收到連接池中 //如果type=“UNPOOLED”,代表直連,close則會調(diào)用Connection.close()方法關(guān)閉連接 //這是配置帶來的底層處理機(jī)制的不同 sqlSession.close(); } } }
}
設(shè)置MybatisUtils工具類
在之前的課程中,我們提到需要保證SqlSessionFactory在全局中保證唯一,那么如何保證該SqlSessionFactory在應(yīng)用全局保證唯一呢? 通過額外創(chuàng)建的工具類MybatisUtils對SqlSessionFactory對象的初始化以及SqlSession對象的創(chuàng)建和釋放方法進(jìn)行封裝 。說明:
一般工具類放在utils包下;用static代碼塊對靜態(tài)對象進(jìn)行初始化;這邊我們在異常捕獲后將類的初始化的過程中產(chǎn)生的異常拋出,為了外界能捕獲到這個異常信息并進(jìn)行后續(xù)處理,而不是直接終止運(yùn)行程序,我們需要將異常拋出;提供SqlSession對象的創(chuàng)建與釋放方法,工具類的大多數(shù)方法要使用static進(jìn)行描述。
工具類代碼
package com.dodoke.mybatis;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException; import java.io.Reader;
/**
MyBatisUtils工具類,創(chuàng)建全局唯一的SqlSessionFactory對象 */ public class MyBatisUtils {//設(shè)置私有靜態(tài)屬性,因?yàn)殪o態(tài)內(nèi)容屬于類而不屬于對象,且擁有全局唯一的特性 private static SqlSessionFactory sqlSessionFactory = null;
//利用靜態(tài)代碼塊在初始化類時實(shí)例化sqlSessionFactory屬性 static {try {Reader reader = Resources.getResourceAsReader(“mybatis-config.xml”); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (IOException e) {e.printStackTrace(); //需要拋出初始化的異常,并且傳入捕捉到的異常,形成一條完整的異常鏈 //以便于通知調(diào)用者 throw new ExceptionInInitializerError(e); } }
/**
獲取數(shù)據(jù)庫交互SqlSession@return SqlSession對象 */ public static SqlSession openSqlSession() {return sqlSessionFactory.openSession(); }
/**
釋放一個有效的SqlSession對象@param sqlSession 準(zhǔn)備釋放的SqlSession對象 */ public static void closeSqlSession(SqlSession sqlSession) {if(sqlSession != null) {sqlSession.close(); } } }
測試類單元測試代碼
/** * MyBatisUtils使用指南 * @throws Exception */@Testpublic void testMyBatisUtils() throws Exception { SqlSession sqlSession = null; try { sqlSession = MyBatisUtils.openSqlSession(); Connection connection = sqlSession.getConnection(); System.out.println(connection); }catch (Exception e){ throw e; } finally { MyBatisUtils.closeSqlSession(sqlSession); }}
MyBatis數(shù)據(jù)查詢
在MyBatis中,雖然我們可以使用MyBatis之前的舊形式,寫出如同JDBC那樣Java代碼和SQL代碼混合的數(shù)據(jù)操作命令,但是我們不建議大家這么做! 對于MyBatis數(shù)據(jù)查詢,可以總結(jié)出如下的步驟:1. 創(chuàng)建實(shí)體類(Entity)在main/java下創(chuàng)建com.dodoke.mybatis.entity包,entity包下創(chuàng)建數(shù)據(jù)庫中t_goods表對應(yīng)的Goods商品實(shí)體類,將數(shù)據(jù)表中的字段對應(yīng)在實(shí)體類中增加一系列的私有屬性及getter/setter方法,屬性采用駝峰命名。
/** * 數(shù)據(jù)庫t_goods表對應(yīng)映射的實(shí)體類 */public class Goods { private Integer goodsId;//商品編號 private String title;//標(biāo)題 private String subTitle;//子標(biāo)題 private Float originalCost;//原始價格 private Float currentPrice;//當(dāng)前價格 private Float discount;//折扣率 private Integer isFreeDelivery;//是否包郵 ,1-包郵 0-不包郵 private Integer categoryId;//分類編號public Integer getGoodsId() { return goodsId;}public void setGoodsId(Integer goodsId) { this.goodsId = goodsId;}public String getTitle() { return title;}public void setTitle(String title) { this.title = title;}public String getSubTitle() { return subTitle;}public void setSubTitle(String subTitle) { this.subTitle = subTitle;}public Float getOriginalCost() { return originalCost;}public void setOriginalCost(Float originalCost) { this.originalCost = originalCost;}public Float getCurrentPrice() { return currentPrice;}public void setCurrentPrice(Float currentPrice) { this.currentPrice = currentPrice;}public Float getDiscount() { return discount;}public void setDiscount(Float discount) { this.discount = discount;}public Integer getIsFreeDelivery() { return isFreeDelivery;}public void setIsFreeDelivery(Integer isFreeDelivery) { this.isFreeDelivery = isFreeDelivery;}public Integer getCategoryId() { return categoryId;}public void setCategoryId(Integer categoryId) { this.categoryId = categoryId;}
}
2. 創(chuàng)建Mapper XML說明SQL語句第二步,第三步結(jié)合使用,具體內(nèi)容在第三步中。3. 在Mapper XML中增加SQL語句對應(yīng)標(biāo)簽在main/resources下創(chuàng)建新的子目錄mappers,mappers代表映射器,里面存放的都是xml文件。創(chuàng)建GoodsMapper.xml文件來說明實(shí)體類和數(shù)據(jù)表的對應(yīng)關(guān)系(和哪個數(shù)據(jù)表對應(yīng),屬性和字段怎么對應(yīng))。 說明:A.根節(jié)點(diǎn)通過增加不同的命名空間namespace來區(qū)分不同的mapper文件,通常我們會將針對一張表操作的SQL語句放置在一個mapper文件中。B.語句節(jié)點(diǎn)的id屬性為別名,相當(dāng)于SQL名稱,同一個namespace下id要唯一,不同的namespace可以重名;因此namespace的設(shè)置就很有必要,不然調(diào)用SQL的時候分不清哪個idC.語句節(jié)點(diǎn)的resultType屬性代表返回的對象是什么,為實(shí)體類的完整路徑,在SQL語句執(zhí)行完后會自動的將得到的每一條記錄包裝成對應(yīng)的實(shí)體類的對象;
select * from t_goods order by goods_id desc limit 10
4. 在mybatis-config.xml中增加Mapper XML文件聲明其實(shí)就是讓MyBatis認(rèn)識新創(chuàng)建的GoodsMapper.xml: 在mybatis-config.xml中添加mappers標(biāo)簽,這樣MyBatis在初始化的時候才知道這個GoodsMapper.xml的存在。
5. 利用SqlSession執(zhí)行Mapper XML中的SQL語句
/** * select查詢語句執(zhí)行 * @throws Exception */@Testpublic void testSelectAll() throws Exception { SqlSession session = null; try{ session = MyBatisUtils.openSqlSession(); //selectList代表查詢多條數(shù)據(jù),selectOne代表查詢一條結(jié)果 Listlist = session.selectList("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectAll"); for(Goods g : list){ System.out.println(g.getTitle()); } }catch (Exception e){ throw e; }finally { MyBatisUtils.closeSqlSession(session); }}
對于這樣的查詢,其實(shí)獲取到的數(shù)據(jù)是存在數(shù)據(jù)丟失的,這是因?yàn)槲覀兊牟樵兘Y(jié)果類型字段和表中字段名不能匹配!6. 在mybatis-config.xml中開啟駝峰命名映射其實(shí)第六步應(yīng)該放在第五步之前,這里只是給大家作為演示。
goodsId -->
MyBatis的SQL傳參
在實(shí)現(xiàn)CRUD等操作的時候,有很多的SQL條件數(shù)據(jù)其實(shí)是通過接受前臺動態(tài)傳遞過來的參數(shù)決定的。那么如何設(shè)置這些SQL語句的參數(shù)呢? 在數(shù)據(jù)操作節(jié)點(diǎn)中,可以添加parameterType屬性指定參數(shù)類型,并采用#{param}的形式接受傳入的參數(shù)。 示例: GoodsMapper.xml
select * from t_goods where goods_id = #{value}
測試:
/** * 傳遞單個SQL參數(shù) * @throws Exception */@Testpublic void testSelectById() throws Exception { SqlSession session = null; try{ session = MyBatisUtils.openSqlSession(); //傳入的參數(shù)類型需要和對應(yīng)數(shù)據(jù)操作節(jié)點(diǎn)中指明的參數(shù)類型一致 Goods goods = session.selectOne("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectById" , 1603); System.out.println(goods.getTitle()); }catch (Exception e){ throw e; }finally { MyBatisUtils.closeSqlSession(session); }}
/**
傳遞多個SQL參數(shù)@throws Exception */ @Test public void
testSelectByPriceRange() throws Exception {SqlSession session = null;
try{session = MyBatisUtils.openSqlSession(); Map param = new HashMap();
//map中的key-value的key值,需要和數(shù)據(jù)操作節(jié)點(diǎn)中參數(shù)名一致 param.put(“min”,100); param.put(“max” ,
500); param.put(“l(fā)imt” , 10); List
多表關(guān)聯(lián)查詢
在之前的學(xué)習(xí)中,我們針對的都是一個表的查詢,那么如何針對多表進(jìn)行聯(lián)合查詢呢? 其實(shí)我們可以將返回的結(jié)果變?yōu)镸ap類型,這樣MyBatis就會將結(jié)果封裝為Map集合中對應(yīng)的鍵值對
select g.* , c.category_name from t_goods g , t_category c where g.category_id = c.category_id
/** * 利用Map接收關(guān)聯(lián)查詢結(jié)果 * @throws Exception */@Testpublic void testSelectGoodsMap() throws Exception { SqlSession session = null; try{ session = MyBatisUtils.openSqlSession(); Listlist = session.selectList("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectGoodsMap"); for(Map map : list){ System.out.println(map); } }catch (Exception e){ throw e; }finally { MyBatisUtils.closeSqlSession(session); }}
我們可以看到,該方法返回的結(jié)果為數(shù)據(jù)庫中表對應(yīng)的原始字段名為key值,而且查詢到的結(jié)果的順序是混亂的。 為了保證我們等到的結(jié)果的順序和數(shù)據(jù)庫中的順序一致,我們需要使用LinkedHashMap。
LinkedHashMap是采用鏈表形式的HashMap,他在進(jìn)行數(shù)據(jù)提取的時候是按照插入數(shù)據(jù)時的順序進(jìn)行提取保存的,不會出現(xiàn)亂序的情況。使用LinkedHashMap來接收數(shù)據(jù)是常用的,因?yàn)楣镜臄?shù)據(jù)結(jié)構(gòu)較為復(fù)雜,需要多表關(guān)聯(lián)查詢,LinkedHashMap可以有效進(jìn)行數(shù)據(jù)的擴(kuò)展,非常靈活。缺點(diǎn):太過靈活,任何查詢結(jié)果都會被LinkedHashMap包裝在內(nèi),相比較實(shí)體類而言,缺少了編譯時檢查,是很容易出錯的。
select g.* , c.category_name,"1" as test from t_goods g , t_category c where g.category_id = c.category_id
其實(shí)針對于這樣的多表查詢,我們還可以通過修改實(shí)體類來實(shí)現(xiàn),顯得不夠靈活,但是卻可以保證在編譯的時候進(jìn)行檢查。具體選用哪種方式可以根據(jù)實(shí)際情況進(jìn)行選擇。 PS:注意,在之前我們的學(xué)習(xí)中,我們是利用在mybaits-config.xml文件中設(shè)置駝峰映射的方式,來解決字段和實(shí)體類屬性名稱不能匹配的問題的,但是我們也可以設(shè)置在查詢的時候起別名的方式,解決這個問題。
ResultMap結(jié)果映射
介紹:
ResultMap可以將查詢結(jié)果映射為復(fù)雜類型的Java對象。ResultMap適用于Java對象保存多表關(guān)聯(lián)結(jié)果ResultMap是MyBatis關(guān)聯(lián)的核心所在,支持對象關(guān)聯(lián)查詢等高級特性
在上節(jié)課程中,我們也提到過,可以為了查詢結(jié)果去修改實(shí)體類。但是,這種方式在標(biāo)準(zhǔn)的mybatis開發(fā)下是不太建議的。實(shí)體類僅僅和數(shù)據(jù)表對應(yīng)就好,不要添加一些冗余的屬性,但是在實(shí)際開發(fā)中,我們有時為了方便,實(shí)際上較多的還是采用修改實(shí)體類的形式。 但是,采用DTO,數(shù)據(jù)擴(kuò)展類開發(fā)的形式,我們同學(xué)們必須掌握。 在com.dodoke.mybatis包下面新建一個dto包,新建GoodsDTO類。
DTO是一個特殊的JavaBean,數(shù)據(jù)傳輸對象。對原始對象進(jìn)行擴(kuò)展,用于數(shù)據(jù)保存和傳遞。
/** * 擴(kuò)展類,數(shù)據(jù)傳輸對象 */public class GoodsDTO { private Goods goods = new Goods(); private String categoryName; private String test;public Goods getGoods() { return goods;}public void setGoods(Goods goods) { this.goods = goods;}public String getCategoryName() { return categoryName;}public void setCategoryName(String categoryName) { this.categoryName = categoryName;}public String getTest() { return test;}public void setTest(String test) { this.test = test;}
}
使用resultMap屬性,添加結(jié)果映射
select g.* , c.*,"1" as test from t_goods g , t_category c where g.category_id = c.category_id
測試
/** * 利用ResultMap進(jìn)行結(jié)果映射 * @throws Exception */@Testpublic void testSelectGoodsDTO() throws Exception { SqlSession session = null; try{ session = MyBatisUtils.openSqlSession(); Listlist = session.selectList("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectGoodsDTO"); for (GoodsDTO g : list) { System.out.println(g.getGoods().getTitle()); } }catch (Exception e){ throw e; }finally { MyBatisUtils.closeSqlSession(session); }}
其實(shí)我們可以繼續(xù)擴(kuò)展,比如我現(xiàn)在不僅僅想要得到category_name產(chǎn)品名稱,還想要獲得其他屬性,那么我們該怎么辦呢? 新建t_category表的實(shí)體類
package com.dodoke.mybatis.entity;
public class Category {private Integer categoryId; private String categoryName; private Integer parentId; private Integer categoryLevel; private Integer categoryOrder;
public Integer getCategoryId() { return categoryId;}public void setCategoryId(Integer categoryId) { this.categoryId = categoryId;}public String getCategoryName() { return categoryName;}public void setCategoryName(String categoryName) { this.categoryName = categoryName;}public Integer getParentId() { return parentId;}public void setParentId(Integer parentId) { this.parentId = parentId;}public Integer getCategoryLevel() { return categoryLevel;}public void setCategoryLevel(Integer categoryLevel) { this.categoryLevel = categoryLevel;}public Integer getCategoryOrder() { return categoryOrder;}public void setCategoryOrder(Integer categoryOrder) { this.categoryOrder = categoryOrder;}
}
修改DTO數(shù)據(jù)對象
package com.dodoke.mybatis.dto;
import com.dodoke.mybatis.entity.Category; import com.dodoke.mybatis.entity.Goods;
/**
擴(kuò)展類,數(shù)據(jù)傳輸對象 */ public class GoodsDTO {private Goods goods = new Goods(); private Category category = new Category(); private String test;
public Goods getGoods() {return goods; }
public void setGoods(Goods goods) {this.goods = goods; }
public Category getCategory() {return category; }
public void setCategory(Category category) {this.category = category; }
public String getTest() {return test; }
public void setTest(String test) {this.test = test; } }
修改映射結(jié)果集
select g.* , c.*,"1" as test from t_goods g , t_category c where g.category_id = c.category_id
MyBatis數(shù)據(jù)寫入
在之前的課程中,我們實(shí)現(xiàn)了MyBatis的數(shù)據(jù)查詢工作,接下來,我們來看看如何實(shí)現(xiàn)數(shù)據(jù)的新增,修改和刪除工作。
數(shù)據(jù)庫事務(wù)
提到數(shù)據(jù)庫的寫入操作,就離不開數(shù)據(jù)庫的事務(wù)。數(shù)據(jù)庫事務(wù)是保證數(shù)據(jù)操作完整性的基礎(chǔ)所有從客戶端發(fā)來的新增修改刪除操作,都會被事務(wù)日志所記錄,我們形象的將事務(wù)日志看成流水賬,它記錄客戶端發(fā)來的所有寫操作的前后順序, 當(dāng)客戶端向MySQL服務(wù)器發(fā)起了一個commit提交命令的時候,事務(wù)日志才會將這三個數(shù)據(jù)同時的寫入到數(shù)據(jù)表中,在commit的時候才是真正的往數(shù)據(jù)表寫入的過程,當(dāng)這三條數(shù)據(jù)都被成功寫入到數(shù)據(jù)表中后,剛才所產(chǎn)生的事務(wù)日志都會被清空掉。 假設(shè)如果客戶端在處理這些數(shù)據(jù)的時候,數(shù)據(jù)1和數(shù)據(jù)2執(zhí)行成功,數(shù)據(jù)3因?yàn)楦鞣N原因沒有執(zhí)行成功的話,客戶端會發(fā)起一個rollback回滾命令,當(dāng)MySQL收到了rollback回滾命令后,當(dāng)前事務(wù)日志中的所有已經(jīng)產(chǎn)生的數(shù)據(jù)都會被清除,這就意味著前面已經(jīng)產(chǎn)生的數(shù)據(jù)1和數(shù)據(jù)2不會放入到數(shù)據(jù)表中,只有當(dāng)所有數(shù)據(jù)都完成的時候,在由客戶端發(fā)起commit提交,數(shù)據(jù)才能成功的寫入。要么數(shù)據(jù)全部寫入成功,要么中間出現(xiàn)了任何問題,全部回滾,保證了數(shù)據(jù)的完整性
案例
修改MyBatisUtils
/** * 獲取數(shù)據(jù)庫交互SqlSession * @return SqlSession對象 */public static SqlSession openSqlSession() { //默認(rèn)SqlSession對自動提交事務(wù)數(shù)據(jù)(commit) //設(shè)置false代表關(guān)閉自動提交,改為手動提交事務(wù)數(shù)據(jù) return sqlSessionFactory.openSession(false);}
新增
INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id) VALUES (#{title} , #{subTitle} , #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId}) select last_insert_id()
/** * 新增數(shù)據(jù) * @throws Exception */@Testpublic void testInsert() throws Exception { SqlSession session = null; try{ session = MyBatisUtils.openSqlSession(); Goods goods = new Goods(); goods.setTitle("測試商品"); goods.setSubTitle("測試子標(biāo)題"); goods.setOriginalCost(200f); goods.setCurrentPrice(100f); goods.setDiscount(0.5f); goods.setIsFreeDelivery(1); goods.setCategoryId(43); //insert()方法返回值代表本次成功插入的記錄總數(shù) int num = session.insert("com.dodoke.mybatis.resources.mappers.GoodsMapper.insert", goods); session.commit();//提交事務(wù)數(shù)據(jù) System.out.println(goods.getGoodsId()); }catch (Exception e){ if(session != null){ session.rollback();//回滾事務(wù) } throw e; }finally { MyBatisUtils.closeSqlSession(session); }}
我們在上述代碼中可以利用selectKey標(biāo)簽獲得對應(yīng)的新增主鍵,其實(shí)我們還可以利用另外一個屬性userGenerateKeys實(shí)現(xiàn)獲得新增主鍵,它們的區(qū)別在哪里呢?
SelectKey適用于所有數(shù)據(jù)庫,但需要根據(jù)不同的數(shù)據(jù)庫編寫對應(yīng)的獲得最后改變主鍵值得查詢語句userGenerateKeys只支持“自增主鍵”的數(shù)據(jù)庫(DB2,Oracle等沒有自增主鍵約束),但使用簡單,會根據(jù)不同的數(shù)據(jù)庫驅(qū)動自動編寫查詢語句,以下是該屬性的使用方法
insert 語句
如果要在Oracle中獲得新增后的主鍵,需要借助序列來實(shí)現(xiàn),其實(shí)是通過序列在執(zhí)行新增語句之前生成一個新的序列值并保存到主鍵字段中。更新與刪除
UPDATE t_goods SET title = #{title} , sub_title = #{subTitle} , original_cost = #{originalCost} , current_price = #{currentPrice} , discount = #{discount} , is_free_delivery = #{isFreeDelivery} , category_id = #{categoryId} WHERE goods_id = #{goodsId}
/** * 更新數(shù)據(jù) * @throws Exception */@Testpublic void testUpdate() throws Exception { SqlSession session = null; try{ session = MyBatisUtils.openSqlSession(); Goods goods = session.selectOne("com.dodoke.mybatis.resources.mappers.GoodsMapper.selectById", 739); goods.setTitle("更新測試商品"); int num = session.update("com.dodoke.mybatis.resources.mappers.GoodsMapper.update" , goods); session.commit();//提交事務(wù)數(shù)據(jù) }catch (Exception e){ if(session != null){ session.rollback();//回滾事務(wù) } throw e; }finally { MyBatisUtils.closeSqlSession(session); }}/** * 刪除數(shù)據(jù) * @throws Exception */@Testpublic void testDelete() throws Exception { SqlSession session = null; try{ session = MyBatisUtils.openSqlSession(); int num = session.delete("com.dodoke.mybatis.resources.mappers.GoodsMapper.delete" , 739); session.commit();//提交事務(wù)數(shù)據(jù) }catch (Exception e){ if(session != null){ session.rollback();//回滾事務(wù) } throw e; }finally { MyBatisUtils.closeSqlSession(session); }}
預(yù)防SQL注入攻擊
在之前的學(xué)習(xí)中,我們了解到什么是SQL注入攻擊,并且在JDBC課程中也去實(shí)現(xiàn)了如何預(yù)防SQL注入攻擊。那么,在MyBatis中如何去進(jìn)行SQL注入攻擊的預(yù)防呢? 其實(shí),SQL注入攻擊的原理非常簡單,就在在接收用戶輸入的時候,不對接收的數(shù)據(jù)進(jìn)行任何的判斷和轉(zhuǎn)義,導(dǎo)致在接收時可能全盤接收到諸如單引號、or等一些SQL關(guān)鍵字。 所以,預(yù)防SQL注入攻擊需要的是對接收數(shù)據(jù)進(jìn)行判斷和轉(zhuǎn)義。在MyBatis中,這些工作其實(shí)早就已經(jīng)為我們準(zhǔn)備好了。MyBatis兩種傳值方式
${}文本替換,未經(jīng)任何處理對SQL文本替換#{}預(yù)編譯傳值,使用預(yù)編譯傳值可以預(yù)防SQL注入
在我們的實(shí)際使用中,更多的還是通過#{}的形式進(jìn)行傳值
標(biāo)簽:
相關(guān)推薦:
精彩放送:
- []今日觀點(diǎn)!世茂股份擬召開債券持有人會議,所有存續(xù)公司債12月9日開市起停牌
- []多家房企拋出股權(quán)融資方案 地產(chǎn)行業(yè)困境反轉(zhuǎn)?
- []消息!又一家大行看多!摩根士丹利:中國股票將跑贏全球
- []金溢科技:關(guān)于股東人數(shù)情況,詳見公司最近一期定期報(bào)告
- []格力地產(chǎn)調(diào)整重組方案:募集配套資金超8億元,明日復(fù)牌
- []【播資訊】“小步快跑”供地風(fēng)向標(biāo)顯現(xiàn) 武漢率先開啟第六批集中供地
- []世界熱點(diǎn)評!45個重點(diǎn)城市城鎮(zhèn)化率:這六個城市超90%
- []世界熱文:星輝娛樂:(1)近兩年,受多種因素影響,公司收入和凈利潤有所下滑
- []全球速訊:被六省(市)納入新冠肺炎診療方案的化痰止咳中藥是怎樣煉成的?
- []博雅生物:公司一直在積極推進(jìn)漿站拓展工作,申請新設(shè)漿站存在不確定性,如公司獲批新設(shè),將及時披露
- []原油交易提醒:美國料陷入技術(shù)性衰退,需求減弱拖累油價五連陰
- []當(dāng)前資訊!融創(chuàng)發(fā)布境外債務(wù)初步重組框架:擬將30至40億美元借款轉(zhuǎn)為普通股等
- []世界快看點(diǎn)丨內(nèi)蒙一機(jī):公司民品業(yè)務(wù)涉及鐵路車輛及相關(guān)零部件,訂單任務(wù)充足,重要合同簽訂情況均在臨時公告中有披露
- []世界頭條:二手房買家因賣家換掉家具拒付尾款遭起訴,法院:出賣人構(gòu)成違約
- []2022財(cái)年虧損18.16億,靠港府“續(xù)命”的香港海洋公園能走多遠(yuǎn)?
- []每日快看:大葉股份:公司綜合考慮質(zhì)量、性能、交期、價格等多個因素,汽油割草機(jī)零部件為全球化采購
- []晉億實(shí)業(yè):公司主要從事各類緊固件的研究和開發(fā),生產(chǎn)銷售各類緊固件、鐵道扣件等產(chǎn)品,產(chǎn)品遠(yuǎn)銷國內(nèi)外
- []融創(chuàng)公布境外債重組重大進(jìn)展 加速回到健康發(fā)展軌道
- []新力被債權(quán)人放棄了
- []房企融資“三箭齊發(fā)”,置業(yè)信心能否回暖?
- []【環(huán)球速看料】國際油價 7日 顯著下跌
- []獨(dú)立儲能電站商業(yè)投資價值的識別與分析
- []甘肅多措并舉保障冬季電力供應(yīng)
- []天天快報(bào)!電化學(xué)儲能是什么意思?電化學(xué)儲能主要包括哪些?
- []焦點(diǎn)!成立1年,業(yè)務(wù)覆蓋30+國家和地區(qū)!這家儲能公司怎么這么猛?
- []今日看點(diǎn):車險(xiǎn)年底買是否優(yōu)惠些 年底買車保險(xiǎn)會不會優(yōu)惠些
- []【全球熱聞】美股異動 | 中概教育股普漲 新東方(EDU.US)漲超9%
- []【天天新要聞】定向增發(fā)+公司債 大名城拋出約50億元再融資方案
- []保險(xiǎn)報(bào)案有效期是多久 一般保險(xiǎn)報(bào)案的有效期限是多長時間
- []保險(xiǎn)不續(xù)費(fèi)自動退保嗎 保險(xiǎn)要是不續(xù)費(fèi)會自行退保嗎
- []參保人就是被保險(xiǎn)人嗎 被保險(xiǎn)人是不是參保人
- []公積金一定要留余額嗎 公積金必須留余額嗎
- []歲寶百貨深圳宏發(fā)大世界購物廣場門店提前終止租賃協(xié)議
- []天天滾動:2023年Q1全球計(jì)劃運(yùn)力預(yù)計(jì)達(dá)12億,法國境內(nèi)短途航班取消將為對手創(chuàng)造機(jī)會
- []頭條:川潤股份:12月7日公司高管李輝減持公司股份合計(jì)5.37萬股
- []零售云平臺多點(diǎn)數(shù)智赴港IPO 騰訊IDG是股東
- []【環(huán)球熱聞】新湖中寶擬引入衢州國資 由控股股東出讓不超過10%股權(quán)
- []科藍(lán)軟件:12月7日公司高管王安京減持公司股份合計(jì)14.84萬股
- []全球快訊:龍佰集團(tuán):12月7日公司高管張海濤增持公司股份合計(jì)1600股
- []世界球精選!歷時八個月 南京正式實(shí)施商品房預(yù)售資金監(jiān)管新政
- []當(dāng)前信息:北京銀行與重點(diǎn)房地產(chǎn)企業(yè)簽約,提供意向性融資總額2500億元
- []環(huán)球焦點(diǎn)!格力地產(chǎn)重啟收購珠海免稅 構(gòu)建三大業(yè)務(wù)板塊
- []美國房地產(chǎn)大起大落后迎來投資機(jī)會
- []每日視點(diǎn)!新柴股份:12月7日公司高管周高峰減持公司股份合計(jì)2000股
- []北京銀行:為萬科、中海、招商等重點(diǎn)房企提供意向性融資總額2500億元
- []快資訊丨佳力奇:加大自主創(chuàng)新力度 持續(xù)鞏固技術(shù)堡壘
- []當(dāng)前播報(bào):群興玩具:截止目前,公司未存在籌劃重大資產(chǎn)重組等事項(xiàng)
- []現(xiàn)貨黃金持穩(wěn),市場權(quán)衡兩大前景,警惕通脹“掛自動擋”
- []環(huán)球今日報(bào)丨中指院: A股ESG報(bào)告披露率較低
- []人福醫(yī)藥:12月7日徐華斌減持公司股份合計(jì)13萬股
- []每日快訊!越秀地產(chǎn)前11月合同銷售1029.4億元 完成年度銷售目標(biāo)83%
- []交建股份:11月28日至12月1日公司高管胡先寬、儲根法、曹振明、陳明洋、施秀瑩減持公司股份合計(jì)72.02萬股
- []物業(yè)流拍、招租進(jìn)行中,天橋百貨覓新生
- []當(dāng)前關(guān)注:合生創(chuàng)展前11月總合約銷售額281.13億元 同比下降27.73%
- []全球觀熱點(diǎn):中指院:二十城物業(yè)服務(wù)收費(fèi)穩(wěn)中略升
- []新化股份:12月6日至12月7日公司高管方軍偉減持公司股份合計(jì)8000股
- []寶龍地產(chǎn)前11月合約銷售總額約379.3億元
- []【天天新要聞】萬通發(fā)展擬投資5億元設(shè)立通信業(yè)務(wù)全資子公司
- []全球速讀:沃森生物:公司近年來持續(xù)從銷售體系建設(shè)、消費(fèi)者教育、終端服務(wù)和渠道布局多維度打造產(chǎn)品品牌和市場影響力
- []大名城擬定增不超過30億元 主要投向上海5個項(xiàng)目
- []天天熱文:黃山膠囊:我公司根據(jù)相關(guān)法律、法規(guī)及規(guī)范性文件的規(guī)定標(biāo)準(zhǔn)進(jìn)行信息披露
- []黃山膠囊:我公司與熊去氧膽酸膠囊暫無合作
- []【新要聞】中南建設(shè)三只債券獲持有人會議通過 豁免美元債交叉違約
- []每日快報(bào)!大名城擬發(fā)行本金不超過20億元的公司債券
- []全球即時看!落子布局電池租賃!寧德時代或許將用換電服務(wù)深度綁定車企
- []越秀地產(chǎn):前11月合同銷售額約為人民幣1029.4億元
- []環(huán)球快看:中華企業(yè)擬非公開發(fā)行股票不超過總股本30% 用于“保交樓“項(xiàng)目
- []德藝文創(chuàng):截至2022年11月30日(目前最新數(shù)據(jù))的股東人數(shù)為12,383
- []全球熱門:中駿集團(tuán)提前匯出12.87億以兌付購房尾款A(yù)BS本息 年內(nèi)公開債務(wù)“零違約”
- []環(huán)球報(bào)道:杭州規(guī)定保租房租金應(yīng)低于同類房源市場價格 2023年1月5日起施行
- []全球動態(tài):奧馬電器:公司產(chǎn)品為冰箱冷柜,冰箱冷柜為居民生活必備的耐用消費(fèi)品
- []全球速看:合肥搭建線上服務(wù)平臺 開啟“二手房互換”新模式
- []每日資訊:金石亞藥:目前公司產(chǎn)能及備貨充足,能夠滿足市場需求
- []實(shí)至名歸,箭牌家居榮獲行業(yè)唯一“2022國際CMF設(shè)計(jì)獎”金獎!
- []快資訊:雖遲但到 | 2022 環(huán)球旅訊峰會,12月底上海見
- []天天速遞!圖解貴金屬及外匯:多空成本+最單邊押注(2022/12/08周四)
- []熱資訊!中駿安全度過行業(yè)低谷期,年內(nèi)償還境內(nèi)外公開債務(wù)超70億元
- []世界熱門:豪森股份:公司2022年度向特定對象發(fā)行A股股票的定價基準(zhǔn)日為發(fā)行期首日
- []財(cái)面兒丨中駿集團(tuán)控股1-11月實(shí)現(xiàn)累計(jì)合同銷售金額約544.42億元
- []天天新動態(tài):西安飲食:該公司并未實(shí)際開展業(yè)務(wù)
- []青島中程:公司印尼工業(yè)園現(xiàn)場員工,克服多方困難,全力推進(jìn)RKEF鎳電項(xiàng)目剩余工程的建設(shè),爭取早日交付
- []天天日報(bào)丨財(cái)面兒|德信中國前11月累計(jì)合約銷售金額336億元
- []全球看熱訊:物業(yè)丨卓越商企服務(wù):全資附屬公司收到仲裁通知書
- []【新要聞】比特幣概念股票有哪些?2021年比特幣概念股一覽?
- []快消息!核電股票有哪些?2018核電概念股龍頭有哪些?
- []當(dāng)前快訊:股市熔斷機(jī)制是什么意思?股市熔斷機(jī)制有什么意義?
- []今日要聞!物業(yè)丨華潤萬象生活:與華潤置地訂立商業(yè)運(yùn)營服務(wù)框架協(xié)議之補(bǔ)充協(xié)議
- []全球熱議:鉬板概念股是哪些?鉬板股票一覽?
- []資訊推薦:合力泰:公司目前未涉及該業(yè)務(wù)
- []全球熱推薦:甲醇概念上市公司有哪些?甲醇概念股一覽?
- []全球短訊!2020年股市休市放假怎么安排的?A股全年休市一覽?
- []2020新能源電池概念股票有哪些?2020新能源電池概念股票一覽?
- []全球?qū)崟r:哪些是智能家居概念股?智能家居概念股名單一覽?
- []全球消息!抄底是什么意思?抄底的四大形態(tài)是怎樣的?
- []【熱聞】磷化工股票有哪些?相關(guān)磷化工概念股票有哪些?
- []【世界新要聞】面板概念龍頭股有哪些?2021年面板概念股有哪些?
- []碳中和是什么概念?碳中和概念股有哪些?
- []每日消息!太陽能電池背板上市公司有哪些?太陽能電池背板概念股一覽
- []全球滾動:虛擬現(xiàn)實(shí)板塊股票有哪些?虛擬現(xiàn)實(shí)概念股票一覽?
- []全球動態(tài):橡膠股票龍頭股有哪些?橡膠股票有哪些?
- 遺傳算法實(shí)例有哪些?函數(shù)的最大值怎么解?
- 二十年老品牌利德治療儀讓你在家安心做理療
- 頭條焦點(diǎn):FBI的WARNING是什么?簡單的靜態(tài)代碼檢測規(guī)則
- 快看點(diǎn)丨12月9日沈陽化工漲停分析:PVC,燒堿,石油化工概念熱股
為什么要使用框架?使用軟件框架的優(yōu)點(diǎn)總結(jié) - 12月9日科拓生物漲停分析:幽門螺桿菌概念,食品,寵物經(jīng)濟(jì)概念熱股
- 招行信用卡旗下App全新上線 掌上生活9.0體驗(yàn)究竟如何
- 26.4%!晶科能源182TOPCon電池轉(zhuǎn)換效率再創(chuàng)新高
- 王亞平女兒眼中的“航天女英雄”竟然是這樣的!
- WotoKOL臥兔周年,深耕海外網(wǎng)紅營銷五載
- B站注冊資本增幅400%至5億 目前由陳睿全資持股
- 光源資本出任獨(dú)家財(cái)務(wù)顧問 沐曦集成電路10億元A輪融資宣告完成
- 巨輪智能2021年上半年?duì)I收11.24億元 期內(nèi)研發(fā)費(fèi)用投入增長19.05%
- 紅棗期貨尾盤拉升大漲近6% 目前紅棗市場總庫存約30萬噸
- 嘉銀金科發(fā)布2021年Q2財(cái)報(bào) 期內(nèi)凈利潤達(dá)1.27億元同比增長208%
- 成都銀行2021上半年凈利33.89億元 期內(nèi)實(shí)現(xiàn)營收同比增長17.27億元
- 汽車之家發(fā)布2021年第二季度業(yè)績 期內(nèi)新能源汽車品牌收入增長238%
- 中信銀行上半年實(shí)現(xiàn)凈利潤290.31億元 期末不良貸款余額706.82億元
- 光伏概念掀起漲停潮交易價格創(chuàng)新高 全天成交額達(dá)1.29億元
- 上半年生物藥大增45% 關(guān)鍵財(cái)務(wù)指標(biāo)好轉(zhuǎn)營收賬款持續(xù)下降
- 世界快看:俄油上限剛出臺沖擊就已顯現(xiàn)?俄羅斯原油出口出現(xiàn)急劇減少
- 電纜上市公司有哪些?相關(guān)上市公司龍頭有哪些?
- 世界快看:核電板塊龍頭股票有哪些?核電概念股票有哪些?
- 世界微資訊!食用油板塊龍頭股票有哪些?食用油板塊龍頭股票有哪些?
- 環(huán)球視訊!2021年騰訊概念股票有哪些?騰訊概念股一覽?
- 森馬服飾股票屬于什么板塊?森馬服飾股票屬于哪些概念股?
- MINE's TALK對話祝羽捷,「一個自己的房間」 傳遞自洽生活哲學(xué)
- 世界今頭條!國際油價多頭須盡快離場,該指標(biāo)暗示需求擔(dān)憂仍唱主角
- 中交路橋建設(shè)20億元綠色公司債券已提交注冊
- 世界熱推薦:中建信息10億元應(yīng)收賬款資產(chǎn)支持ABS已獲受理
- 產(chǎn)業(yè)物流線上季快訊 | 王少華:險(xiǎn)資在物流上的投資機(jī)會將增多
- 綠城房地產(chǎn)擬發(fā)行90億元中票 項(xiàng)目狀態(tài)為“預(yù)評中”
- 上海地鐵全線受理云閃付乘車碼“一碼通行”功能
- 焦點(diǎn)快播:粵萬年青:公司產(chǎn)品消炎利膽片功能主治為“清熱,祛濕,利膽
- 精彩看點(diǎn):味知香:公司新產(chǎn)能預(yù)計(jì)前期先進(jìn)行部分投產(chǎn),后期根據(jù)生產(chǎn)運(yùn)營情況,逐步釋放產(chǎn)能
- 香港發(fā)展局:一般項(xiàng)目由“生地”變成可建屋“熟地”的時間減至4年
- 環(huán)球百事通!錫裝股份:公司沒有上述高送轉(zhuǎn)的計(jì)劃。感謝您的關(guān)心支持!
- 焦點(diǎn)短訊!金價有望繼續(xù)走強(qiáng)!世界黃金協(xié)會稱全球央行繼續(xù)購金,三季度購買量猛增至400噸
- 加碼歐洲儲能市場 優(yōu)能新能源發(fā)布新一代儲能逆變器
- 世界熱點(diǎn)!美原油交易策略:經(jīng)濟(jì)衰退擔(dān)憂籠罩市場,油價跌勢難改
- 頭條焦點(diǎn):國際金價持穩(wěn),市場擔(dān)心美聯(lián)儲繼續(xù)維持強(qiáng)硬鷹派立場
- 當(dāng)前速看:現(xiàn)貨黃金交易策略:初請數(shù)據(jù)來襲,關(guān)注200日均線阻力
- 攜程發(fā)布“2023旅游振興A計(jì)劃”,三“重”戰(zhàn)略促萬億消費(fèi)
- 天天即時看!冬季冰雪游升溫,同程旅行冰雪搜索熱度增長150%
- 全球要聞:國際金價或回踩1772美元
- 環(huán)球即時:ThinkBook16p對比聯(lián)想小新 Pro16 2021款哪個值得更好?詳細(xì)評測
- 焦點(diǎn)熱文:北京樓市,變了
- 場景化營銷精準(zhǔn)發(fā)力 錢小樂持續(xù)優(yōu)化金融服務(wù)質(zhì)效
- 環(huán)球熱頭條丨Excel函數(shù)之VLOOKUP()怎么使用?一文搞懂Excel函數(shù)之VLOOKUP()使用
- “新十條”發(fā)布后,這個省份開始搶游客了
- 全球最新:魏小安:旅游業(yè)大局三個月可定,六個月可起
- 環(huán)球百事通!FFT是什么意思?FFT的詳解
- 天天微頭條丨disable怎么運(yùn)用?disable簡單易理解用法
- 環(huán)球快報(bào):格式化時間是什么?抽象類DateFormat是什么?
- 焦點(diǎn)!中駿集團(tuán):前11月合同銷售額約544.42億元
- 全球即時:order by是什么意思?order by的詳解
- 天天熱消息:java.lang.NullPointerException解決方案是什么?
- 焦點(diǎn)消息!誅仙3新手卡怎么領(lǐng)取?誅仙3新手卡領(lǐng)取中心
- 弘陽地產(chǎn)前11月合約銷售額同比減少56.98% 單月同比跌64.3%
- 天天要聞:主板測試卡代碼a2是什么?主板測試卡代碼 常見代碼總結(jié)
- UML建模怎么用?UML建模之用例圖
- 環(huán)球百事通!國產(chǎn)搞笑電視劇排行榜你看過幾個?愛情公寓只能排倒數(shù)第三
- 【世界快播報(bào)】工廠模式是什么?工廠模式的詳解
- 世界通訊!黃淮學(xué)院最低錄取分?jǐn)?shù)線是多少?2022文理科最低分及位次
- 最美夕陽紅 攜手度余生——富德生命人壽十堰中支用鏡頭為老人定格相濡以沫的愛情
- 速訊:使用Icon圖標(biāo)的幾種方式是啥?Icon圖標(biāo)怎么使用?
- 速看:歌名最長的網(wǎng)絡(luò)歌曲是什么?歌名最長的中文歌
- fm2015是什么?fm2010戰(zhàn)術(shù)
- 【獨(dú)家】.NET Core是什么?NET Core有哪些用處?
- Trans系列是啥?基于翻譯模型(Trans系列)的知識表示學(xué)習(xí)
- 尼康d800與d810哪個好?尼康d800與d810有哪些區(qū)別?
- 快看點(diǎn)丨Internal問題解決流程 Internal server error 500 問題解決思路
- 【環(huán)球播資訊】12月8日天元股份漲停分析:可降解塑料,包裝印刷概念熱股
- 每日快播:12月8日焦點(diǎn)科技漲停分析:跨境電商,職業(yè)教育,教育概念熱股
- 12月8日千紅制藥漲停分析:肝素,化學(xué)原料藥,抗原自測概念熱股
- 微速訊:轉(zhuǎn)動慣量是什么意思?轉(zhuǎn)動慣量的含義
- 當(dāng)前焦點(diǎn)!歉疚的意思是什么?歉疚一詞詳情介紹
- 西米是什么米?西米露和西米是一樣的嗎?
- 興民智通:公司目前不觸及 st 相關(guān)條款
- 世界頂級昂貴音響有哪些?世界頂級昂貴音響介紹
- 世界今日報(bào)丨如何正確使用系統(tǒng)清理bat程序?清理bat程序的方法技巧
- 天天微動態(tài)丨11月百城二手住宅市場均價穩(wěn)中趨降
- 【世界熱聞】12月8日國光連鎖漲停分析:新零售概念熱股
- 頭條焦點(diǎn):文章目錄是什么?選擇排序怎么設(shè)置?
- 世界微資訊!網(wǎng)絡(luò)的利與弊是什么?網(wǎng)絡(luò)的利弊分析
- 天天快資訊丨吸血鬼狂刀技能搭配詳情 吸血鬼狂刀攻略)
- 世界動態(tài):磁條讀寫器多少錢?磁條讀寫器使用方法介紹
- Modbus通信協(xié)議是什么?Modbus通信協(xié)議詳解
- JSONObject是什么意思?JSONObject的詳情介紹
- 世界關(guān)注:iPad Air(iPad5)什么時候上市?iPad Air(iPad5)的上市時間
- 安徽大專學(xué)校推薦!安徽大專院校排名前十詳細(xì)介紹含分?jǐn)?shù)線
- 每日熱聞!BOW是什么意思?為什么要用BOW模型描述圖像?
- 環(huán)球快資訊:鉛球世界紀(jì)錄2019 女子男子鉛球世界紀(jì)錄分別是多少?
- 熱門看點(diǎn):分析賓得645d怎么樣?賓得公司詳情介紹
- 觀察:梯度(gradient)是什么?梯度的概念是建立在哪方面?
- 焦點(diǎn)播報(bào):程子土包子來的時候歌廳的dj叫什么名字?海燕KTV
- 世界視訊!信號的基本概念是什么?信號的分類有哪些?
- 環(huán)球?qū)崟r:電腦電源額定功率要多少才合適?電腦電源的額定功率
- 全球快消息!4399生死狙擊萬人號賬號2021 4399生死狙擊好號和密碼免費(fèi)永久2021
- 焦點(diǎn)訊息:OneNote是什么?OneNote的功能有哪些?
- 世界今頭條!多普達(dá)手機(jī)都有哪些型號?多普達(dá)最新手機(jī)大全詳情
- 揮著翅膀的女孩英文版叫什么?揮著翅膀的女孩英語版歌詞翻譯
- lol怎么在游戲里回復(fù)好友?lol游戲回復(fù)技巧
- 今日精選:碧海青天的意思是什么?碧海青天一詞出自哪里?
- 世界信息:圖片或手寫簽名轉(zhuǎn)電子簽名怎么轉(zhuǎn)?手寫簽名轉(zhuǎn)電子簽名教程
- 世界要聞:44歲賈靜雯出席活動耳朵被燙傷 修杰楷很是心疼
- 當(dāng)前視點(diǎn)!手機(jī)QQ接收電腦端好友發(fā)送的文件存儲在什么地方?手機(jī)文件儲存路徑
- 天天速讀:語義分割:基于openCV和深度學(xué)習(xí)(二)
- 支付寶網(wǎng)上銀行如何付款?網(wǎng)上銀行付款操作流程
- 天天微頭條丨用VC6.0實(shí)現(xiàn)上位機(jī)串口通信
- 全球速看:寶寶毛衣怎么編織?寶寶毛衣編織圖解
- 魂鎖典獄長二技能怎么用?lol魂鎖典獄長背景以及皮膚介紹
- 基礎(chǔ)版本的基礎(chǔ)版本 直方圖均衡化系列
- 天天觀速訊丨用身份證辦的移動手機(jī)號碼可以跨省改歸屬地嗎?是不可以的
- 攝像頭遠(yuǎn)程監(jiān)控步驟是什么?手機(jī)遠(yuǎn)程監(jiān)控?cái)z像頭設(shè)置方法
- Android中LayoutParams是什么?Android中LayoutParams總結(jié)和用法
- 歌詞里有我真的很不錯是什么兒歌?歌詞我真的很不錯是什么兒歌?
- 全球新資訊:會議panel是什么意思?醫(yī)學(xué)術(shù)語中的panel到底是指什么?
- 當(dāng)前動態(tài):顏料墨水和染料墨水的區(qū)別是什么?顏料墨水和染料墨水簡介