1. 程式人生 > 其它 >Elasticsearch詳解(二)

Elasticsearch詳解(二)

MyBatis 框架

第一章 框架的概述

1.三層架構

mvc:web開發中,使用mvc架構模式。 m:資料, v:檢視, c:控制器。

​ c控制器: 接收請求,呼叫service物件,顯示請求的處理結果。 當前使用servlet作為控制器

​ v檢視: 現在使用jsp, html,css,js。 顯示請求的處理結果,把m中資料顯示出來。

​ m資料: 來自資料庫mysql, 來自檔案,來自網路

mvc作用:

​ 1)實現解耦合。

​ 2)讓mvc 各負其職。

​ 3)使的系統擴充套件更好。更容易維護。

三層架構:

1.介面層(檢視層):接收使用者的請求,呼叫service, 顯示請求的處理結果的。 包含了jsp,html,servlet等物件。 對應的包controller,

2.業務邏輯層:處理業務邏輯, 使用演算法處理資料的。 把資料返回給介面層。 對應的是service包,和包中的很多的XXXService類。 例如: StudentService , OrderService, ShopService

3.持久層(資料庫訪問層):訪問資料庫,或者讀取檔案,訪問網路。獲取資料。 對應的包是dao。 dao包中很多的StudentDao, OrderDao, ShopDao等等。

2. 三層架構請求的處理流程

使用者發起請求---->介面層----->業務邏輯層---->持久層---->資料庫(mysql)

3. 為什麼要使用三層?

1,結構清晰、耦合度低, 各層分工明確
2,可維護性高,可擴充套件性高
3,有利於標準化
4,開發人員可以只關注整個結構中的其中某一層的功能實現
5,有利於各層邏輯的複用

4. 三層架構模式和框架

每一層對應著一個框架

1)介面層---SpringMVC框架

2)業務層---Spring框架

3)持久層---MyBatis框架

5 .框架

  1. 什麼是框架(framework)

框架:就是一個軟體, 完成了部分的功能。 軟體中的類和類之間的方法呼叫都已經規定好了。 通過這些可以完成某些功能。 框架看做是模版。

框架是可以升級的,改造的。 框架是安全的。

框架是對某一個方面有用的,不是全能的。

6. 框架解決的問題

1)框架能實現技術的整合。

2)提供開發的效率。 降低難度。

7. jdbc訪問資料庫的優缺點

優點:

  1. 直觀,好理解

缺點:

  1. 建立很多物件 Connection ,Statement, ResultSet
  2. 註冊驅動
  3. 執行sql語句
  4. 把ResultSet轉為 Student , List集合。
  5. 關閉資源
  6. sql語句和業務邏輯程式碼混在一起

8 MyBatis框架

什麼 mybatis: 是一個持久層框架, 原名是ibatis, 2013改名為 MyBatis. MyBatis可以操作資料庫,對資料執行增刪改查。 看做是高階的jdbc。 解決jdbc的缺點。

mybatis能做什麼?

1) 註冊驅動 。

2) 建立jdbc中使用的Connection, Statement,ResultSet

3)   執行sql語句, 得到ResultSet

4)   處理ResultSet, 把記錄集中的資料轉為java物件,  同時還能把java物件放入到List集合。

5)關閉資源

6)實現sql語句和java程式碼的解耦合。

mybatis的文件: https://mybatis.org/mybatis-3/zh/index.html

第二章 MyBatis入門

2.1 第一個例子

實現步驟:

0.建立student表(id,name,email,age)

1.新建maven專案

2.修改pom.xml

1)加入依賴 mybatis依賴, mysql驅動, junit

2)在加入資源外掛

3.建立實體類Student。定義屬性, 屬性名和列名保持一致

4.建立Dao介面, 定義操作資料庫的方法。

5.建立xml檔案(mapper檔案), 寫sql語句。

mybatis框架推薦是把sql語句和java程式碼分開

mapper檔案:定義和dao介面在同一目錄, 一個表一個mapper檔案。

6.建立mybatis的主配置檔案(xml檔案):有一個, 放在resources目錄下

1)定義建立連線例項的資料來源(DataSource)物件

  2)   指定其他mapper檔案的位置

7.建立測試的內容。

使用main方法,測試mybatis訪問資料庫

也可以使用junit 訪問資料庫

2.2 概念

1.自動提交:當你的 sql語句執行完畢後, 提交事務。 資料庫更新操作之間儲存到資料

2.手動(手工)提交事務:在你需要提交事務的位置, 執行方法,提交事務或者回顧事務。

2.3 MyBatis的一些重要物件

1) Resources : mybatis框架中的物件, 一個作用讀取 主配置資訊。

InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");

2)SqlSessionFactoryBuilder:負責建立SqlSessionFactory物件

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

3)SqlSessionFactory: 重要物件

SqlSessionFactory是重量級物件:建立此物件需要使用更多的資源和時間。 在專案中有一個就可以了。

SqlSessionFactory介面:作用是SqlSession的工廠, 就是建立SqlSession物件。

DefaultSqlSessionFactory實現類

public class DefaultSqlSessionFactory implements SqlSessionFactory { } 

SqlSessionFactory介面中的方法

openSession(): 獲取一個預設的SqlSession物件, 預設是需要手工提交事務的。

openSession(boolean): boolean引數表示是否自動提交事務。

​ true: 建立一個自動提交事務的SqlSession

​ false: 等同於沒有引數的openSession

  1. SqlSession物件

SqlSession物件是通過SqlSessionFactory獲取的。 SqlSession本身是介面

DefaultSqlSession: 實現類

public class DefaultSqlSession implements SqlSession { }

SqlSession作用是提供了大量的執行sql語句的方法:

selectOne:執行sql語句,最多得到一行記錄,多餘1行是錯誤。
selectList:執行sql語句,返回多行資料
selectMap:執行sql語句的,得到一個Map結果
insert:執行insert語句
update:執行update語句
delete:執行delete語句
commit:提交事務
rollback:回顧事務

注意SqlSession物件不是執行緒安全的, 使用的步驟:

①:在方法的內部,執行sql語句之前,先獲取SqlSession物件

②:呼叫SqlSession的方法,執行sql語句

③:關閉SqlSession物件,執行SqlSession.close()

2.4 使用工具類和模版

1)建立模版,mapper檔案模版和mybatis主配置檔案模版

建立模版的步驟:

建立模版檔案:

建立檔案選擇使用的模版:

第三章 MyBatis的Dao代理

3.1 dao代理

3.1.1 mybatis提供代理:

mybatis建立Dao介面的實現類物件, 完成對sql語句的執行。 mybatis建立一個物件代替你的 dao實現類功能。

3.1.2 使用mybatis代理要求

1)mapper檔案中的namespace 一定dao介面的全限定名稱

2)mapper檔案中 標籤的id是dao介面方法名稱

3.1.3 mybatis代理實現方式

使用SqlSession物件的方法 getMapper(dao.class)

例如: 現在有 StudentDao介面。

SqlSession session  = MyBatisUtils.getSqlSession();
StudentDao dao  = session.getMapper(StudentDao.class);
Student student = dao.selectById(1001);


//上面程式碼中
StudentDao dao  = session.getMapper(StudentDao.class);
等同於
StudentDao dao  = new StudentDaoImpl();

3.2 理解引數

理解引數是: 通過java程式把資料傳入到mapper檔案中的sql語句。 引數主要是指dao介面方法的形參

3.2.1 parameterType

parameterType:表示引數的型別, 指定dao方法的形引數據型別。 這個形參的資料型別是給mybatis使用。 mybatis在給sql語句的引數賦值時使用。 PreparedStatement.setXXX( 位置, 值)

第一個用法: java型別的全限定型別名稱   parameterType="java.lang.Integer"
第二個用法: mybatis定義的java型別的別名  parameterType="int"

parameterType:mybatis通過反射機制可以獲取 dao介面方法引數的型別, 可以不寫

<select id="selectById"  parameterType="integer"
                 resultType="com.bjpowernode.domain.Student">
   select id,name,email,age from student where id=#{studentId}
</select>

3.2.2 dao介面方法是一個簡單型別的引數

//dao介面的方法形參是一個簡單型別的
//簡單型別: java基本資料型別和String
Student selectByEmail(String email);
<!--
   dao介面是一個簡單型別的引數
   mapper檔案,獲取這個引數值,使用#{任意字元}
-->
<select id="selectByEmail" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where email=#{studentEmail}
</select>

3.2.3 dao介面方法有多個簡單型別的引數

@Param: 命名引數, 在方法的形參前面使用的, 定義引數名。 這個名稱可以用在mapper檔案中。

dao介面,方法的定義

/*
  多個簡單型別的引數
  使用@Param命名引數, 註解是mybatis提供的
  位置:在形參定義的前面
  屬性:value 自定義的引數名稱
 */
List<Student> selectByNameOrAge(@Param("myname") String name,
                                @Param("myage") Integer age);

mapper檔案

<!--
   多個簡單型別的引數.
   當使用了@Param命名後,例如@Param("myname").
   在mapper中,使用#{命名的引數}, 例如 #{myname}
-->
<select id="selectByNameOrAge" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>

3.2.4 dao介面方法使用一個物件作為引數

方法的形參是一個java物件。這個java物件表示多個引數。使用物件的屬性值作為引數使用

java物件

public class Student {
    private Integer id;
    private String name;
    private String email;
    private Integer age;
    //set|get方法
}

public class QueryParam {
    private Object p1;
    private Object p2;
    //set|get方法
}

dao介面中的方法定義

/*
 * 一個java物件作為引數( 物件由屬性, 每個屬性有set,get方法)
 */
List<Student> selectByObject(Student student);

List<Student> selectByQueryParam(QueryParam param);

mapper檔案

<!--
   一個java物件作為方法的引數,使用物件的屬性作為引數值使用
   簡單的語法: #{屬性名} , mybatis呼叫此屬性的getXXX()方法獲取屬性值
-->
<select id="selectByObject" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{name} or age=#{age}
</select>

<select id="selectByQueryParam" resultType="com.bjpowernode.domain.Student">
     select id,name,email,age from student where name=#{p1} or age=#{p2}
</select>

<!--負責的語法格式: #{屬性名,javaType=java型別的全限定名稱,jdbcType=mybatis中定義列的資料型別}-->
<select id="selectByObject" resultType="com.bjpowernode.domain.Student">
        select id,name,email,age from student where
        name=#{name,javaType=java.lang.String,jdbcType=VARCHAR}
        or
        age=#{age,javaType=java.lang.Integer,jdbcType=INTEGER}
</select>

3.2.5 dao介面中多個簡單型別的引數,使用位置

引數位置: dao介面中方法的形參列表,從左往右,引數位置是 0 , 1, 2......

語法格式:#{arg0} ,#{arg1}

dao介面的方法

/*
   使用位置,獲取引數
 */
List<Student> selectByPosition(String name,Integer age);
<!--
   mybatis版本是 3.5.1
   使用位置獲取引數值, dao介面方法是多個簡單型別的引數
   語法: #{arg0}, #{arg1}....
-->
<select id="selectByPosition" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{arg0} or age=#{arg1}
</select>

3.2.6 dao介面引數是一個Map

map作為dao介面的引數, 使用 key 獲取引數值,mapper檔案中,語法格式 #{key}

/*
   使用Map作為引數
 */
List<Student> selectStudentByMap(Map<String,Object> map);

mapper檔案

<!--
   使用Map傳遞引數,
   在mapper檔案中,獲取map的值,是通過key獲取的,語法:#{key}
-->
<select id="selectStudentByMap" resultType="com.bjpowernode.domain.Student">
     select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>

測試,呼叫方法的位置

@Test
public void testSelectByMap(){
    SqlSession sqlSession = MyBatisUtil.getSqlSession();
    StudentDao dao  = sqlSession.getMapper(StudentDao.class);

    //使用map傳遞引數
    Map<String,Object> data = new HashMap<>();
    data.put("myname", "李思思");
    data.put("myage", 20);
    List<Student> students = dao.selectStudentByMap(data);

    students.forEach( stu-> System.out.println("stu="+stu));
    sqlSession.close();

}

3.3 #和$的區別

3.3.1 # 佔位符

語法: #{字元}

mybatis處理#{} 使用jdbc物件是 PrepareStatment物件

<select id="selectById"  parameterType="integer"
             resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where id=#{studentId}
</select>

mybatis出建立PrepareStatement物件,執行sql語句
String sql=" select id,name,email,age from student where id=?";
PrepareStatement pst = conn.prepareStatement(sql);
pst.setInt(1,1001);  //傳遞引數
ResultSet rs  = pst.executeQuery(); //執行sql語句


{}特點:

1)使用的PrepareStatement物件,執行sql語句,效率高。

2)使用的PrepareStatement物件,能避免sql語句, sql語句執行更安全。

3) #{} 常常作為 列值使用的, 位於等號的右側, #{}位置的值和資料型別有關的。

3.3.2 $ 佔位符

語法 : ${字元}

mybatis執行${}佔位符的sql語句

<select id="selectById"  parameterType="integer"
             resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where id=${studentId}
</select>	

${} 表示字串連線, 把sql語句的其他內容和 ${}內容使用 字串(+) 連線的方式連在一起
String sql="select id,name,email,age from student where id=" + "1001";

mybatis建立Statement物件, 執行sql語句。
Statement stmt  = conn.createStatement(sql);
ResultSet rs  = stmt.executeQuery();

${} 的特點

1)使用Statement物件,執行sql語句,效率低

2)${}佔位符的值,使用的字串連線方式, 有sql注入的風險。 有程式碼安全的問題

  1. ${} 資料是原樣使用的, 不會區分資料型別。

4)${} 常用作 表名或者列名, 在能保證資料安全的情況下使用 ${}

3.4 封裝MyBatis輸出結果

封裝輸出結果: MyBatis執行sql語句,得到ResultSet, 轉為java物件。

講兩個 resultType, resultMap

3.4.1 resultType

resultType屬性: 在執行select時使用, 作為