1. 程式人生 > >mybatis的使用-基於xml檔案

mybatis的使用-基於xml檔案

1.mybatis:MyBatis是一個優秀的持久層框架,對jdbc的操作資料庫的過程進行了封裝
    
2.mybatis環境搭建:
    1)建立工程匯入jar包:
        jar包:mybatis核心包、mybatis依賴包(下載的mybatis開發包的lib資料夾下的所有jar)、資料庫驅動包;        //包含日誌的包,如果要顯示日誌,需要編寫log4j.properties
    
    2)建立資料庫,表;定義實體類,一個實體類對應資料庫中的一張表
    
    3)sqlMapConfig.xml核心配置檔案:
        1)約束
        
        
2)根標籤configuration 3)定義屬性:properties 1)定義方式 方法一:可在外部.properties檔案中定義屬性,然後通過properties標籤引入: <properties resource="db.properties"></properties> 方法二:直接在properties標籤中定義 <properties> <property name="
jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/> <property name="jdbc.username" value="hello"/> </properties> 2)載入順序:先載入檔案內部properties標籤中定義的屬性,再載入外部檔案中的屬性,如果有重複的屬性,後面載入的會覆蓋前面載入的
3)屬性的引用方法:${屬性名} 如:${jdbc.driver} 4)定義別名:typeAliases標籤 //給類的全類名取別名 //aliases 別名 1)定義方式: 方法一:直接給某個全類名取別名,別名不區分大小寫 <typeAliases> //這個標籤下可有多個typeAlias <typeAlias type="cn.itheima.mybatis.po.User" alias="user"/> </typeAliases> 方法二:掃描包的形式建立別名,別名預設就是類名,不區分大小寫 <typeAliases> <package name="cn.itheima.mybatis.po"/> //會為這個包下所有的類建立別名,別名為類名 </typeAliases> 5)配置environments //再這個標籤下有多個environment <environments default="development"> //default定義預設情況下使用的environment,對應environment標籤的id <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> 6)配置mappers //配置sql對映檔案的位置 方式一:採用mapper標籤和resource屬性,基於classpath載入 <mapper resource="sqlmap/user.xml"/> 方式二:採用mapper標籤和class屬性,根據介面名稱載入mapper檔案 要求: 1)mapper對映檔案和介面在同一個目錄下 2)mapper對映檔案的名稱和介面名稱一致。 <mapper class="cn.itheima.mybatis.mapper.UserMapper"/> //這裡的class值為介面全類名 //配置檔案載入時會在這個介面所在的目錄下查詢相同類名的對映配置檔案,並建立代理 方式三:採用package標籤和name屬性:使用掃描包的形式載入mapper檔案 也需要方式二中的兩個條件 <package name="cn.itheima.mybatis.mapper"/> //name屬性指定包名 //配置檔案載入時會在這個包下找到介面和對應的對映配置檔案併為介面建立代理 示例: <mappers> <mapper resource="sqlmap/user.xml"/> //方式一 <mapper class="cn.itheima.mybatis.mapper.UserMapper"/> //方式二 <package name="cn.itheima.mybatis.mapper"/> //方式三 </mappers> 總結:第一種方式手動配置對映檔案位置,第二種第三種方式配置介面和包名,將自動載入對映配置檔案 7)sqlMapConfig.xml例項: <configuration> <properties resource="db.properties"> //在標籤中同時實現外部引入和內部定義 <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/> <property name="jdbc.username" value="hello"/> </properties> <!-- 配置pojo別名 --> <typeAliases> <package name="cn.itheima.mybatis.po"/> </typeAliases> <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> <!-- 載入mapper檔案 --> <mappers> <package name="cn.itheima.mybatis.mapper"/> </mappers> </configuration> 4)sql mapper對映檔案: 1)約束: 2)根標籤:mapper namespace屬性:namespace是名稱空間,用於sql語句的隔離 <mapper namespace="test"> <mapper namespace="cn.itheima.mybatis.mapper.UserMapper"> //namespace可以定義為介面全類名,用在mapper代理開發中 3)增刪該查的sql的配置: 1)查:select標籤 parameterType: 指定引數(輸入值)型別,基本資料型別可直接寫,如int、String。如果是一個物件或者包裝物件,要寫全類名或別名 resultType: 自動對映,指定返回值(輸出值)型別,基本資料型別可直接寫,如int、String。 如果是一個物件或List集合,要寫物件或者list集合中元素的全類名或別名 //這裡框架會將資料庫中欄位自動對映到物件的屬性上 注意:如果輸出值用一個物件接收,只有當資料庫表字段名和物件屬性相同才能成功對映,實現屬性封裝 resultMap: 手動對映實現資料庫中欄位和物件屬性的對映。 //當資料庫中欄位與物件的屬性不一致時,使用這種方式完成對映 輸出對映的手動定義: <resultMap type="user" id="userResultMap"> //type指定對映的物件的類全名或別名 //id是對映的標識 <id column="id" property="id" /> //id標籤實現主鍵的對映,這裡column表示資料庫中欄位,property為user物件中的屬性名,即把資料庫中的id對映到user物件中的id屬性 <result column="user_name" property="username"/> //普通屬性採用result標籤實現對映,類似id標籤,將資料庫中user_name對映到user中的username ... </resultMap> 注意:當resultMap中沒有關聯查詢的association和collection標籤的情況下, 配置手動對映時,不需要配置所有的屬性,只需要為屬性名和資料庫欄位名不一致的屬性配置對映.屬性名和欄位名一致時會自動完成對映 使用:直接在標籤中通過resultMap屬性引入這裡定義的resultMap //通過id引用 <select id="getUserById" parameterType="int" resultType="USer"> //物件需要寫全類名或別名,別名不區分大小寫 SELECT * FROM `user` WHERE id=#{id123}; //查詢資料庫中指定id的記錄 </select> <select id="getUserById" parameterType="int" resultMap="userResultMap"> //手動對映,實現資料封裝,這裡userResultMap要提前定義 SELECT * FROM `user` WHERE id=#{id123}; </select> <select id="getUserByName" parameterType="string" resultType="cn.itheima.mybatis.po.User"> SELECT * FROM `user` WHERE username LIKE '%${value}%' //模糊查詢 //user的`為轉義符,表示user不為sql關鍵字 </select> 佔位符#{}和拼接符${}的使用: #{}佔位符,不能用在sql語句的引號中(字串中),可防止sql注入 ${}拼接符,用於sql語句字串拼接,放在sql字串中(引號中)使用,不能防止sql注入 佔位符#{}和拼接符${}接收引數的三種情況: //和輸入引數(parameterType)相關 1)輸入引數為基本資料型別:#{}中可隨便寫,${}中只能寫value 2)輸入引數為物件(pojo):#{},${}中寫物件的屬性名,會將引數物件中的屬性值傳入,如#{id},${id} //會將輸入物件的id屬性傳入 3)輸入引數為包裝型別(A): //包裝型別,如物件A中有一個屬性為B物件,則A為B的包裝物件 #{},${}如果想傳入A包裝的B物件中的屬性值,要寫B.屬性名,如#{B.id} ${B.id} //會將輸入包裝物件中的B物件的id屬性傳入 2)增:insert標籤 //增刪改也都有parameterType,resultType,resultMap標籤 <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User"> <selectKey keyProperty="id" resultType="int" order="AFTER"> //實現主鍵返回 SELECT LAST_INSERT_ID() //獲取最後插入記錄的id值 </selectKey> INSERT into user (username,birthday,sex,address) values (#{username}, #{birthday}, #{sex}, #{address}) </insert> 主鍵返回的實現:selectKey //插入到資料庫中後,獲取到記錄的id keyProperty:對應pojo的主鍵屬性 resultType:對應主鍵的資料型別 order:是在insert語句執行之前或者之後。//如果使用uuid做主鍵,應該先生成主鍵然後插入資料,此時應該使用Before //sql獲取uuid: select uuid() 3)刪:delete標籤 <delete id="deleteUser" parameterType="int"> DELETE from user WHERE id=#{id1} </delete> 4)改:update標籤 <update id="updateUser" parameterType="cn.itheima.mybatis.po.User"> //這裡引數為一個物件 update user set username=#{username} WHERE id=#{id} //大括號中為User中的屬性名 </update> 3.程式碼實現增刪改查: 1)建立一個SQLSessionFactoryBuilder物件 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); 2)Resources載入配置檔案,獲取輸入流 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //會在類路徑下查詢檔案 3)獲取sqlSessionFactory物件 sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); //會讀取和解析配置檔案 4)建立SQLSession物件 SqlSession sqlSession = sqlSessionFactory.openSession(); 5)使用SqlSession物件執行增刪改查 6)事務提交 sqlSession.commit(); //增刪改時需要提交事務;預設情況下有事務,但不會自動提交 7)釋放資源 sqlSession.close(); 增刪改查: //對應不同的方法,方法引數均類似,第一個引數對應sql對映檔案中的id,第二個引數為sql需要的引數 查:selectOne() selectList() User user = sqlSession.selectOne("getUserById", 10); //返回一個結果時使用,第一個引數對應sql對映檔案中的id(也可以寫成"名稱空間.id"),第二個引數為sql需要的引數 List<User> list = sqlSession.selectList("getUserByName", ""); //返回多個結果時使用,引數同上 增:insert() sqlSession.insert("insertUser", user); //引數同上;user為一個User物件,需要提前構造出來 刪:delect() sqlSession.delete("deleteUser",2); 改:update() sqlSession.update("updateUser", user); 執行流程:核心配置檔案載入,同時載入對映配置檔案,建立sqlsessionfactory.通過sqlsessionfactory獲取到sqlsession物件,sqlsession呼叫增刪改查方法 4.Mapper動態代理方式開發: 條件: 1)Mapper.xml(sql對映檔案)中的namespace與mapper介面的類全名相同。 2)Mapper介面方法名和Mapper.xml中定義的每個statement的id相同 3)Mapper介面方法的輸入引數型別和mapper.xml中定義的每個sql 的parameterType的型別相同 4)Mapper介面方法的輸出引數型別和mapper.xml中定義的每個sql的resultType的型別相同 5)Mapper介面中所有的方法必須在mapper.xml中都有對應的配置 //mapper.xml中的配置可以沒有對應的方法 滿足以上條件即可完成mapper代理開發 1)編寫SqlMapConfig.xml 2)編寫dao層介面: Public interface UserMapper { public User findUserById(int id) throws Exception; //根據使用者id查詢使用者資訊 public List<User> findUserByUsername(String username) throws Exception; //查詢使用者列表 public void insertUser(User user)throws Exception; //新增使用者資訊 } 3)定義對映檔案mapper.xml: <mapper namespace="cn.itcast.mybatis.mapper.UserMapper"> //namespace值為介面的全類名 <!-- 根據id獲取使用者資訊 --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> //id為方法名,parameterType對應介面中方法引數型別,resultType對應方法返回值 select * from user where id = #{id} </select> <!-- 自定義條件查詢使用者列表 --> <select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> select * from user where username like '%${value}%' </select> <!-- 新增使用者 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="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> </mapper> 4)SqlMapConfig.xml中載入mapper.xml <mappers> <mapper resource="mapper/UserMapper.xml"/> //三種方式,還有采用class配置介面,parkage配置包掃描均可 </mappers> 注意:是否為介面建立代理,和SqlMapConfig.xml載入對映檔案的方式無關,只和對映配置檔案中配置有關,只要滿足所需的五個條件即可 即只要對映檔案被載入且滿足四個條件,框架就能為介面建立代理 5)不需要編寫dao實現類,採用代理呼叫介面方法 //當然也可以使用sqlsession直接實現相應的操作(傳統方式) 1)通過sqlSession的getMapper方法,獲取mapper介面的代理物件 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //這裡的引數為介面的class //此方法呼叫時建立介面的代理物件 2)呼叫代理物件方法 //每一個方法對應對映配置檔案中的一個配置,底層應該也是通過sqlsession實現 User user = userMapper.findUserById(1); 總結:傳統方式開發和mapper代理方式開發的區別:傳統方式開發使用sqlsession直接完成操作,mapper代理方式,首先通過sqlsession獲取mapper代理,通過代理直接呼叫介面中方法實現操作 執行流程:載入核心配置檔案和對映配置檔案,建立sqlsessionfactory,在程式中通過sqlsession呼叫getMapper()方法時,會基於介面建立代理物件,當呼叫代理物件的方法時 會對應的找到對映檔案中的標籤,執行sql 5.mybatis和hibernate的區別 1)hibernate是一個ORM框架,mybatis不是一個完全的ORM框架,需自己編寫sql 2)mybatis相對於hibernate學習門檻低,可直接編寫sql語句,靈活控制sql執行效能。 3)hibernate可以做到資料庫無關性,但mybatis做不到,資料庫變化後需要重新編寫配置檔案 可定義config資料夾存放配置檔案,相當於放在classpath中。定義config的方法:工程--new--source folder--config(定義的包名)
1.動態sql:即動態生成sql語句:
    1)在sql對映檔案中的select標籤中通過<where>、<if>實現動態生成sql
        where標籤:定義條件
        if標籤:基於條件動態生成sql,有test屬性指定條件
        
            <select id="findUserList" parameterType="user" resultType="user">
                select * from user 
                <where>        //標籤中新增條件
                    <if test="id!=null and id!=''">        //test中定義條件,test中的id對應user中的屬性名
                        and id=#{id}    //條件滿足時,拼接的sql語句
                    </if>
                    <if test="username!=null and username!=''">
                        and username like '%${username}%'
                    </if>
                </where>
            </select>
            
            使用where標籤後,會自動處理第一個and關鍵字(自動保留或刪除)

    2)foreach標籤的使用:向sql傳遞陣列或List,如下:
    
        <select id="findUserByIds" parameterType="queryvo" resultType="user">
            SELECT * FROM `user` 
            <where>
                <if test="ids!=null and ids.size>0">     //這裡的ids對應queryvo中的id的list集合名稱。 ids.size獲取到ids集合的大小
                    <foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >    
                        //collection為要遍歷的集合或陣列,ids對應queryvo中的集合名稱
                        //open屬性為生成sql中前面編寫的內容;close為遍歷完後,拼接在sql最後的內容
                        //item為迴圈變數,即每次迴圈得到的值
                        //separator定義間隔符
                        #{id}    //這裡的id對應item的值
                    </foreach>        //迴圈完成後生成的sql:  and id in(1,10,20,21,31) 
                </if>
            </where>
        </select>

    3)sql片段:使用sql標籤將定義的sql片段進行抽取,通過id在需要的地方引用
        抽取:
            <sql id="query_user_where">
                <if test="id!=null and id!=''">
                    and id=#{id}
                </if>
                <if test="username!=null and username!=''">
                    and username like '%${username}%'
                </if>
            </sql>

        引用:採用include標籤引用
            <select id="findUserList" parameterType="user" resultType="user">
                select * from user 
                <where>
                    <include refid="query_user_where"/>    //引用定義好的sql片段
                </where>
            </select>
        
2.一對一關聯對映:association
    當通過sql語句進行關聯查詢時,如order關聯查詢user(一個訂單對應一個使用者),查詢到的資料中有兩個表的資訊。不能直接使用order進行封裝,解決方法:
    
    方法一:,
        1)首先定義pojo,這個pojo包含order和user中的欄位    //可以定義一個類繼承order類,然後在這個類中新增需要的屬性
            public class OrderUser extends Orders {    //這個類中既有orders物件中的屬性,又有user中的username和address,使用這個類封裝關聯查詢結果
                private String username;// 使用者名稱稱
                private String address;// 使用者地址

        2)使用resultType完成。    
            <select id="findOrdersList" resultType="cn.itcast.mybatis.po.OrderUser">    
            
    方法二: 使用resultMap,手動定義對映
        1)在Order中新增User屬性:
            public class Order{
                private Integer id;
                private String number;
                ...
                private User user;    //這個物件用於對映關聯查詢中user表中的欄位
            }    
        2)自定義對映並使用resultMap實現:    //採用association標籤實現關聯表中欄位的對映
            <resultMap type="Orders" id="orderUserResultMap">
                <id column="id" property="id"/>
                <result column="number" property="number"/>
                ...
                <!-- 一對一關聯對映 -->
                <association property="user" javaType="cn.itcast.po.User">    //property:對應Orders物件的user屬性        //javaType:user屬性對應的型別
                    <id column="user_id" property="id"/>    //這裡的property對應關聯的user中的屬性,column為查詢結果的欄位名,下同
                    <result column="username" property="username"/>
                    <result column="address" property="address"/>
                </association>
            </resultMap>
            
            注意:這裡手動配置對映時,需要為每個屬性配置對映,不配置就算屬性名和資料庫欄位名一致,也不能自動完成對映
            
            <select id="findOrdersWithUserResultMap" resultMap="orderUserResultMap">    //resultMap為自定義對映
                SELECT
                    o.id,
                    o.user_id,
                    o.number,
                    o.createtime,
                    o.note,
                    u.username,
                    u.address
                FROM
                    orders o
                JOIN `user` u ON u.id = o.user_id
            </select>
    
3.一對多關聯對映:collection    //通過user關聯查詢order,一個使用者對應多個訂單
    1)在User中新增Order集合的屬性,用於封裝查詢出的訂單資訊:
        public class User(){
            private Integer id;
            private String username;
            ...
            private List<Order> orders;        //集合封裝訂單資訊
        }

    2)對映檔案中使用resultMap,自定義對映完成sql輸出對映:採用collection實現一對多關聯對映
        <resultMap type="user" id="userOrderResultMap">
            <id property="id" column="id"/>
            <result property="username" column="username"/>
            ...
            <collection property="orders" ofType="order">    //一對多關聯對映    //property 為user中的關聯的集合的屬性名    //ofType為集合中元素的型別
                <id property="id" column="oid"/>    //property為order中的屬性,column為表中的列欄位名
                <result property="number" column="number"/>
                <result property="createtime" column="createtime"/>
                <result property="note" column="note"/>
            </collection>
        </resultMap>
        
        注意:和一對一關聯對映時一樣,這裡手動配置對映時,需要為每個屬性配置對映,不配置就算屬性名和資料庫欄位名一致,也不能自動完成對映
        
        <select id="getUserOrderList" resultMap="userOrderResultMap">    //resultMap引用自定義對映
            SELECT
            u.*, o.id oid,
            o.number,
            o.createtime,
            o.note
            FROM
            `user` u
            LEFT JOIN orders o ON u.id = o.user_id
        </select>


4.mybatis和spring整合
    思路:將SqlSessionFactory交給spring管理
        
    1)建工程,導jar包(四個部分):spring的jar包;Mybatis的jar包;Spring+mybatis的整合包;資料庫驅動包和連線池包
    2)mybatis的配置檔案sqlMapConfig.xml
        <configuration>
            <typeAliases>    //配置別名
                <package name="cn.itcast.mybatis.pojo"/>    //不適用別名時可省略
            </typeAliases>
            <mappers>
                <mapper resource="sqlmap/User.xml"/>    //配置對映檔案,applicationContext.xml中配置介面或包掃描時,這裡的配置可省略
            </mappers>
        </configuration>

    3)spring配置檔案:applicationContext.xml sqlSessionFactoryBean的配置
        1)資料庫連線池的配置
            <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
                destroy-method="close">
                <property name="driverClassName" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
                <property name="maxActive" value="10" />
                <property name="maxIdle" value="5" />
            </bean>

        2)sqlSessionFactoryBean的配置    //相當於將sqlsessionfactory交給spring管理
            <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
                <property name="dataSource" ref="dataSource" />        //注入連線池
                <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />    //配置mybatis配置檔案的位置,不需要時可以不配置
            </bean>

    4)dao層的開發(傳統方式和配置mapper代理方式)
        1)傳統的dao開發方式:
            1)定義dao介面和對映檔案        //在sqlMapConfig.xml中需要配置對映檔案
            
            2)讓dao層繼承SqlSessionDaoSupport
                SqlSessionDaoSupport:這個類中封裝了sqlSessionFactory 及其get方法,並提供獲取sqlSession方法
            
                public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {

            3)applicationContext.xml配置dao,並注入sqlSessionFactory
                <bean id="userDao" class="cn.itcast.dao.UserDaoImpl">
                    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>    //會呼叫SqlSessionDaoSupport中的set方法實現注入
                </bean>

            4)dao獲取sqlSession方法:getSqlSession();    //由父類SqlSessionDaoSupport提供
            

        2)Mapper代理形式開發dao        //不需要定義dao實現類
            1)為每一個介面配置代理方式:
                1)定義dao介面,和其對映檔案        //介面和對映檔案必須在同一個目錄下,且名稱必須相同
                
                2)在applicationContext.xml中配置mapper代理:
                    <bean class="org.mybatis.spring.mapper.MapperFactoryBean">
                        <property name="mapperInterface" value="cn.itcast.mybatis.mapper.UserMapper"/>    //指定被代理的介面
                        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>    //注入sqlSessionFactory
                    </bean>

                    注意:UserMapper介面必須和其對映檔案在同一個目錄下,且名稱相同。不需要在sqlMapConfig.xml的mapper標籤中配置對映檔案
                
                    原理:spring配置檔案載入後,會為配置的介面建立代理類,並被spring管理    //這個實現類實際上也會繼承SqlSessionDaoSupport
                    
                3)獲取介面的實現類,呼叫方法
                    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");        //載入spring配置檔案,獲取applicationContext物件
                    UserMapper userMapper = applicationContext.getBean(UserMapper.class);    //獲取spring容器中UserMapper的代理,不需要通過sqlsession獲取
                    User user = userMapper.getUserById(1);    //呼叫方法    
                    
                缺點:需要為每一個介面進行配置
                
                執行流程:spring配置檔案載入時,建立sqlsessionfactoryBean,基於配置的介面掃描與介面在同一目錄下的同名的對映配置檔案,併為介面建立代理,在代理中注入sqlsessionfactory.並將代理交給spring管理
        
            2)掃描包形式配置mapper代理實現dao開發    
                1)在同一個目錄下定義dao介面,和其對映檔案     //也需要介面和對映檔案在同一個目錄下,且名稱必須相同
                2)配置包掃描    //會為配置的包下所有的介面建立代理物件,且不需要注入sqlSessionFactory,spring會自動在容器中找到sqlSessionFactory並自動注入
                    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                        <property name="basePackage" value="cn.itcast.mybatis.mapper"></property>    
                    </bean>
                    
                    注意:生成的代理物件的id為介面名稱,首字母小寫

                    優點:可批量為包中的介面建立代理物件
                
                3)獲取介面的實現類,呼叫方法,同配置介面方式
            
                執行流程:spring配置檔案載入時,建立sqlsessionfactoryBean,根據配置的包,掃描這個包下為介面,基於同一目錄下同名的對映配置檔案,為介面建立代理物件,
                            並在spring容器中獲取到sqlSessionFactory並注入到代理物件,這個代理物件被spring容器管理
            
        注意:傳統的dao開發方式需要在sqlmapconfig.xml中配置對映檔案位置,mapper代理形式開發不需要配置對映檔案,但對映檔案必須和介面同名且在同一個目錄下

5.逆向工程:基於資料庫表,自動生成pojo,介面,實現類
    1)匯入工程:E:\itmeima\上課資料\ssm\01-mybatis\day01\資料\逆向工程\generatorSqlmapCustom
    2)修改generatorConfig.xml中的配置包括:
        mybatis的版本
        連線資料庫的配置
        生成pojo的包
        生成介面的包
        生成對映配置檔案的包
        修改需要操作的資料庫的表
    3)執行GeneratorSqlmap.java中的main方法即可自動生成pojo ,介面,實現類
    
    4)基於自動生成的介面進行開發:
        介面中包含常用的增刪該查的方法:
        
            根據id查詢:
                UserMapper userMapper = applicationContext.getBean(UserMapper.class);
                User user = userMapper.selectByPrimaryKey(10);
            
            通過構造example物件,進行條件查詢:
                UserMapper userMapper = applicationContext.getBean(UserMapper.class);
                UserExample example = new UserExample();
                Criteria criteria = example.createCriteria();    //Criteria為UserExample的內部類;example呼叫createCriteria()時,會將創建出來的Criteria物件儲存
                criteria.andUsernameLike("%張%");
                //執行查詢
                List<User> list = userMapper.selectByExample(example);    //這裡的example封裝了Criteria物件和其中定義的條件
    
                ...
    
            在插入和更新方法中有兩個比較特殊的方法:
                int insertSelective(User record);        //只插入物件中不為空的欄位,為空時使用資料庫預設值
                
                int updateByPrimaryKeySelective(User record);    //只更新物件中不為空的欄位,為空時保留更新之前的值
    
                包含selecttive表示在插入和更新時,只插入和更新物件中不為null的欄位