vue中activated的用法
Mybatis
官網:https://mybatis.org/mybatis-3/
1. 簡介
MyBatis 是一款優秀的持久層框架,它支援自定義 SQL、儲存過程以及高階對映。MyBatis 免除了幾乎所有的 JDBC 程式碼以及設定引數和獲取結果集的工作。MyBatis 可以通過簡單的 XML 或註解來配置和對映原始型別、介面和 Java POJO(Plain Old Java Objects,普通老式 Java 物件)為資料庫中的記錄。
依賴jar包
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency>
2. 持久化
持久化就是將程式的資料在持久狀態和瞬時狀態下的轉換
對應生活的例子
罐頭,冷藏
3. 為什麼使用Mybatis
- 方便
- 簡化jdbc程式碼
- 幫助程式設計師將資料存到資料庫中
- 簡單易學:本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只要兩個jar檔案+配置幾個sql對映檔案易於學習,易於使用,通過文件和原始碼,可以比較完全的掌握它的設計思路和實現。
- 靈活:mybatis不會對應用程式或者資料庫的現有設計強加任何影響。 sql寫在xml裡,便於統一管理和優化。通過sql語句可以滿足操作資料庫的所有需求。
- 解除sql與程式程式碼的耦合:通過提供DAO層,將業務邏輯和資料訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和程式碼的分離,提高了可維護性。
- 提供對映標籤,支援物件與資料庫的orm欄位關係對映
- 提供物件關係對映標籤,支援物件關係組建維護
- 提供xml標籤,支援編寫動態sq
4. 第一個Mybatis程式
配置mybatis配置檔案
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> </configuration>
編寫工具類
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static{
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//獲取openSession
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
編寫測試環境
dao UserMapper
pojo User
編寫 UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.immortal.dao.UserMapper">
<!-- 查詢語句-->
<select id="getUserList" resultType="com.immortal.pojo.User">
select * from mybatis.user
</select>
</mapper>
注意點
org.apache.ibatis.binding.BindingException: Type interface com.immortal.dao.UserMapper is not known to the MapperRegistry
沒有註冊到mapper的註冊中心裡面區 ,就是mybatis的核心配置檔案
解決:
重新測試
初始化異常 失敗
Cause: java.io.IOException: Could not find resource com.immortal.dao.UserMapper.xml
沒有找到這個UserMapper.xml maven的靜態資源過濾問題
解決:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
junit 測試
public class Test {
@org.junit.Test
public void TestSelect(){
//獲得SqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
//獲取Mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//呼叫介面的方法
List<User> userList = userMapper.getUserList();
//遍歷
for (User user : userList) {
System.out.println(user);
}
//關閉連線
sqlSession.close();
}
5. CRUD
mamespace中的包名要和介面名字一致
Select
- id 就是對應的方法名
- resultType sql語句執行的返回值
- paramterType 引數的型別
<select id="getUserList" resultType="com.immortal.pojo.User">
select * from mybatis.user
</select>
Insert
<insert id="addUser" parameterType="com.immortal.pojo.User">
insert into mybatis.user (`id`,`name`,`pwd`) values(#{id},#{name},#{pwd})
</insert>
Update
<update id="updateUser" parameterType="com.immortal.pojo.User">
update mybatis.user set `name`=#{name},`pwd`=#{pwd} where `id`=#{id}
</update>
Delete
<delete id="deleteUser">
delete from mybatis.user where `id`=#{id}
</delete>
6. 萬能的Map
假設,我們的實體類或者資料庫中的表字段或者引數過多,我們應當考慮使用map
Map傳遞引數,直接在sql中取出key即可
7. 模糊查詢
java程式碼執行的時候,傳遞萬用字元 %李%
@org.junit.Test
public void getUserLike(){
//獲得SqlSession
SqlSession sqlSession = MybatisUtils.getSqlSession();
//獲取Mapper
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//呼叫介面的方法
List<User> userList = userMapper.getUserLike("%杜%");
//遍歷
for (User user : userList) {
System.out.println(user);
}
//關閉連線
sqlSession.close();
}
<select id="getUserLike" resultType="com.immortal.pojo.User">
select * from mybatis.user where `name` like #{value}
</select>
8. 配置解析
MyBatis 的配置檔案包含了會深深影響 MyBatis 行為的設定和屬性資訊。 配置文件的頂層結構如下:
- configuration(配置)
- properties(屬性)
- settings(設定)
- typeAliases(類型別名)
- typeHandlers(型別處理器)
- objectFactory(物件工廠)
- plugins(外掛)
- environments(環境配置)
- environment(環境變數)
- transactionManager(事務管理器)
- dataSource(資料來源)
- environment(環境變數)
- databaseIdProvider(資料庫廠商標識)
- mappers(對映器)
環境配置(environments)
MyBatis 可以配置成適應多種環境,這種機制有助於將 SQL 對映應用於多種資料庫之中, 現實情況下有多種理由需要這麼做。例如,開發、測試和生產環境需要有不同的配置;或者想在具有相同 Schema 的多個生產資料庫中使用相同的 SQL 對映。還有許多類似的使用場景。
不過要記住:儘管可以配置多個環境,但每個 SqlSessionFactory 例項只能選擇一種環境。
mybatis的預設事務管理器是jdbc它支援事務提交回滾操作 連線池是POOLED的
還有一種是MANAGED – 這個配置幾乎沒做什麼。它從不提交或回滾一個連線,而是讓容器來管理事務的整個生命週期(比如 JEE 應用伺服器的上下文)。 預設情況下它會關閉連線。然而一些容器並不希望連線被關閉,因此需要將 closeConnection 屬性設定為 false 來阻止預設的關閉行為。例如:
官方文件 寫的很清楚
屬性(properties)
db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai
username=root
password=123456
mybatis-config
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 匯入外部配置檔案-->
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/immortal/dao/UserMapper.xml"/>
</mappers>
</configuration>
優先使用外部配置檔案
類型別名(typeAliases)
類型別名可為 Java 型別設定一個縮寫名字。 它僅用於 XML 配置,意在降低冗餘的全限定類名書寫。例如:
<typeAliases>
<typeAlias type="com.immortal.pojo.User" alias="User"/>
</typeAliases>
在其他地方可以使用User這個別名代表com.immortal.pojo.User
<typeAliases>
<package name="com.immortal.pojo"/>
</typeAliases>
每一個在包 domain.blog
中的 Java Bean,在沒有註解的情況下,會使用 Bean 的首字母小寫的非限定類名來作為它的別名。 比如 domain.blog.Author
的別名為 author
;若有註解,則別名為其註解值。見下面的例子:
@Alias("author")
public class Author {
...
}
下面是一些為常見的 Java 型別內建的類型別名。它們都是不區分大小寫的,注意,為了應對原始型別的命名重複,採取了特殊的命名風格。
別名 | 對映的型別 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
設定(settings)
這是 MyBatis 中極為重要的調整設定,它們會改變 MyBatis 的執行時行為。 下表描述了設定中各項設定的含義、預設值等。
對映器(mappers)
既然 MyBatis 的行為已經由上述元素配置完了,我們現在就要來定義 SQL 對映語句了。 但首先,我們需要告訴 MyBatis 到哪裡去找到這些語句。 在自動查詢資源方面,Java 並沒有提供一個很好的解決方案,所以最好的辦法是直接告訴 MyBatis 到哪裡去找對映檔案。 你可以使用相對於類路徑的資源引用,或完全限定資源定位符(包括 file:///
形式的 URL),或類名和包名等。例如:
<!-- 使用相對於類路徑的資源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定資源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- 使用對映器介面實現類的完全限定類名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 將包內的對映器介面實現全部註冊為對映器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
這些配置會告訴 MyBatis 去哪裡找對映檔案,剩下的細節就應該是每個 SQL 對映檔案了,也就是接下來我們要討論的。
mapperRegister若如果沒有註冊的話,就區mybatis-config.xml配置
生命週期於作用域
生命週期於作用域是至關重要的,因為錯誤使用會導致嚴重的併發問題
SqlSessionFactoryBuilder
- 建造者模式
- 一旦建立了SqlSessionFactory,就不再需要了
- 區域性變數
SqlSessionFactory
- 工廠模式
- 可以想象為資料庫連線池
- SqlSessionFactory 一旦被建立就應該在應用的執行期間一直存在,沒有任何理由丟棄它或重新建立另一個例項。 使用 SqlSessionFactory 的最佳實踐是在應用執行期間不要重複建立多次,多次重建 SqlSessionFactory 被視為一種程式碼“壞習慣”。因此 SqlSessionFactory 的最佳作用域是application作用域。 有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式。
SqlSession
-
連線到連線池的一個請求
-
每個執行緒都應該有它自己的 SqlSession 例項。SqlSession 的例項不是執行緒安全的,因此是不能被共享的,所以它的最佳的作用域是請求或方法作用域。
-
連線完畢後需要趕緊關閉,否則會佔用資源!
9. 解決屬性名和欄位不一致
如果資料庫的欄位名與pojo的屬性沒有不一致的話,無法進行賦值到屬性上,導致空值
ResultMap
可以通過 ResultMap這個標籤將資料庫的欄位名與JavaBean的屬性名進行關聯進行賦值
UserMapper..xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.immortal.dao.UserMapper">
<resultMap id="userMap" type="com.immortal.pojo.User">
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserById" resultMap="userMap">
select * from mybatis.user where id = #{id}
</select>
</mapper>
賦值到屬性上面了
10. 日誌
日誌工廠
-
STDOUT_LOGGING簡單,加上就可以用
-
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
控制檯輸出
LOG4J
- Log4j是Apache的一個開源專案,通過使用Log4j,我們可以控制日誌資訊輸送的目的地是控制檯、檔案、GUI元件,甚至是套介面伺服器、NT的事件記錄器、UNIX Syslog守護程序等;
- 我們也可以控制每一條日誌的輸出格式
- 通過定義每一條日誌資訊的級別
- 最令人感興趣的就是,這些可以通過一個配置檔案來靈活地進行配置,而不需要修改應用的程式碼。
- 匯入jar包
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
編寫配置檔案
將mybatis的日誌實現換成log4j的 就可以了
11. 分頁
為什麼要分頁?
- 減少資料的處理量
語法
select * from user limit startIndex,pageSize;
select * from user limit 0,5;
基於Map實現,不正規,爽
<select id="getListUserLimit" parameterType="map" resultMap="userMap">
select * from mybatis.user limit #{startIndex},#{pageSize}
</select>
RowBounds
<select id="getListUserRowBounds" resultMap="userMap">
select * from mybatis.user
</select>
@org.junit.Test
public void getListUserRowBounds(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
RowBounds rowBounds = new RowBounds(0,5);
List<User> userList = sqlSession.selectList("com.immortal.dao.UserMapper.getListUserRowBounds", null, rowBounds);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
分頁外掛
按照文件一步一步操作就行 easy
12. 使用註解開發
關於介面的理解 解耦
介面更深的理解就是定義與實現的分離
介面本事反應了系統設計人員對系統的抽象理解
介面有兩類
- 第一種是對一個個體的抽象,它對應一個抽象體
- 第二種是對一個個體莫一方面的抽象,既成為一個抽象面
官網上很具體了 !!! 複雜的sql不建議使用
13. Mybatis執行流程
- Resources物件獲取載入全域性配置檔案
- 例項化SqlSessionFactoryBuilder構造器
- 解析配置檔案流XMLConfigBuilder
- 返回Configuration所有的配置資訊
- sqlSessionFactory例項化
- 事務管理器transaction
- 建立執行器executor
- 建立sqlSession
- 實現crud
- 是否執行成功 失敗回滾
14. 多對一,一對多
多個學生關聯一個老師 【多對一】
對於老師而言就是 【一對多】
如果java實體類中包含其他java類 需要進行結果集對映
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.immortal.dao.StudentMapper">
<select id="getStudentList" resultMap="StudentTeacher">
select * from mybatis.student;
</select>
<!--這裡將結果集通過association 進行對映 用子查詢將結果對映到屬性上-->
<resultMap id="StudentTeacher" type="com.immortal.pojo.Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<association property="teacher" column="tid" javaType="com.immortal.pojo.Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="com.immortal.pojo.Teacher">
select * from mybatis.teacher where id = #{tid}
</select>
</mapper>
還可以向將資料查詢出來 在將資料對映到具體的屬性上
<select id="getStudentList" resultMap="StudentTeacher">
select student.id as sid,student.name as sname,teacher.name as tname,teacher.id as tid
from mybatis.student,mybatis.teacher
where student.tid = teacher.id
</select>
<!--對映查詢的資料-->
<resultMap id="StudentTeacher" type="com.immortal.pojo.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="com.immortal.pojo.Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>
其實我們在解決我問題就是 javaBean欄位與資料庫欄位無法對映的問題
提供對映關係
15. 動態SQL
根據不同的條件生成不同的sql
動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦,例如拼接時要確保不能忘記新增必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。
使用動態 SQL 並非一件易事,但藉助可用於任何 SQL 對映語句中的強大的動態 SQL 語言,MyBatis 顯著地提升了這一特性的易用性。
如果你之前用過 JSTL 或任何基於類 XML 語言的文字處理器,你對動態 SQL 元素可能會感覺似曾相識。在 MyBatis 之前的版本中,需要花時間瞭解大量的元素。藉助功能強大的基於 OGNL 的表示式,MyBatis 3 替換了之前的大部分元素,大大精簡了元素種類,現在要學習的元素種類比原來的一半還要少。
-
if
-
<select id="selectBlogIF" resultType="com.immortal.pojo.Blog" parameterType="map"> select * from Blog <where> <if test="title != null"> title = #{title} </if> <if test="author != null"> and author = #{author} </if> </where> </select>
-
-
choose (when, otherwise)
-
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select>
-
-
trim (where, set)
-
foreach
-
動態 SQL 的另一個常見使用場景是對集合進行遍歷(尤其是在構建 IN 條件語句的時候)。比如:
-
<select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select>
-
報錯
org.apache.ibatis.binding.BindingException: Mapper method 'com.immortal.dao.BlogMapper.addBlog attempted to return null from a method with a primitive return type (int).
這裡腦子問題將select 標籤寫錯了 導致這個問題 將改成insert標籤就可以了
https://mybatis.org/mybatis-3/zh/dynamic-sql.html 官網 上面寫的很好
SQL片段
我們有的時候可能會將一些公共的部分抽取出來
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<select id="selectBlogIF" resultType="com.immortal.pojo.Blog" parameterType="map">
select * from Blog
<where>
<include refid="if-title-author"/>
</where>
</select>
16. 快取
- 什麼是快取?
- 記憶體中儲存的臨時資料,
- 將使用者經常查詢的資料放在快取中,使用者區查詢資料就不用次磁碟上查詢,從快取上查詢會大大提高效率,提高效能
- 為什麼使用快取
- 減少與資料庫的互動,減小系統的開銷,提高系統的效率
- 什麼資料能使用快取
- 經常查詢,不變的資料
Mybatis快取
MyBatis 內建了一個強大的事務性查詢快取機制,它可以非常方便地配置和定製。 為了使它更加強大而且易於配置
- Mybatis系統預設定義兩種快取,一級快取,二級快取
- 預設情況下,只有一級快取(sqlSession基本的快取,也稱為本地快取)
- 二級快取需要手動配置和開啟,它是基於namespace級別的
- 為了提高擴充套件性,Mybatis定義了快取介面Cache,我們可以通過實現介面,自定義二級快取
- 可用的清除策略有:
LRU
– 最近最少使用:移除最長時間不被使用的物件。FIFO
– 先進先出:按物件進入快取的順序來移除它們。SOFT
– 軟引用:基於垃圾回收器狀態和軟引用規則移除物件。WEAK
– 弱引用:更積極地基於垃圾收集器狀態和弱引用規則移除物件。
一級快取
這個簡單語句的效果如下:
- 對映語句檔案中的所有 select 語句的結果將會被快取。
- 對映語句檔案中的所有 insert、update 和 delete 語句會重新整理快取。
- 快取會使用最近最少使用演算法(LRU, Least Recently Used)演算法來清除不需要的快取。
- 快取不會定時進行重新整理(也就是說,沒有重新整理間隔)。
開啟日誌
測試在一個session中查詢兩次記錄
@org.junit.Test
public void selectBlogIF(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("author","james");
List<Blog> blogs = mapper.selectBlogIF(map);
List<Blog> blogs1 = mapper.selectBlogIF(map);
System.out.println(blogs == blogs1);
sqlSession.close();
檢視日誌輸出
快取失效的情況:
- 增刪改 可能會改變原來的資料,所有必定會重新整理快取!
- 查詢不同的東西
- 查詢不同的mapper.xml
- 手動清除
二級快取
二級快取也稱全域性快取,一級的作用域太低了
基於namespace級別的快取,一個名稱空間,對應一個二級快取
工作機制
- 一個會話查詢一條資料,這個資料會儲存在當前會話的一級快取中
- 如果當前會話關閉了,這個對話的一級快取就沒有了,但是我們想要的是會話關閉了,一級快取的資料就會被儲存在二級快取中
- 新的會話查詢資訊,就可以在二級快取中獲取資訊
- 不同的mapperhu查出的資料,會放在自己對應的快取中
步驟
-
需要在setting中中顯示開啟二級快取
-
設定名 描述 有效值 預設值 cacheEnabled 全域性性地開啟或關閉所有對映器配置檔案中已配置的任何快取。 true | false true -
在mapper中 配置二級快取
-
加上
-
<cache eviction="FIFO" //快取策略 flushInterval="60000" //重新整理實現 size="512" //快取大小 readOnly="true"/> //只讀