【Mybatis】Mybatis實戰1
阿新 • • 發佈:2020-09-08
MyBatis 框架
資料持久層框架(DAO將資料持久化到資料庫),實現DAO層的程式碼。對JDBC程式碼的封裝。
特點:
①封裝通用功能,簡化程式碼,提高開發效率(獲得conn,繫結引數,傳送sql,處理異常,處理結果集)
②sql放在配置檔案中,提高sql可維護性。
③自帶連線池功能
④自帶快取(提高查詢效率) [重點]
1).第一個MyBatis程式
核心程式設計思想 ①書寫DAO介面 ②開發Mapper檔案 SQL+繫結的引數===實現介面中的方法。 環境搭建 1. 匯入jar。 1. 匯入mybatis的jar 2. 匯入oracle的驅動jar 3. 匯入mybatis依賴lib的jar。 2. 引入配置檔案: mybatis-config.xml(連線資料庫相關的引數) driverClassName oracle.jdbc.OracleDriver url jdbc:oracle:thin:@localhost:1521:xe username hr password hr transactionManager 連線池(POOLED/UNPOOLED) XxxMapper.xml(相當於dao的實現類) 3. 初始化配置
2).MyBatis實現DAO、以及重要的API
(1)實現DAO程式設計 ① 寫DAO介面 public interface PersonDAO{ void insert(Person person); } ② 書寫Mapper檔案(DAO的實現類)[sql+引數] <insert id="實現介面的方法名" parameterType="引數中實體型別全類名"> insert into t_person values(seq_person.nextval,#{屬性名},#{sex},#{age},#{mobile},#{address}) </insert> 屬性: id: 實現的介面的方法名 parameterType: 引數型別(實體的全類名) sql語中繫結引數: #{屬性名} ③ 註冊管理mapper檔案[在mybatis-config中配置] <mappers> <!-- 註冊管理所有的mapper檔案 --> <mapper resource="com/baizhi/demo1/PersonDAOImpl.xml"></mapper> </mappers> resource: mapper檔案相對於src的路徑。 (2)重要API 目的: 使用DAO獲得PersonDAO的物件、呼叫personDAO的方法。 常用的類: sqlSession: ①獲得dao介面的實現類的物件。 XxxDAO dao = sqlSession.getMapper(介面.class); ②相當於connection.[提交事務 關閉close,回滾事務] SqlSessionFactory ①獲得sqlSession SqlSession session = sqlSessionFactory.openSession(); ②儲存封裝mybatis-config.xml配置檔案。 SqlSessionFactoryBuilder: 讀取配置檔案 Resources: 獲得讀取配置檔案的輸入流。 步驟: ①獲得mybatis-config的輸入流 ②讀取mybatis-config的檔案,構造成SqlSessionFactory ③通過SqlSEssionFactory獲得SqlSession ④通過SqlSession獲得DAO介面的物件 ⑥呼叫方法測試。
3).MyBatis-DAO介面的修改、刪除、(模糊)查詢、多參方法呼叫
(1)操作 ①修改 a. 書寫PersonDAO介面,宣告修改的方法 public interfafce PersonDAO{ public void update(Person person); } b. 在Mapper通過標籤實現方法 <update id="update" parameterType="Person的全類名"> update t_person set name = #{name},sex =#{sex},age=#{age},mobile=#{mobile},address=#{address} where id = #{id} </update> c. 註冊mapper檔案 [一個介面,對應一個mapper檔案,註冊一次] ②刪除 a. 定義dao介面的方法 b. 書寫mapper檔案標籤 c. 註冊mapper檔案。 限定引數繫結的名字 a.定義介面方法 public interface PersonDAO{ public void delete(@Param("指定引數繫結使用的名字")Integer id); } b Mapper檔案 <delete>delete from t_person where id = #{指定引數繫結使用的名字} </delete> ③查詢 查詢單個: a. 書寫DAO介面方法 public interface PersonDAO{ Person selectById(Integer id); } b. mapper檔案實現該方法(sql 引數 對查詢結果對映實體物件) <select id="selectById" parameterType="java.lang.Integer" resultType="一行資料對映實體物件型別 select id,name,sex,age,mobile,address from t_person where id = #{id} </select> c. 註冊mapper檔案 ResultType的作用: 作用: 對映查詢結果的列封裝成實體的屬性 要求: 查詢結果的列名必須和實體的屬性名一致 注意:表列名和實體屬性名不一致時,通過sql 的as起別名方式,使查詢結果的列名和實體的屬性名一致。 查詢多個: 只需要明確單行資料對映的實體型別,MyBatis會自動講每個資料封裝的每個實體放入list集合中。 a. 書寫DAO介面方法 public interface PersonDAO {List<Person> selectAll(); } b. 書寫mapper檔案中的標籤 <select id="selectAll" resultType="rs的一行資料對映實體型別"> select id,name,sex,age,mobile,address from t_person </select> c. 註冊mapper檔案 模糊查詢: <select id="selectByName" resultType="rs的一行資料對映實體型別" paramType=”java.lang.String”> select * from t_person where name = ‘%’ || #{name} ||‘%’ 或 select * from t_person where name = ‘%${name}%’ </select> ④多個引數(基本,包裝,String): 方案一: @Param給介面方法的引數起別名 public interface UserDAO { User selectByUsernameAndPassword(@Param("username")String username,@Param("password")String password); } //可以不用寫型別 select id,username,password from t_user where username = #{username} and password = #{password} 方案二: 繫結引數通過#{引數的序號從0開始} 注意:MyBatis的Mapper檔案的sql書寫 >或者 < 問題: 會發生轉義 解決: 替換成轉義字元 MyBatis注意事項總結: ①增刪改必須要提交事務。(事務自動開啟,手動提交模式) ②引數繫結情況 實體型別 #{屬性名} (單個引數)基本資料型別+包裝型別+String #{隨便} 沒有引數 parameterType不用寫 多個引數 可以起別名,可以按序號繫結 ③mapper檔案轉義字元 sql的篩選條件: < ---> < > ---> > & ---> & “ ---> " © ---> ' eg: select * from t_user where id <= 1000; //選擇id值不超過1000的使用者資訊
4).MyBatisUtil類的封裝、MyBatis的使用技巧、以及日誌
(1)MyBatisUtil類的封裝
MyBatis核心API
SqlSession:
①相當於connection
sqlSession.commit();//提交事務
sqlSession.rollback();//回滾事務
sqlSession.close();//將連線還回連線池。
②獲得XXxDAO介面的物件。
輕量級物件,每次操作建立一個新的。
比如: Action SqlSession Connection
③SqlSessionFactory
作用: 封裝mybatis-config配置檔案的資訊。
重量級物件,web應用只建立一個。物件的建立消耗資源。
java程式碼:
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil2 {
private static SqlSessionFactory factory = null;
private static ThreadLocal<SqlSession> tdl = new ThreadLocal<SqlSession>();
static{
InputStream is = null;
try {
is = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {throw new RuntimeException("mybatis配置檔案載入異常",e);
}finally{
if(is != null){
try { is.close();
} catch (IOException e) { e.printStackTrace(); }
}
}
}
/** 獲得SqlSession */
public static SqlSession getSqlSession(){
SqlSession session = null; //1. 獲得DAO物件 sqlSession
try {
session = tdl.get();
if(session == null){ //當前執行緒如果沒有sqlSEssion
session = factory.openSession();
tdl.set(session); //將session存入當前執行緒
}
} catch (Exception e) {throw new RuntimeException("獲得SqlSession的異常",e);}
return session;
}
/** 根據介面的類物件,獲得dao的物件*/
public static <T> T getMapper(Class<T> clazz){
SqlSession session = getSqlSession(); //獲得sqlSession
T t = session.getMapper(clazz); //呼叫session.getMapper(clazz);
return t;
}
/** 提交事務+釋放資源*/
public static void commit(){
//sqlSession.commit();
try{
SqlSession session = getSqlSession();
session.commit();
}catch(RuntimeException e){throw e;
}finally{close();}
}
/** 回滾事務+釋放資源 */
public static void rollback(){
try{
SqlSession session = getSqlSession();
session.rollback();
}catch(RuntimeException e){ throw e;
}finally{close();}
}
/** 釋放session資源 */
public static void close(){
//session.close();
SqlSession session = getSqlSession();
if(session != null){
session.close();
//從當前執行緒中移除該session
tdl.remove();
}
}
}
(2)MyBatis使用技巧、日誌
①配置檔案提示
②日誌
MyBatis整合日誌功能:mybatis執行期間的痕跡,通過控制檯列印。
目的: 檢視mybatis執行的痕跡,除錯,驗證。
使用: 匯入日誌的jar log4j.jar; 匯入配置檔案. log4j.properties [必須放在src根目錄]
補救工作:在建立專案時java version可以選擇高版本、Target Runtime可以選擇自己安裝的TomCat
5).MyBatis實體起別名(簡化)、引數繫結底層原理、物件插入後繫結隨機的id(可返回)
(1)實體簡化
①給實體類的許可權定名取別名。(mybatis-config配置檔案)
com.baizhi.demo1.Person 別名="Person"
<typeAliases>
<typeAlias type="實體的全類名" alias="別名"></typeAlias>
<typeAlias></typeAlias>
</typeAliases>
②Mapper使用實體類名
resultType="Person" 或 parameterType=”Person”
(2)引數繫結的底層原理
①預設mapper檔案繫結引數 #{xxx}
說明:底層使用的PreparedStatement物件,使用的是SQL預編譯執行、引數繫結。
優點: 防止sql注入、相對效率高(一點)
缺點: 只能繫結資料值. sql關鍵字,列 非資料無法繫結。
②使用sql字串拼接繫結引數 ${xx}
優點: 可以繫結任何內容。(關鍵詞,列)
缺點: sql注入。
mybatis使用字串拼接繫結引數: ${xx}
(3)插入操作後的實體物件繫結id
傳統的插入:提前查出要隨機的id:select 序列名.nextval from dual;然後呼叫物件的set方法進行繫結。
MyBatis方式:
<insert id='insert' parameterType="實體型別">
<!--在insert語句之前,執行select序列的sql,為了給引數的id屬性繫結值。-->
<selectKey order="BEFORE" resultType="型別" keyProperty="sql執行結果繫結引數的實體的屬性名,例如id">
select seq_user.nextval from dual
</selectKey>
insert into t_user values(#{id},…)
</insert>
注:order(在插入語句之前繫結),keyProperty(要繫結的屬性名)