1. 程式人生 > >MyBatis總結(筆面試題)

MyBatis總結(筆面試題)

目錄

Mybatis

1.談談MyBatis

2.Mybatis分為三層

3.Mybatis和jdbc的區別 

4.對映檔案

5.模糊查詢:LIKE

6.$和#的區別

7.主鍵自增

8.API

9.SqlSession不是執行緒安全的

10.呼叫sqlSession.selectOne()還是SQLSession.selectList()是由mapper介面的返回值決定的

11.Mapper介面的引數:簡單型別,pojo型別包裝型別,Map,List集合等

12.指定別名

13.隱射檔案的載入

14.輸入引數

15.只寫map的

16.動態sql的編寫

17.快取

18.Mybatis的程式設計步驟

19.主鍵自增問題

21.如何獲取自動生成的(主)鍵值

22.使用MyBatis的mapper介面呼叫有哪些要求?

23.Statement和PrepareStatement的區別


Mybatis

1.談談MyBatis

Mybatis是一個優秀的持久層框架,它對jdbc的操作資料庫的過程進行封裝,使得開發者只需要專注於SQL語句本身,而不用去關心註冊驅動,建立connection等,Mybatis通過xml檔案配置或者註解的方式將要執行的各種statement配置起來,並通過java物件和statement中的sql進行對映成最終執行的sql語句,最後由Mybatis框架執行sql並將結果對映成java物件並返回。

2.Mybatis分為三層

  (1)API介面層:提供給外部使用的介面API

  (2)資料處理層:負責具體的SQL

  (3)基礎支撐層:負責最基礎的功能支撐,如連線管理,事務管理,配置載入和快取處理

3.Mybatis和jdbc的區別 

  相比與jdbc,Mybatis具有以下優點    

       (1)資料庫連結建立,釋放頻繁造成系統資源浪費會影響系統性能,使用資料庫可以解決

               解決:在核心配置檔案SqlMapConfig.xml中配置資料鏈接池,使用資料鏈接池管理資料庫連結

       (2)Sql寫在程式碼中不易於維護,修改需要變動java程式碼

             在對映檔案XXXMapper.xml檔案中配置sql語句與Java程式碼分離

       (3)向Sql語句傳輸引數麻煩,因為Sql語句的WHERE條件不一定,可能多也可能少,佔位符需要和引數一一對應

            Mybatis可以自動將Java物件對映到sql語句

       (4)對結果集解析麻煩,sql變化導致解析程式碼變化,且解析前需要遍歷,將資料庫記錄封裝成pojo物件解析更加方便

              Mybatis可以自動將sql執行結果對映到Java物件

4.對映檔案

  <mapper name="text">

        <select id="FindByID" paramenterType="int" resultType="com.guigu.User">

               select * from user where id=#{id}

        </select>

  </mapper>

namespace:名稱空間  id:根據id執行sql  parameterType:入參  resultType:出參   #{id} 接收的引數

5.模糊查詢:LIKE

   <selectid="findByName2"

       parameterType="java.lang.String" resultType="com.gugiu.model.User">

              select *  from user where name like  '%${value}%'

   </select>

   修改  

 <update id="updateUserById"  parameterType="com.gugiu.model.User">

              update user set name = #{name},age =#{age},address=#{address}

              where id =#{id}

  </update>

6.$和#的區別

  (1)#把傳入的引數當做字串處理  $表示直接顯示

  (2)#很大程度防止Sql注入(語句拼接)

  (3)能用#儘量用#

7.主鍵自增

8.API

  (1)SqlSessionFactoryBuilder

    通過載入MyBatisde 核心配置檔案,建立SqlSessionFactory

  (2)SqlSessionFactory

      定義了openSession的不同過載方法

  (3)sqlSession

      定義了資料庫的操作,增刪改查

9.SqlSession不是執行緒安全的

10.呼叫sqlSession.selectOne()還是SQLSession.selectList()是由mapper介面的返回值決定的

  

     List<User>  findUserByName(String name);  selectList()

       User  findUserByName(String name);   selectOne()

11.Mapper介面的引數:簡單型別,pojo型別包裝型別,Map,List集合等

12.指定別名

  單個檔案        

      

 <typeAliases>

        <typeAlias type="com.gugiu.model.User" alias="user"/>

 </typeAliases>

  批量    

   <typeAliases>

              <package name="com.guigu.model1"/>

              <package name="com.guigu.model2"/>

   </typeAliases>

13.隱射檔案的載入

    單個檔案     

  <mappers>

              <!—載入單個對映檔案-->

              <mapper resource="com/guigu/mapper/UserMapper.xml"/>
</mappers>

    批量 

     <mappers>

         <package name="com.guigu.mapper"/>

       </mappers>

14.輸入引數

   (1)簡單型別     

 <select id="findById" parameterType="int" resultType="user" >

           select * from User where id = #{id} ;

</select>

   (2)pojo型別 

   <insert id="addUser" parameterType="com.guigu.model.User">

          <selectKey keyColumn="id" order="AFTER" resultType="int">

             SELECT LAST_INSERT_ID()

          </selectKey>

        INSERT INTO user (name,age,address)

              VALUE(#{name},#{age},#{address})

   </insert>

   (3)pojo的包裝型別  

 <select id="findById" parameterType="com.guigu.model.UserVo" resultType="user">

              select * from User where id = #{user.id} ;

 </select>

   (4)Map

   <insert id="addUserMap" parameterType="hashmap">

    INSERT INTO my_user(NAME,age,address)  VALUE(#{name},#{age},#{address})

   </insert>

15.只寫map的

 

    <selectid="findById"  parameterType="int"  resultMap="userMap">

          SELECT id ,name user_name  FROM my_user WHERE id = #{id}

    </select>

16.動態sql的編寫

    (1)if

         <insert id="addUserVo"  parameterType="com.guigu.mybatis.pojo.UserVo">

               <if  test="user != null">

                  insert into  my_user (name,age,address)

                  value(#{user.name},#{user.age},#{user.address})

               </if>

          </insert>

    (2)where          

   <select id="findByUserVo" parameterType="UserVo"resultType="User">

               select * from my_user

                            <where>

                                   <iftest="user!= null">

                                          <if test="user.id != null and user.id !='' ">

                                                 and id = #{user.id}

                                          </if>

                                          <if test="user.name != null and user.name !='' ">

                                                 and name like '%#{user.name}%'

                                          </if>

                                   </if>

                            </where>

            </select>

    (3)sql程式碼片段      

    <sql id="find_user_byId">

                     <if test="user.id != null and user.id !='' ">

                                          and id = #{user.id}

                     </if>

        </sql>

              <sql id="find_user_byAge">

                     <if test="user.age != null and user.age !='' ">

                                          and age = #{user.age}

                     </if>

              </sql>

              <select id="findByUserVo"  parameterType="UserVo" resultType="User">

                     select * from my_user

                     <where>

                            <if test="user!= null">

                            <include ref id="find_user_byId"></include>

                            <include ref id="find_user_byAge"></include>

                            </if>

                     </where>

              </select>

     (4)foreach

           <insert id="addUsers" parameterType="map">

                  insert into my_user (name,age,address)

                <if test="users != null">

                values

                  <foreach collection="users" item="user" separator=",">

                    (#{user.name},#{user.age},#{user.address})

                  </foreach>

                </if>

              </insert>

             

              <select id="findByIds"  parameterType="map" resultType="User">

                     <if test="userIds != null">

                            select * from my_user

                            <where>

                                   <foreach collection="userIds"  item="userId" separator="or">

                                   id = #{userId}

                                   </foreach>

                            </where>

                     </if>

              </select>

17.快取

  (1)一級快取(SqlSession級別)

      MyBatis一級快取的作用域是同一個SqlSession,在同一個sqlSession中兩次執行

         相同的sql語句,第一次執行後會將查詢到的資料儲存到快取當中,第二次會從緩

         存中進行查詢,從而提高查詢效率,當一個SqlSession結束之後,一級快取也將不

         存在,Mybatis預設開啟一級快取。

  (2)二級快取(Mapper級別)

         二級快取的作用域是mapper的同一個namespace,執行兩次相同的SQL語句,第一次執行後會將查詢到的資料儲存到快取當中,第二次會從快取中進行查詢,從而提高查詢效率,預設不開啟。      

18.Mybatis的程式設計步驟

   (0)建立SqlSessionFactoryBuilder

   (1)通過SqlsesionFactoryBuilder建立sqlSessionFactory

   (2)通過SqlSessionFactory建立sqlSession  

   (3)通過sqlSession執行資料庫操作

   (4)呼叫session.commit()提交事務

   (5)呼叫session.close()關閉會話

       publicclass MyBatisUtil {

              privatestatic SqlSessionFactory  factory = null;

              static {

                     try {

                            SqlSessionFactoryBuilder builder = newSqlSessionFactoryBuilder();

                            InputStream  inputStream = Resources.getResourceAsStream("MyBatisConfig.xml");

                            //建立Session工廠

                            factory = builder.build(inputStream);

                     } catch (Exception e) {

                            e.printStackTrace();

                     }

              }

             

              publicstatic SqlSession  getSqlSession(){

                     //獲得session會話

                     return factory.openSession();

              }

       }

19.主鍵自增問題

20.實體類中的屬性名和資料表中的列名不一致

   (1)在sql語句中使用別名

   (2)事先指定對映關係,這樣Mybatis也能自動完成對映。Mybatis提供了resultMap標籤

  


 <resultMap type="User" id="UserResultMap">

     <id column="id" property="id"/>

     <result column="user_name" property="userName"/>

     <result column="user_password" property="userPassword"/>

 </resultMap>
  1. Mybatis提供了一個全域性屬性mapUnderscoreToCamelCase來解決兩者名字不一致的問題。
<settings>

           <setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>

21.如何獲取自動生成的(主)鍵值

   解決思路:通過LAST_INSERT_ID()獲取剛插入記錄的自增主鍵值,在insert語句執行後,執行select LAST_INSERT_ID()就可以獲取自增主鍵。

    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">

              <selectKey keyProperty="id" order="AFTER" resultType="int">

                 select LAST_INSERT_ID()

              </selectKey>

          INSERT INTO USER(username,birthday,sex,address)

          VALUES(#{username},#{birthday},#{sex},#{address)

     </insert>

22.使用MyBatis的mapper介面呼叫有哪些要求?

(1)Mapper介面方法名和mapper.xml中定義的每個sql的id相同

(2)Mapper介面中輸入的引數型別和mapper.xml中定義的每個sql的ParameterType相同

(3)Mapper介面中輸出的引數型別和mapper.xml中定義的每個sql的resultType相同

(4)Mapper.xml檔案中的namespace即是介面的類路徑

23.Statement和PrepareStatement的區別

  PreparedStatement:表示預編譯的 SQL 語句的物件。

  (1)PrepareStatement可以使用佔位符,是預編譯的,批處理比Statement效率高

  (2)在對資料庫只執行一次性存取的時侯,用 Statement 物件進行處理。

  (3)PreparedStatement的第一次執行消耗是很高的. 它的效能體現在後面的重複執行