Mybatis02:CRUD操做及配置解析

使用代理對象的方式實現CRUD操做

select

  • select標籤是mybatis中經常使用的查詢標籤
  • select中有不少屬性能夠詳細配置每一條SQL語句
    • id屬性:標識是咱們接口中的那個方法。接口中的方法名與映射文件中的SQL語句id一一對應
    • parameterType屬性:用於指定傳入的參數類型
    • resultType屬性:用於指定結果集的類型
    • ......

需求:根據id查詢用戶java

一、在UserDao中添加對應方法mysql

/**
     * 根據用戶id查詢用戶
     * @param userId 要查詢的用戶id
     * @return 若是存在返回該用戶,不存在則返回null
     */
    User findById(Integer userId);

二、在UserDao.xml中添加select語句sql

<!--根據id查詢用戶(記住這裏有返回值類型,要告知程序返回值類型是什麼)-->
    <select id="findById" resultType="com.lng.pojo.User">
        select * from user where id = #{id};
    </select>

三、在測試類中測試
這裏和下面就不測試了,就是獲取SqlSession對象來進行操做數據庫

查詢使用聚合函數緩存

一、在UserDao中添加對應方法服務器

/**
     * 查詢總用戶數
     * @return
     */
    int findTotal();

二、在UserDao.xml中添加對應的語句mybatis

<!--查詢總用戶數-->
    <select id="findTotal" resultType="int">
        select count(*) from user;
    </select>

有多個查詢條件(多是同一個對象的,也可能不是同一個對象的)
例如根據用戶名和地址查詢用戶併發

思路一:直接在方法中傳遞參數
一、在接口方法的參數前加@Param屬性
二、Sql語句編寫的時候,直接取@Param中設置的值便可,不須要單獨設置參數類型app

//在UserDao接口中添加以下方法
User findByAddAndName(@Param("username") String username, @Param("address") String address);

//在UserDao.xml中添加以下語句
<select id="findByAddAndName" resultType="com.lng.pojo.User">
        select * from user where username = #{username} and address = #{address};
</select>

思路二:使用Map
一、在接口方法中,參數直接傳遞Map函數

User findByAddAndName(Map<String, Object> map);

<select id="findByIdAndName" resultType="com.lng.pojo.User" parameterType="map" >
        select * from user where address = #{address} and username = #{username};
</select>

思路三:自定義一個查詢類
其實這種方式和思路二是一個意思,就是將咱們要查詢的條件封裝進一個類中,而後當成參數給傳遞過去

總結:若是參數較多的狀況下建議使用Map或自定義實現類的方式,反之則使用直接傳遞參數的方式

注意事項

在使用增、刪、改操做須要提交事務

一開始執行的時候就將自動提交事務給關閉了,因此要咱們手動提交事務,使用sqlSession.commit()提交

insert

咱們使用insert標籤進行插入操做,他的配置和select差很少

給數據庫增長一個用戶

一、在UserDao接口中添加對應方法

/**
     * 保存方法
     * @param user
     */
    void saveUser(User user);

二、在UserDao.xml中添加對應語句

<!--保存用戶-->
    <insert id="saveUser" parameterType="com.lng.pojo.User">
        <!--配置插入操做後,獲取插入數據的id,會自動填充至咱們的User對象中-->
        <selectKey keyProperty="id" keyColumn="id" order="AFTER" resultType="java.lang.Integer">
            select last_insert_id();
        </selectKey>
        insert into user (username, birthday, sex, address) values (#{username}, #{birthday}, #{sex}, #{address});
     </insert>

update

使用update標籤進行用戶的更新

修改用戶信息

一、編寫接口方法

/**
     * 更新操做
     * @param user
     */
    void updateUser(User user);

二、編寫對應的配置文件SQL

<!--更新用戶-->
    <update id="updateUser" parameterType="com.lng.pojo.User">
        update user set username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address}
        where id = #{id};
    </update>

delete

可使用delete標籤進行刪除操做。

刪除用戶

一、編寫對應接口方法

/**
     * 根據id刪除用戶
     * @param userId 須要被刪除的用戶的id號
     */
    void deleteUser(Integer userId);

二、編寫對應配置文件的SQL

<!--刪除用戶-->
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id = #{id}; <!--若是參數是基本數據類型及其包裝類,那麼裏面的佔位符名隨便寫-->
    </delete>

模糊查詢

在java代碼中添加sql通配符(經常使用)

/**
     * 根據名稱模糊查詢用戶名稱
     * @param username
     * @return
     */
    List<User> findByName(String username);

    List<User> users = mapper.findByName("%王%");

<!--對應配置文件的寫法-->
 <!--根據名稱模糊查詢的語法-->
    <select id="findByName" resultType="com.lng.pojo.User" parameterType="java.lang.String">
        select * from user where username like #{username};<!--這種方式使用的是佔位符的方式,因此在傳遞參數的時候要直接傳遞完整的模糊語句-->
    </select>
  • 執行的SQL

在sql語句中拼接通配符,會引發SQL注入等問題

/**
     * 根據名稱模糊查詢用戶名稱
     * @param username
     * @return
     */
    List<User> findByName(String username);

    List<User> users = mapper.findByName("王");

<!--在對應中配置文件中編寫-->
 <!--根據名稱模糊查詢的語法-->
    <select id="findByName" resultType="com.lng.pojo.User" parameterType="java.lang.String">
       <!-- select * from user where username like '%${value}%'; 這種方式瞭解就好了,基本不會使用,這種方式不是用預處理SQL的方式-->
    </select>
  • 執行的SQL

  • 注意事項:咱們將原來的#{}佔位符,改爲了\({value}。注意若是用模糊查詢的這種寫法,那麼\){value}的寫法就是固定的,不能改爲其它名字。這個${value}就是咱們傳遞的參數。

  • #{}與${}的區別

    • #{}表示一個佔位符:經過#{}能夠實現PreparedStatement向佔位符中設置值,自動進行java類型和jdbc類型轉換,#{}能夠有效防止sql注入。#{}能夠接收簡單類型值或pojo屬性值。若是parameterType傳輸單個簡單類型值,#{}括號中能夠是value或其餘名稱

    • \({}表示拼接sql串:經過\){}能夠將parameterType傳入的內容拼接在sql中且不進行jdbc類型轉換,\({}能夠接收簡單類型值或pojo屬性值,若是parameterType傳輸單個簡單類型值,\){}括號中只能是value

      • 模糊查詢的${value}源碼分析

配置解析

核心配置文件

  • SqlMapConfig.xml核心配置文件
  • Mybatis的配置文件包含了會深深影響Mybatis行爲的設置和屬性信息
  • 能配置的內容以下:

environments元素

<environments default="development">
 <environment id="development">
   <transactionManager type="JDBC">
     <property name="..." value="..."/>
   </transactionManager>
   <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>
  • 配置Mybatis的多套運行環境,將SQL映射到多個不一樣的數據庫上,必須指定其中一個爲默認的運行環境(經過default指定)
  • 子元素節點:environment
    • dataSource元素使用標準的JDBC數據源接口來配置JDBC鏈接對象的資源
    • 數據源(dataSource)是必須配置的
    • 有三種內建的數據源類型:type="[UNPOOLED|POOLED|JNDI]")
    • unpooled:這個數據源的實現只是每次被請求是打開和關閉鏈接(沒有使用數據庫鏈接池技術)
    • pooled:這種數據源的實現利用「池」的概念將JDBC鏈接對象組織起來,這是一種使得併發Web應用快速響應請求的流行處理方式
    • jndi:這個數據源的實現是爲了能在如Spring或應用服務器這類容器中使用,容器能夠集中或在外部配置數據源,而後放置一個JNDI上下文引用。
    • 數據源也有不少第三方的實現:好比DBCP、c3p0、druid等等...
    • 子元素節點:transactionManager-[事務管理器]:
<!-- 語法 -->
<transactionManager type="[ JDBC | MANAGED ]"/>

mappers元素
mappers

  • 映射器:定義映射SQL語句文件的位置
  • 既然Mybatis的行爲其餘元素已經配置完了,咱們先就要定義SQL映射語句。可是首先咱們須要告訴Mybatis到哪裏去找到這些語句。Java在自動查找這方面沒有提供一個很好的方法,因此最佳的方式是告訴Mybatis到哪裏去找映射文件。你可使用相對於類路徑的資源引用,或徹底限定資源定位符(包括file:///的URL),或類名和報名等。映射器是Mybatis中最核心的組件之一,在Mybatis3以前,只支持xml映射器,即:全部的SQL語句都必須在xml文件中配置。而從Mybatis3開始,還支持接口映射器,這種映射器方式容許Java代碼的方式註解定義SQL語句,很是簡潔。

引入資源的方式

<!-- 使用相對於類路徑的資源引用 -->
<mappers>
 <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用徹底限定資源定位符(URL) -->
<mappers>
 <mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
<!--
使用映射器接口實現類的徹底限定類名
須要配置文件名稱和接口名稱一致,而且位於同一目錄下
-->
<mappers>
 <mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>
<!--
將包內的映射器接口實現所有註冊爲映射器
可是須要配置文件名稱和接口名稱一致,而且位於同一目錄下
-->
<mappers>
 <package name="org.mybatis.builder"/>
</mappers>

Mapper文件

<?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.kuang.mapper.UserMapper">
   
</mapper>
  • namespace中文意思:名稱空間,做用以下
    • namespace的命名必須跟某個接口的同名
    • 接口中的方法與映射文件中SQL語句id應該一一對應
    • namespace和子元素的id聯合保證惟一性,區別不一樣的mapper
    • 綁定DAO接口
    • namespace命名規則:包名+類名

Properties優化

數據庫這些屬性都是可外部配置且可動態替換的,既能夠在典型的Java屬性文件中配置,亦可經過properties元素的子元素來傳遞。
一、在資源目錄下新建一個JdbcConfig.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=123456

二、將文件導入properties配置文件

<configuration>
   <!--導入properties文件-->
   <properties resource="JdbcConfig.properties"/>

   <environments default="development">
       <environment id="development">
           <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>
   </environments>
   <mappers>
       <mapper resource="mapper/UserMapper.xml"/>
   </mappers>
</configuration>

typeAliases優化

類型別名視爲Java類型設置一個短的名。他只和XML配置有關,存在的意義僅在於用來減小全類名書寫的冗餘

<!--使用typeAliases用於配置別名。-->
    <typeAliases>
        <!--typeAlias用於配置別名。type屬性指定的是實體類全限定類名。alias屬性指定別名,當指定了別名就再也不區分大小寫
            (再也不區分大小寫的的意思是下面引用別名的時候能夠是user, USER, UsEr等都是能夠的)
        -->
        <typeAlias type="com.lng.pojo.User" alias="user"/>
    </typeAliases>

也能夠指定一個包名,Mybatis會在包名下面搜索須要的JavaBean,如:

<!--使用typeAliases用於配置別名。-->
    <typeAliases>
        <!--用於指定要配置別名的包,當指定以後,該包下的實體類都會註冊別名,而且類名就是別名,不在區分大小寫-->
        <package name="com.lng.pojo"/>
    </typeAliases>

如有註解,則別名爲其註解值,如:

@Alias("user")
public class User {
  ...
}

注意:基本數據類型及其包裝類和一些經常使用的類,Mybatis在加載的時候已經把經常使用的數據類型註冊了別名

其餘配置

設置

  • 設置(settings)相關
    • 懶加載
    • 日誌實現
    • 緩存開啓
  • 一個完整的settings元素的實例以下:
<settings>
 <setting name="cacheEnabled" value="true"/>
 <setting name="lazyLoadingEnabled" value="true"/>
 <setting name="multipleResultSetsEnabled" value="true"/>
 <setting name="useColumnLabel" value="true"/>
 <setting name="useGeneratedKeys" value="false"/>
 <setting name="autoMappingBehavior" value="PARTIAL"/>
 <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
 <setting name="defaultExecutorType" value="SIMPLE"/>
 <setting name="defaultStatementTimeout" value="25"/>
 <setting name="defaultFetchSize" value="100"/>
 <setting name="safeRowBoundsEnabled" value="false"/>
 <setting name="mapUnderscoreToCamelCase" value="false"/>
 <setting name="localCacheScope" value="SESSION"/>
 <setting name="jdbcTypeForNull" value="OTHER"/>
 <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

類型處理器

  • 不管是Mybatis在預處理語句(PreparedStatement)中設置一個參數時,仍是從結果集中取出一個值時,都會用類型處理器將獲取的值以合適的方式實現Java類型和JDBC類型的互相轉化
  • 能夠本身重寫類型處理器或建立本身的類型處理器來處理不支持的或非標準的類型【瞭解便可】

對象工廠

  • Mybatis每次建立結果對象的新實例時,他都會使用一個對象工廠(ObjectFactory)實例來完成
  • 默認的對象工廠須要作的僅僅是實例化目標類,要麼經過默認構造方法,要麼在參數映射存在的時候經過有參構造方法來實例化
  • 若是想覆蓋對象工廠的默認行爲,則能夠經過建立本身的對象工程來實現【瞭解便可】
相關文章
相關標籤/搜索