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 .框架
- 什麼是框架(framework)
框架:就是一個軟體, 完成了部分的功能。 軟體中的類和類之間的方法呼叫都已經規定好了。 通過這些可以完成某些功能。 框架看做是模版。
框架是可以升級的,改造的。 框架是安全的。
框架是對某一個方面有用的,不是全能的。
6. 框架解決的問題
1)框架能實現技術的整合。
2)提供開發的效率。 降低難度。
7. jdbc訪問資料庫的優缺點
優點:
- 直觀,好理解
缺點:
- 建立很多物件 Connection ,Statement, ResultSet
- 註冊驅動
- 執行sql語句
- 把ResultSet轉為 Student , List集合。
- 關閉資源
- 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
- 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注入的風險。 有程式碼安全的問題
- ${} 資料是原樣使用的, 不會區分資料型別。
4)${} 常用作 表名或者列名, 在能保證資料安全的情況下使用 ${}
3.4 封裝MyBatis輸出結果
封裝輸出結果: MyBatis執行sql語句,得到ResultSet, 轉為java物件。
講兩個 resultType, resultMap
3.4.1 resultType
resultType屬性: 在執行select時使用, 作為