MyBatis_day1

一.MyBatis框架初使用

  1. 使用底層的selectOne()方法
    • 導入Mybatis的jar包
    • 創建一個全局配置文件 mybatis-config.xml ,根據全局配置文件,創建了一個
      SqlSessionFactory對象.
    • 創建一個sql映射文件, EmployeeMapper.xml,該配置文件中配置了sql語句.
    • 將sql映射文件註冊到全局配置文件中
    • 從SqlSessionFactory中獲取SqlSession對象. sqlSession代表和數據庫的一次會話.
    • 然後調用selectOne(“sql語句的唯一標識”,執行sql的參數)完成查詢操作.
    • 最後將SqlSession對象關閉.釋放資源.
將sql映射文件註冊到全局配置文件中:
       <mappers>
            <!--<mapper resource="EmployeeMapper.xml"/>-->引入一個sql映射配置文件
            <!--批量引入-->
            <package name="com.atguigu.mybatis.dao"/>該包下方的配置文件全部引入
        </mappers>

2.目錄結構
在這裏插入圖片描述

二.Mapper接口開發

Mapper接口的好處:
1.接口中定義的方法明確的類型約束(方法參數的類型 方法返回值的類型)
2.接口本身:
接口本身就是抽象.抽出了規範.不強制要求如何做具體的實現.可以使用jdbc,hibernate,Mybatis.
接口將規範與具體的實現分離.
Mapper接口開發, MyBatis會爲接口生成代理實現類。代理對象完成具體的增刪改查操作.
最底層還是使用selectOne,update等方法來完成的.
Mapper接口開發需要注意:
1.Mapper接口要與sql映射文件動態綁定. sql映射文件的namespace指定成接口的全類名.

 <mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper"></mapper>

2.Mapper接口方法與sql映射文件的sql語句綁定。 sql語句的id值指定成接口中的方法名.

 <!--
select: 配置查詢的sql語句
	 id:sql語句的唯一標識,不能重複,當添加上databaseId="XXX"時,即使用不同的數據庫,此時id允許重複
	 resultType:當前sql查詢到的數據想讓MyBatis封裝的javaBean對象的類型.
     #{id}: 從傳遞過來的參數中取出id值.
 -->
<!--	public Employee getEmpById(Integer id );-->
    <!--sql語句的id值指定成方法名,目的是將sql語句與方法綁定-->
    <select id="getEmpById" resultType="com.atguigu.mybatis.beans.Employee">
        select id,last_name,gender,email from tb1_employee where id = #{id}
    </select>

三.全局配置文件

1.properties
  
    <!-- 
    	properties: Mybatis可以是用properties來引入外部properties類型的文件.
    		resource: 引入類路徑下的資源
    		url: 引入網絡路徑或者是磁盤路徑下的資源
     -->
     <properties resource="db.properties" ></properties>在db.properties中配置數據庫的驅動,用戶名等
     
2.settings
     <!-- 
		settings: 包含了很多重要的設置項
			setting: 用來設置每一個設置項
				name:設置項的名稱
				value:設置項的值
	 -->
	 <settings>
	 	<!-- 自動映射下劃線到駝峯命名    (數據庫中常用下劃線命名,JavaBean類中用大寫命名)
	 	 DB: last_name  autoMapping:lastName -->
	 	<setting name="mapUnderscoreToCamelCase" value="true"/>
	 </settings>
	 
3.typeAliases
     	 <!-- 
	 	typeAliases:別名處理,爲java 類型註冊別名
	 		typeAlias: 爲某個java類指定別名
	 			type: 指定java的類型(包名+ 類名
	 			alias: 指定具體的別名。 如果alias不顯示的指定,則默認的別名是類名的首字母小
                       寫. 
	 				   別名不區分大小寫。
	 		package: 批量取別名.
	 			 name:指定包名。   爲該包下的所的類取默認的別名。
	 			 批量取別名可能會出現別名衝突的情況. 例如指定的包下與子包下相同的類.
	 			 可以使用@Alias("別名")在類上標註具體的別名.
	  -->
	  <typeAliases>	
	  	<package name="com.atguigu.mybatis.beans"/>
	  	<!-- <typeAlias type="com.atguigu.mybatis.beans.Employee" alias="emp" /> -->
	  </typeAliases>
	  
 4.environments
       <!--
		environments: 環境們。  使用default來指定具體使用的環境.
			 environment:配置具體的環境.
			 	id: 當前環境的標識
			 	transactionManager:事務管理器
			 		type: 配置具體的事務管理器的類型
			 			JDBC: JdbcTransactionFactory
			 			MANAGED:ManagedTransactionFactory			
			 	最終: 事務管理要交給Spring. 使用Spring的聲明式事務.		 	
			 	dataSource:數據源
			 		type: 執行數據源的類型.
			 			UNPOOLED:不使用連接池 UnpooledDataSourceFactory
			 			POOLED:使用連接池  PooledDataSourceFactory
			 			JNDI:從web服務器中獲取數據源.  JndiDataSourceFactory			 
			 	最終: 數據源交給Spring管理
	  -->
	<environments default="mysql">此處default配置那個id標識,使用的就是哪一個數據庫
		<environment id="mysql">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
		 <!--使用oracle數據庫-->
        <environment id="oracle">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${orcl.driver}" />
                <property name="url" value="${orcl.url}" />
                <property name="username" value="${orcl.username}" />
                <property name="password" value="${orcl.password}" />
            </dataSource>
        </environment>
    </environments>
    
5.databaseIdProvider
     <!-- 
		databaseIdProvider:
			Mybatis用來支持多數據庫廠商。Mybatis可以根據不同的數據庫執行不同的sql語句
			DB_VENDOR: VendorDatabaseIdProvider 作用就是得到數據庫廠商的標識名.
					   Connection.getMetaData().getDataBaseProductName();	
			常見的數據庫廠商的標識名:
				MySQL:  MySQL
				Oracle: Oracle
				SQL Server:  SQL Server		
	 --> 
	 <databaseIdProvider type="DB_VENDOR">
	 	<!-- 爲數據庫廠商的標識名起別名 -->
	 	<property name="MySQL" value="mysql"/>
	 	<property name="Oracle" value="oracle"/>
	 	<property name="SQL Server" value="sqlserver"/>
	 </databaseIdProvider>
      
6.mappers
      <!-- 
		mappers: 引入sql映射文件
			mapper: 引入單個的sql映射文件
				resource: 引入類路徑下的sql映射文件
				url:引入網絡路徑或者是磁盤路徑下的sql映射文件.
		    package: 批量引入sql映射文件
		    		 要求: 
		    		   1.sql映射文件的名字與 Mapper接口的名字一致.
		    		   2.Sql映射文件與Mapper接口必須在同一目錄下.
		    	name:指定包名	    		 
 	 -->
 	<mappers>
    <!--<mapper resource="EmployeeMapper.xml"/>-->
    <!--批量引入-->
    <package name="com.atguigu.mybatis.dao"/>
</mappers>


sql映射文件

1.增刪改查

 <insert id=""  parameterType="" databaseId="" >
 <update>
 <delete>
 <select id="" parameterType="" resultType=""  databaseId="">
 如果想要獲取到增刪改對數據的影響條數,可以直接在接口的方法中聲明返回值類型即可.

2.主鍵自增以及主鍵值的返回

  • a.對於支持自增主鍵的數據庫(Mysql),可以使用useGeneratedKeys=“true”
    keyProperty=“javaBean類的某個屬性”

  • b.對於不支持自增主鍵的數據庫(oracle),使用selectKey的子標籤完成主鍵值得返回.
    selectKey的用法:
    BEFORE: selectKey在插入語句之前執行
    AFTER: selectKey在插入語句之後執行

  • c.Oracle數據庫的自增策略:
    使用序列模擬自增. 可以從序列中查詢 nextval currval.
    在這裏插入圖片描述

3.參數傳遞:

單個參數(普通類型(基本類型/包裝類型+String)):  Mybatis不會做特殊的處理 
       取值: #{參數名(隨便寫)} 取出參數值
       
多個參數:MyBatis會做特殊處理. 多個參數會被封裝成一個Map。
	      封裝map的規則:
			 key: param1 ,param2 , param3 ..... paramN / 0 1 2 ....N-1
          value:具體傳入的參數值
          
<!--測試傳遞多個參數的編寫方式:public Employee getEmpByIdAndLastName(Integer id,String lastName);
   select * from tb1_employee where id=#{param1} and last_name=#{param2}
   
   當接口處明確標出Param時,這裏可以使用對應的值來進行傳參
      public Employee getEmpByIdAndLastName(@Param("id")Integer id , @Param("lastName")String lastName);
-->
<select id="getEmpByIdAndLastName" resultType="com.atguigu.mybatis.beans.Employee">
    select * from tb1_employee where id=#{id} and last_name=#{lastName}標明時可以使用對應值
</select>

異常: ### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found.
         Available  parameters are [1, 0, param1, param2]
	  解決: 取值使用#{param1/ 0}  #{param2 / 1 }

1.命名參數**: 明確的指定多個參數封裝map的時候所使用的key。 @Param(“key”)
取值: #{@Param指定的key/paramN}

2.POJO: 如果參數很多,正好又是業務邏輯的數據模型中的屬性,直接傳入POJO
取值: #{POJO的屬性名}

3.Map: 如果參數很多,不是業務邏輯的數據模型中的屬性,可以封裝成map傳入.
取值: #{map中的key}
map.put(“aa”,1001);
map.put(“bb”,“Tom”);
映射配置中:
select * from tb1_employee where id=#{aa} and last_name=#{bb}取key值

參數處理的源碼分析

 names={0=id,1=lastName}
 args=[1001,Tom]
	public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();
    if (args == null || paramCount == 0) {
      return null;
    } else if (!hasParamAnnotation && paramCount == 1) {
      return args[names.firstKey()];
    } else {
      final Map<String, Object> param = new ParamMap<Object>();
      int i = 0;
      for (Map.Entry<Integer, String> entry : names.entrySet()) {
        param.put(entry.getValue(), args[entry.getKey()]);
        // add generic param names (param1, param2, ...)
        final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
        // ensure not to overwrite parameter named with @Param
        if (!names.containsValue(genericParamName)) {
          param.put(genericParamName, args[entry.getKey()]);
        }
        i++;
      }
      return param;
    }

參數值的獲取方式

1.#{}: 可以獲取map中的值 或者是POJO對象屬性的值。 還可以直接獲取普通類型的參數.

2.${}: 可以獲取map中的值 或者是POJO對象屬性的值

區別:
#{}:是以預編譯的形式將參數設置到sql語句中. PreparedStatement 防止sql注入.
${}:取出的值直接拼裝到sql語句中.會有安全問題.

使用場景:
   大部分情況下推薦使用#{},原生的jdbc不支持佔位符的地方可以使用 ${}來進行動態的賦值.
   例如在表名的位置可以使用${}來獲取值

   eg: select  xxxxx    from    where  條件  order by 排序字段  排序方式  limit ?,?;
   分表:
		  select * from 2016_salary ;
		  select * from 2017_salary ; 
		  select * from ${year}_salary ;
       用戶選擇2016年,則從2016_salary表查.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章