SSH框架總結

*mybatis設置主鍵自增長>>點擊打開鏈接

mybatis傳入多個參數>>點擊打開鏈接

mybatis中同一個mapper中的多個查詢爲什麼是啓用多個sqlSession來處理的?>>點擊打開鏈接

mybatis使用的一點小結:session運行模式及批量提交>>mybatis使用的一點小結:session運行模式及批量提交>>點擊打開鏈接

關於Mybatis的Batch模式性能測試及結論>>點擊打開鏈接

mybatis中批量插入的兩種方式(高效插入)>>點擊打開鏈接

mybatis使用association一對一關聯查詢>>點擊打開鏈接

mybatis使用collection多對多/一對多關聯查詢>>點擊打開鏈接

mybatis配置懶加載

<settings>
	<setting name="mapUnderscoreToCamelCase" value="true"/>
	<!-- 開啓懶加載機制 ,默認值爲true-->
	<setting name="lazyLoadingEnabled" value="true"/>
	<!-- 開啓的話,每個屬性都會直接全部加載出來;禁用的話,只會按需加載出來 -->
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

mybatis註解方式查詢>>點擊打開鏈接

mybatis增強註解>>點擊打開鏈接

MyBatis註解方式>>點擊打開鏈接>>點擊打開鏈接

mybatis動態添加字段需要添加在<select>標籤中開啓預編譯,即statementType=“STATEMENT”,而且,在引用的時候只能使用$,而不能使用#,且jdbcType不能添加(這很重要,我就是因爲前面的步驟都對了,最後卡在這裏一個下午)

mybatis批量更新(1)>>原文內容

mybatis批量更新(2)>>原文內容

 

如果你搜索只是返回一個值,比如說String ,或者是int,那你直接用resultType就行了。
但是你如果是返回一個複雜的對象,就必須定義好這個對象的resultMap的result map。

 

*每個線程都應該有它自己的SqlSession實例。SqlSession的實例不能共享使用,它也是線程不安全的。因此最佳的範圍是請求或方法範圍。絕對不能將SqlSession實例的引用放在一個類的靜態字段或實例字段中。 

*在SqlSession接口調用的insert/update/delete方法中,所有的操作都交給了Executor來操作。SqlSession接口是Mybatis框架暴露的外部接口,而Executor是內部的實現接口。在Executor的實現中,又是調用StatementHandler來處理的。當然,在調用StatementHandler設置參數時候,需要ParameterHandler來設置相應的參數

 

*MyBatis常用對象SqlSessionFactory和SqlSession介紹和運用>>點擊打開鏈接


*Mybatis使用foreach批量插入不同的數據庫插入方法不一致

mysql

oracle

 

*Mybatis關聯查詢之一對多和多對一XML配置詳解>>點擊打開鏈接

 

*Spring中@param和mybatis中@param使用區別>>原文內容

*淺談@RequestMapping @ResponseBody 和 @RequestBody 註解的用法與區別>>原文內容

*@RequestBody 的正確使用辦法>>原文內容

*@Controller和@RestController的區別>>原文內容

 

*@Responsebody與@RequestBody

 

一、預備知識:@RequestMapping
RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上。
用於類上,表示類中的所有響應請求的方法都是以該地址作爲父路徑。


@RequestMapping(value = "/aaa")//類級別,可以沒有
public class myController {
    @RequestMapping(value = "/bbb")//方法級別,必須有
    public String getMyName() {
        return "myReturn";
    }
}


對應的action就是:<form action="aaa/bbb">
返回頁面就是myReturn.jsp


二、@Responsebody與@RequestBody
@Responsebody 表示該方法的返回結果直接寫入 HTTP response body 中
一般在異步獲取數據時使用,在使用 @RequestMapping 後,返回值通常解析爲跳轉路徑,
加上 @Responsebody 後返回結果不會被解析爲跳轉路徑,而是直接寫入 HTTP response body 中。
比如異步獲取json數據,加上 @Responsebody 後,會直接返回json數據。


@RequestBody 將 HTTP 請求正文插入方法中,使用適合的 HttpMessageConverter 將請求體寫入某個對象。
function login() {//頁面異步請求
    var mydata = '{"name":"' + $('#name').val() + '","id":"'
            + $('#id').val() + '","status":"' + $('#status').val() + '"}';
    $.ajax({
        type : 'POST',
        contentType : 'application/json',
        url : "${pageContext.request.contextPath}/person/login",
        processData : false,
        dataType : 'json',
        data : mydata,
        success : function(data) {
            alert("id: " + data.id + "\nname: " + data.name + "\nstatus: "
                    + data.status);
        },
        error : function() {
            alert('出錯了!');
        }
    });
};


@RequestMapping(value = "person/login")
@ResponseBody
public Person login(@RequestBody Person person) {//將請求中的mydata寫入Person對象中
   return person;//不會被解析爲跳轉路徑,而是直接寫入HTTP response body中
}


三、擴展:@PathVariable獲取請求路徑變量


function profile() {
    var url = "${pageContext.request.contextPath}/person/profile/";
    var query = $('#id').val() + '/' + $('#name').val() + '/'
            + $('#status').val();
    url += query;
    $.get(url, function(data) {
        alert("id: " + data.id + "\nname: " + data.name + "\nstatus: "
                + data.status);
    });
}


@RequestMapping(value = "person/profile/{id}/{name}/{status}")
@ResponseBody
public Person porfile(@PathVariable int id,@PathVariable String name,@PathVariable boolean status) {
    return new Person(id, name, status);
}
//@RequestMapping(value = "/person/profile/{id}/{name}/{status}")中的{id}/{name}/{status}與@PathVariable int id, @PathVariable String name,@PathVariable boolean status一一對應,按名匹配。

 

*@responseBody註解說明

1、


  @responseBody註解的作用是將controller的方法返回的對象通過適當的轉換器轉換爲指定的格式之後,寫入到response對象的body區,通常用來返回JSON數據或者是XML


  數據,需要注意的呢,在使用此註解之後不會再走試圖處理器,而是直接將數據寫入到輸入流中,他的效果等同於通過response對象輸出指定格式的數據。


2、  


  @RequestMapping("/login")
  @ResponseBody
  public User login(User user){
    return user;
  }
  User字段:userName pwd
  那麼在前臺接收到的數據爲:'{"userName":"xxx","pwd":"xxx"}'


  效果等同於如下代碼:
  @RequestMapping("/login")
  public void login(User user, HttpServletResponse response){
    response.getWriter.write(JSONObject.fromObject(user).toString());
  }

 

*如果一個列允許 null 值,並且會傳遞值 null 的參數,就必須要指定 JDBC Type。閱讀 PreparedStatement.setNull() 的 JavaDocs 文檔來獲取更多信息。

 

*MyBatis 通過包含的jdbcType類型 
BIT FLOAT CHAR TIMESTAMP OTHER UNDEFINED

TINYINT REAL VARCHAR BINARY BLOB NVARCHAR

SMALLINT DOUBLE LONGVARCHAR VARBINARY CLOB NCHAR

INTEGER NUMERIC DATE LONGVARBINARY BOOLEAN NCLOB

BIGINT DECIMAL TIME NULL CURSOR

 

 

 

*Spring 控制反轉怎麼體現

考慮一下我們之前在程序中如果需要一個對象會怎麼辦?一般是使用new關鍵字,然後後面接一個類,調用構造方法,這樣jvm就會給我們生產一個對象。也就是說程序員需要對象的時候完全是自己new的,比如 Person person = new Person();

可是有了Spring之後,我們的對象完全交給Spring去管理類,我們直接在Spring的配置文件裏配置好Bean,就可以放心大膽的不用管了.比如如下配置代碼:

1

2

3

<bean id="person" class="com.wyq.Spring.Person">

<property name="age" value="12" />

<property name="name" value="Tom"/>

然後接下來,我們要使用這個Bean的時候該怎麼辦呢?只需要這樣一個方法:

1

2

ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");

Person person = ctx.getBean("person",Person.class);

如上圖,這樣的peron實例對象就由Spring管理的,關於它是生命週期,如何生產你完全不用管,用的時候直接調用Spring提供的方法就行。

這就是控制反轉的體現,把對象實例化交給Spring去控制,程序員並不用管。

 

*攔截器和過濾器的區別:攔截器是基於Java的反射機制的,而過濾器是基於函數回調。從靈活性上說攔截器功能更強大些,Filter能做的事情,他都能做,而且可以在請求前,請求後執行,比較靈活,缺點是隻能對controller請求進行攔截,對其他的一些比如直接訪問靜態資源的請求則沒辦法進行攔截處理。Filter主要是針對URL地址做一個編碼的事情、過濾掉沒用的參數、安全校驗(比較泛的,比如登錄不登錄之類),太細的話,還是建議用interceptor。不過還是根據不同情況選擇合適的。

 

*Restrictions.eqOrIsNull("inName",outName)和Restrictions.and(Restrictions.or(Restrictions.isNull("inName"),Restrictions.eq("inName",outName)))的區別:現設定數據庫中參數爲inName,外部參數爲outName,前者的意思是:在where後加上inName=outName(outName不爲空)或者inName IS NULL(outName爲空)的條件;後者的意思是:在where後面加上條件(inName IS NULL OR inName=outName)

 

*Hibernate用原生sql查詢時應該用佔位符替代參數的形式組裝sql,如果直接用字符串拼接會遇到兩個問題:1,sql注入,存在安全隱患,2,如果該sql語句頻繁使用,會導致遊標在短時間內佔用大量遊標且釋放緩慢,最終導致遊標超過閾值。

 

 - mybatis的sql.xml文件中,parameterType和resultType只能有一個,如果參數有多個,必須使用map和list。

 


 - 如果需要在頁面導入很多公共標籤最好在一個頁面中把需要的公共標籤導入,然後其他頁面導入此頁面即可。如果每個頁面都導入那麼多公共標籤會使得頁面看起來臃腫而複雜,破壞可讀性。


 - 在web.xml中,spring用listener監聽,struts2用filter監聽,web.xml啓動的順序是:context-param(設置根目錄參數,負責xml文件的加載)>listener>filter>servlet
 
 - Controller可以不必非得用ModelAndView,也可以用String,如果需要帶參數必須要傳入HttpServletRequestrequest,然後利用request.setAttribute(“result”,result);這種類似的方式插入參數。
 
 - <mvc:annotation-driven/>用於開啓SpringMVC的註解功能。可以簡化原來用兩個類開啓註解功能。
 
 - maven座標命名,構建本地repo需要向package再install


 - controller的兩種方法
第一種是類上添加@RequestMapping(value=”save”) ,對應jsp頁面寫法是save.html
第二種是是在controller類上加上@RequestMapping(value=”indexController”)或者@RequestMapping(”indexController”),類上也加上@RequestMapping(params=”save”)或者@RequestMapping(”save”),注意是params,對應jsp頁面寫法是indexController.html?save
 
 - dao,service接口不用添加註解,但是dao,service的實現類需要@Repository和@Service,@Transactional
service的實現類如果要調用dao方法添加@Resource,而不必繼承dao
 
 - 級聯一般用於一對一和一對多.
 
 - 多對一,一對多關係中
在寫關聯和保存時:被依賴的先寫,依賴的後寫.一般情況下,一是依賴的,多是被依賴的.
在解除關係時:依賴的一方要解除關係,先要將inverse設置爲true.
 
 - HashSet不初始化
privateSet<String> addressSet;
Set<String>set=new HashSet<String>();
set.add(“---”);
Useruser=new User();
user.setAddress(set);
 
HashSet初始化
privateSet<String> addressSet=new HashSet<String>();
Useruser=new User();
user.getAddress().add(“---”);
 
 - HQL語言不能識別select *,一般省略。
 
 - 設置默認的事務隔離級別:
         隔離級別    對應的整數表示
         READ UNCOMMITED 1
         READCOMMITED   2
         REPEATABLEREAD 4
         SERIALIZEABLE   8
在更新或刪除之後一般要調用refresh方法更新數據,否則同一個類中第二次取數據無法得到更新後的數據
 
 - 基本數據類型不能作爲泛型,如果非要用基本數據類型作爲泛型,則只能使用其包裝類。
 
 - 用註釋實現IOC
按名字自動注入byName等價於@Resource/@Autowired@Qualifier(value=” “)
按類型自動注入byType等價於@AutoWired/@Resource(type=?.class)
 
 - 集合關係,最上面,中間都是接口,最下面是實現類.List和Queue有序可重複,Set無序不可重複的.
 
 - 拿到一個項目如何分析
 
 - 兩個類有繼承關係才能使用多態
 
 - 返回對象爲一個對象的時候如果所需的數據類型爲int,可以用intValue()方法,將對象轉化爲相應的數據類型.
 
 - API
Configuration 配置
  configure()
 configure(String resource)
 addResource(String resource) 導入一個指定位置的映射文件(測試時用)
 addClass(Class.class) 導入與指定類同一個包中的以類名爲前綴,後綴爲.hbm.xml的文件
 buildSessionFactory() 導入與指定類同一個包中的以類名爲前綴,後綴爲.hbm.xml文件
 Query
 Critria
SessionFactory Session工廠
 openSession()
 getCurrentSession()
 close()
Session 很重要的一個對象
  操作對象的方法
  save(Object)
 update(Object)
 delete(Object)
  查詢的方法
  createQuery(String)
 createCriteria(Class)
  管理事物有關的方法
  beginTransaction()-->Transaction
 getTransaction() -->Transaction獲取當前Session中關聯的事物對象(例如在try…catch塊裏不必把Transaction定義爲全局變量)
  …
Transaction 事物
  commit()
  rollback()
Query 查詢
  list()查詢一個結果集合
 uniqueResult()查詢一個唯一的結果,如果沒有結果,則返回null,如果有多個結果,就拋異常.

Hibernate主配置文件
 
1.配置的key前面的hibernate.前綴可以有,也可以沒有.如hibernate.dialect或dialect都可以.
2.按作用可分爲三類:
         1)數據庫信息
           <property …>
          方言,JdbcUrl,驅動,用戶名,密碼
         2)導入映射文件
           <mapping …>
         3)其他配置
         <property…>
         show_sql顯示生成的sql語句
         format_sql格式化生成的sql語句
         hbm2ddl.auto自動生成表結構
生成表結構的兩種方式
 - hbm2ddl.auto
2.使用SchemaExport工具類
 
type屬性要麼爲java定義的類型如java.lang.String要麼爲小寫string
當列表與關鍵字衝突時,可以通過column屬性指定一個其他列名或者使用反引號包圍起來(不推薦);指定使用text類型是,最好再指定length,以確定生成的SQL類型是能夠存放指定數量的數據.
 
 - sql不區分大小寫,查詢的是表和表中的字段;hql不區分大小寫,但是類名和屬性名區分大小寫
 
 - 三種實例化bean的方式
1,使用類構造器實例化
<bean id=”orderService”class=”cn.itcast.OrderServiceBean”/>
2,使用靜態工廠方法實例化
<bean id=”personService”class=”cn.itcast.service.OrderFactory” factory-method=”createOder”>
//factory-method的名字是OrderFactory中創建類的名字
<constructor-orgvalue=”student”></constructor-org>
//靜態工廠有參數傳遞,則要設置constructor-org屬性
</bean>
public class OrderFactory{
         publicstatic OrderServiceBean createOrder(){
                   returnnew OrderServiceBean();
         }
}
3,使用實例工廠方法實例化
<bean id=”personServiceFactory”class=” cn.itcast.service.OrderFactory” factory-method=”createOder”/>
public class OrderFactory{
         publicOrderServiceBean createOrder(){
                   returnnew OrderServiceBean();
         }

 

 

}

 

 

*SSH框架概念理解

struts負責客戶請求和頁面的跳轉,把需要處理的內容提交給業務邏輯層(或持久層),獲取業務處理後的結果,再把結果返回給客戶。
hibernate負責和數據庫交互,這個就沒啥說的。
spring 主要是負責各層類之間的依賴關聯。
SSH框架中,Struts 主要做控制操作,就是頁面請求到Struts的Action,在Action中接收請求數據並且處理,然後返回結果再應答給JSP頁面,Struts就是一個很完美的MVC結構的開發框架。
Spring的主要技術是IOC和AOP(依賴注入和麪向切面)IOC技術主要是幫助類初始化和實例化,並且在Spring中每個類都可以有對應的Bean,在配置文件中,然後把Bean逐層注入到其他應用類。AOP技術主要是做事物處理,一般聲明式事物和編程式事物較通用。
Hibernate:就是數據持久化,將數據庫中的表映射爲相應的實體,以便對實體的操作。
以上都是本人開發中自己總結的。
SSH:Struts(表示層)+Spring(業務層)+Hibernate(持久層)

Struts:
Struts是一個表示層框架,主要作用是界面展示,接收請求,分發請求。

在MVC框架中,Struts屬於VC層次,負責界面表現,負責MVC關係的分發。(View:沿用JSP,HTTP,Form,Tag,Resourse ;Controller:ActionServlet,struts-config.xml,Action)

Hibernate:
Hibernate是一個持久層框架,它只負責與關係數據庫的操作。

Spring:
Spring是一個業務層框架,是一個整合的框架,能夠很好地黏合表示層與持久層。

我們知道,傳統的Java Web應用程序是採用JSP+Servlet+Javabean來實現的,這種模式實現了最基本的MVC分層,使的程序結構分爲幾層,有負責前臺展示的 JSP、負責流程邏輯控制的Servlet以及負責數據封裝的Javabean。但是這種結構仍然存在問題:如JSP頁面中需要使用符號嵌入很多的 Java代碼,造成頁面結構混亂,Servlet和Javabean負責了大量的跳轉和運算工作,耦合緊密,程序複用度低等等。


Struts 
爲了解決這些問題,出現了Struts框架,它是一個完美的MVC實現,它有一箇中央控制類(一個 Servlet),針對不同的業務,我們需要一個Action類負責頁面跳轉和後臺邏輯運算,一個或幾個JSP頁面負責數據的輸入和輸出顯示,還有一個 Form類負責傳遞Action和JSP中間的數據。JSP中可以使用Struts框架提供的一組標籤,就像使用HTML標籤一樣簡單,但是可以完成非常複雜的邏輯。從此JSP頁面中不需要出現一行包圍的Java代碼了。 可是所有的運算邏輯都放在Struts的Action裏將使得 Action類複用度低和邏輯混亂,所以通常人們會把整個Web應用程序分爲三層,Struts負責顯示層,它調用業務層完成運算邏輯,業務層再調用持久層完成數據庫的讀寫。 使用JDBC連接來讀寫數據庫,我們最常見的就是打開數據庫連接、使用複雜的SQL語句進行讀寫、關閉連接,獲得的數據又需要轉換或封裝後往外傳,這是一個非常煩瑣的過程。 

Hibernate 
這時出現了 Hibernate框架,它需要你創建一系列的持久化類,每個類的屬性都可以簡單的看做和一張數據庫表的屬性一一對應,當然也可以實現關係數據庫的各種表件關聯的對應。當我們需要相關操作是,不用再關注數據庫表。我們不用再去一行行的查詢數據庫,只需要持久化類就可以完成增刪改查的功能。使我們的軟件開發真正面向對象,而不是面向混亂的代碼。我的感受是,使用Hibernate比JDBC方式減少了80%的編程量。 現在我們有三個層了,可是每層之間的調用是怎樣的呢?比如顯示層的Struts需要調用一個業務類,就需要new一個業務類出來,然後使用;業務層需要調用持久層的類,也需要new一個持久層類出來用。通過這種new的方式互相調用就是軟件開發中最糟糕設計的體現。簡單的說,就是調用者依賴被調用者,它們之間形成了強耦合,如果我想在其他地方複用某個類,則這個類依賴的其他類也需要包含。程序就變得很混亂,每個類互相依賴互相調用,複用度極低。如果一個類做了修改,則依賴它的很多類都會受到牽連。 爲此,出現Spring框架。 

Spring
Spring的作用就是完全解耦類之間的依賴關係,一個類如果要依賴什麼,那就是一個接口。至於如何實現這個接口,這都不重要了。只要拿到一個實現了這個接口的類,就可以輕鬆的通過xml配置文件把實現類注射到調用接口的那個類裏。所有類之間的這種依賴關係就完全通過配置文件的方式替代了。所以 Spring框架最核心的就是所謂的依賴注射和控制反轉。 現在的結構是,Struts負責顯示層,Hibernate負責持久層,Spring負責中間的業務層,這個結構是目前國內最流行的Java Web應用程序架構了。另外,由於Spring使用的依賴注射以及AOP(面向方面編程),所以它的這種內部模式非常優秀,以至於Spring自己也實現了一個使用依賴注射的MVC框架,叫做Spring MVC,同時爲了很好的處理事物,Spring集成了Hibernate,使事物管理從Hibernate的持久層提升到了業務層,使用更加方便和強大。 Struts框架是2000年就開始起步了,到目前已經發展了5年,技術相當成熟,目前全球Java開發中Struts框架是顯示層技術中當之無愧的王者。它擁有大量的用戶羣和很好的開發團隊。這也是國內大部分Java軟件公司對新進員工的基本要求。 其他 Java這個名詞似乎註定和開源緊密聯繫在一起了,在Java界,每天都有大量的開源技術出現,由於是開放源代碼的,技術中存在的問題和不足很快就會被人發現,開源軟件提供者會很快的修正或擴展這些技術,因此版本更新很快,幾個星期或者幾天就有一個新版本出來。 當我們在技術線路中選擇了Java,也就選擇了你必須持續學習,經常關注最新的技術,瞭解它們,看是否適合你的需要,然後學習使用它們。
IOC的思想是:Spring容器來實現這些相互依賴對象的創建、協調工作。對象只需要關係業務邏輯本身就可以了。從這方面來說,對象如何得到他的協作對象的責任被反轉了(IOC、DI)。那麼IoC是如何做的呢?有點像通過婚介找女朋友,在我和女朋友之間引入了一個第三者:婚姻介紹所。婚介管理了很多男男女女的資料,我可以向婚介提出一個列表,告訴它我想找個什麼樣的女朋友,比如長得像李嘉欣,身材像林熙雷,唱歌像周杰倫,速度像卡洛斯,技術像齊達內之類的,然後婚介就會按照我們的要求,提供一個mm,我們只需要去和她談戀愛、結婚就行了。簡單明瞭,如果婚介給我們的人選不符合要求,我們就會拋出異常。整個過程不再由我自己控制,而是有婚介這樣一個類似容器的機構來控制。Spring所倡導的開發方式就是如此,所有的類都會在spring容器中登記,告訴spring你是個什麼東西,你需要什麼東西,然後spring會在系統運行到適當的時候,把你要的東西主動給你,同時也把你交給其他需要你的東西。所有的類的創建、銷燬都由 spring來控制,也就是說控制對象生存週期的不再是引用它的對象,而是spring。對於某個具體的對象而言,以前是它控制其他對象,現在是所有對象都被spring控制,所以這叫控制反轉。
AOP的概念大家應該都知道吧,Aspect Oriented Programming的縮寫,意爲:面向切面編程(也叫面向方面),可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。
我們這樣理解,AOP就是一個監控者,它在外面看着我們程序運行,同時也可以定一些規則,決定程序運行不運行,也可以在一個方法運行前進行處理,也可以在一個方法後進行一些邏輯處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章