欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mybatis映射器配置小結(jié)

 更新時(shí)間:2025年09月02日 11:15:32   作者:_江南一點(diǎn)雨  
本文詳解MyBatis映射器配置,重點(diǎn)講解字段映射的三種解決方案(別名、自動(dòng)駝峰映射、resultMap),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前面三篇博客我們已經(jīng)多次涉及到映射器的使用了,增刪查基本上都用過(guò)一遍了,但是之前我們只是介紹了基本用法,實(shí)際上mybatis中映射器可以配置的地方還是非常多,今天我們就先來(lái)看看映射器還有哪些需要配置的地方,用好這些配置,可以讓我們的mybatis變得非常靈活。

映射器中的元素還是非常多的,比如select、insert、update、delete、parameterMap、sql、resultMap、cache、cache-ref等,本文我們先來(lái)說(shuō)其中比較重要,也是非常常用的幾個(gè)元素。

select中字段的映射問(wèn)題

select元素用來(lái)執(zhí)行一條查詢語(yǔ)句,Select可以算作是最常用,最復(fù)雜的元素之一,我們?cè)谑褂肧elect的時(shí)候可以自定義元素自定義結(jié)果集等,非常靈活,OK,在說(shuō)Select強(qiáng)大的一面之前,我們先來(lái)看看我們?cè)谇懊鎺灼┛椭惺窃趺词褂肧elect的:

<select id="getUser" resultType="user" parameterType="Long">
        select * from user where id = #{id}
    </select>

我們直接從user表中查詢一條數(shù)據(jù)出來(lái),查詢的結(jié)果是一個(gè)user對(duì)象,即mybatis會(huì)自動(dòng)幫我們把查詢的結(jié)果轉(zhuǎn)為一個(gè)user對(duì)象,那么mybatis在轉(zhuǎn)化的過(guò)程中怎么知道數(shù)據(jù)庫(kù)的哪個(gè)字段對(duì)應(yīng)JavaBean中的哪個(gè)屬性呢?很簡(jiǎn)單,只要兩者的名稱一樣,系統(tǒng)就能就能自動(dòng)識(shí)別出來(lái),我們?cè)谇懊娌┛椭性跀?shù)據(jù)庫(kù)中創(chuàng)建的user表的字段分別為id,username,password,address這四個(gè),實(shí)體類的屬性也是這四個(gè)一模一樣,所以系統(tǒng)會(huì)自動(dòng)將查詢結(jié)果給我們轉(zhuǎn)為User對(duì)象,那么在實(shí)際開(kāi)發(fā)中,JavaBean中的屬性命名我們習(xí)慣于駝峰命名法,在數(shù)據(jù)庫(kù)中我們更常用下劃線命名法,比如我現(xiàn)在創(chuàng)建一個(gè)新的實(shí)體類User:

public class User {
    private Long id;
    private String userName;
    private String password;
    private String address;
    //省略getter/setter
}

然后創(chuàng)建一個(gè)user表,如下:

小伙伴們注意這個(gè)表中有一個(gè)字段和實(shí)體類的屬性名稱不一樣,就是數(shù)據(jù)庫(kù)的user_name字段對(duì)應(yīng)了實(shí)體類的userName屬性,這樣的話,在Select查詢結(jié)果中,mybatis就沒(méi)法幫我們自動(dòng)將查詢結(jié)果轉(zhuǎn)為user對(duì)象了。對(duì)于這種非常常見(jiàn)的需求,我們有三種不同的解決方案,分別如下:

使用SQL語(yǔ)句中的別名功能

我們可以在查詢的時(shí)候自動(dòng)將相關(guān)的列名進(jìn)行修改,如下:

<select id="getUser" resultType="u" parameterType="Long">
        select id,user_name as userName,password,address from user2 where id = #{id}
    </select>

使用SQL語(yǔ)句中的別名功能,這樣查詢的結(jié)果實(shí)際又變?yōu)榱薸d、userName、password、address這樣幾個(gè)字段,這樣mybatis就知道哪個(gè)字段對(duì)應(yīng)哪個(gè)屬性了,就能成功轉(zhuǎn)化了。

使用mapUnderscoreToCamelCase屬性

在mybatis的配置文件中,有一個(gè)settings節(jié)點(diǎn),該節(jié)點(diǎn)中都是setting節(jié)點(diǎn),setting節(jié)點(diǎn)有一個(gè)屬性叫做mapUnderscoreToCamelCase,該屬性表示是否開(kāi)啟自動(dòng)駝峰命名規(guī)則映射,即從經(jīng)典的數(shù)據(jù)庫(kù)列名A_COLUMN到經(jīng)典Java屬性名aColumn的映射,這種方式要求我們的數(shù)據(jù)庫(kù)字段命名和JavaBean屬性命名都要非常規(guī)范才能實(shí)現(xiàn)。這個(gè)屬性的開(kāi)啟也是非常容易的,在mybatis的配置文件中,我這里實(shí)在mybatis-conf.xml文件中,添加如下代碼即可 :

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

開(kāi)啟了這個(gè)之后,在Select節(jié)點(diǎn)中我們就不需要使用別名這種方式了,直接像下面這樣寫就行了,如下:

<select id="getUser" resultType="u" parameterType="Long">
        select * from user2 where id = #{id}
    </select>

OK,其實(shí)只要我們?cè)陂_(kāi)發(fā)中遵守命名規(guī)范,這個(gè)問(wèn)題其實(shí)很好解決的。

使用resultMap來(lái)解決

resultMap算是這個(gè)問(wèn)題的一個(gè)終極解決方案了,當(dāng)然resultMap的意義不局限于此,我們這里先說(shuō)resultMap的這個(gè)功能,resultMap可以用來(lái)描述從數(shù)據(jù)庫(kù)結(jié)果集中來(lái)加載對(duì)象,有的時(shí)候映射過(guò)于復(fù)雜,我們可以在Mapper中定義resultMap來(lái)解決映射問(wèn)題,比如還是上面那個(gè)問(wèn)題,我可以在userMapper中這樣來(lái)定義一個(gè)resultMap:

<resultMap id="userMap" type="org.sang.bean.User">
        <id property="id" column="id" javaType="long" jdbcType="NUMERIC"/>
        <result property="userName" column="user_name" javaType="string" jdbcType="VARCHAR"/>
        <result property="password" column="password" javaType="string" jdbcType="VARCHAR"/>
        <result property="address" column="address" javaType="string" jdbcType="VARCHAR"/>
    </resultMap>

關(guān)于這個(gè)resultMap,我說(shuō)如下幾點(diǎn):

1.首先我們給resultMap去了一個(gè)id,這個(gè)id是resultMap的唯一標(biāo)識(shí)符,我們?cè)诤竺嬉眠@個(gè)resultMap的時(shí)候就是通過(guò)這個(gè)id來(lái)引用,然后還定義了type屬性,type屬性指明了這個(gè)resultMap它對(duì)應(yīng)的是哪個(gè)JavaBean。
2.在resultMap節(jié)點(diǎn)中,id表示哪個(gè)字段代表這主鍵,result節(jié)點(diǎn)定義了普通的映射關(guān)系,這里的property表示JavaBean中的屬性名稱,column表示數(shù)據(jù)庫(kù)中的字段名稱,javaType代表JavaBean中該屬性的類型,jdbcType則表示數(shù)據(jù)庫(kù)中該字段的類型,

OK ,如此定義之后,我們只需要在select查詢的時(shí)候指定resultMap即可,如下:

<select id="getUser" resultMap="userMap" parameterType="Long">
        select * from user2 where id = #{id}
    </select>

select多條件查詢

之前我們舉的幾個(gè)例子查詢的時(shí)候都是只有一個(gè)查詢條件,真正開(kāi)發(fā)中多條件查詢也是非常常見(jiàn)的需求,對(duì)于多條件查詢mybatis也給我們提供了相應(yīng)的方式,我們來(lái)看一下:

使用Map集合傳遞參數(shù)

我們可以將參數(shù)裝入Map集合中傳入,使用Map集合傳遞參數(shù)的話需要我在UserMapper接口中定義方法的時(shí)候參數(shù)就先設(shè)置為Map,如下:

public ArrayList<User> getUserByAddressAndName2(Map<String,String> map);

然后在userMapper.xml中將map中的數(shù)據(jù)提取出來(lái):

<select id="getUserByAddressAndName2" resultMap="userMap">
        SELECT * FROM user2 WHERE address=#{address} AND user_name LIKE concat(#{username},'%')
    </select>

提取的方式還是通過(guò)#{XXX},只不過(guò)這里XXX代表map中數(shù)據(jù)的key。然后在使用的時(shí)候組裝map集合數(shù)據(jù),如下:

    @Test
    public void test3() {
        SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            Map<String, String> map = new HashMap<String, String>();
            map.put("address", "長(zhǎng)沙");
            map.put("username", "趙");
            List<User> list = userMapper.getUserByAddressAndName2(map);
            for (User user : list) {
                System.out.println(user);
            }
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

    }

構(gòu)造map傳入即可,但是在開(kāi)發(fā)中一般我們不推薦這種方式,因?yàn)閗ey容易寫錯(cuò),這種方式也不直觀,采用較多的還是后面兩種方式。

使用@Param注解

@Param注解可以把問(wèn)題進(jìn)一步簡(jiǎn)化,如下,首先在UserMapper這個(gè)接口中定義相關(guān)的方法:

public List<User> getUserByAddressAndName(@Param("username") String username, @Param("address") String address);

在數(shù)據(jù)提交的過(guò)程中,mybatis會(huì)以@Param提供的名稱為準(zhǔn),如此,我們?cè)趗serMapper.xml中可以這樣來(lái)定義(注意我們我們不再需要指定參數(shù)類型):

<select id="getUserByAddressAndName" resultMap="userMap">
        SELECT * FROM user2 WHERE address=#{address} AND user_name LIKE concat(#{username},'%')
    </select>

這樣的話參數(shù)的傳遞就更直觀一些,使用方式如下:

@Test
    public void test2() {
        SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            List<User> list = userMapper.getUserByAddressAndName("趙", "長(zhǎng)沙");
            for (User user : list) {
                System.out.println(user);
            }
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

    }

這種方式是我們推薦的一種方式,參數(shù)傳遞很直觀,不必像map那樣還要去考慮key到底是什么。

使用JavaBean

第二種方式按說(shuō)已經(jīng)很完美了,但是還有一種情況就是如果參數(shù)特別多的話,這樣寫起來(lái)也是非常麻煩的一件事,所以mybatis支持我們?cè)趥鲄⒌臅r(shí)候可以直接傳入對(duì)象,傳入對(duì)象的話需要我們先創(chuàng)建對(duì)象類,如下:

public class UserParams {
    private String username;
    private String address;

    //省略getter/setter
}

然后在UserMapper中定義方法,如下:

public ArrayList<User> getUserByAddressAndName3(UserParams params);

最后在userMapper.xml文件中我們直接設(shè)置parameterType為UserParams,然后引用UserParams中的屬性即可,如下:

<select id="getUserByAddressAndName3" resultMap="userMap" parameterType="org.sang.bean.UserParams">
        SELECT * FROM user2 WHERE address=#{address} AND user_name LIKE concat(#{username},'%')
    </select>

使用方式如下:

    @Test
    public void test6() {
        SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            UserParams userParams = new UserParams("趙", "長(zhǎng)沙");
            List<User> list = userMapper.getUserByAddressAndName3(userParams);
            for (User user : list) {
                System.out.println(user);
            }
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

    }

第二種和第三種是我們?cè)陂_(kāi)發(fā)中常用的傳參方式,小伙伴們?cè)陂_(kāi)發(fā)中根據(jù)實(shí)際情況選擇合適的方式即可。

insert中的主鍵回填

可能有小伙伴不理解什么是主鍵回填,我這里簡(jiǎn)單解釋下,比如我們?cè)趧?chuàng)建表的時(shí)候設(shè)置了表的id為自增長(zhǎng)字段,我在Java代碼中存儲(chǔ)一條數(shù)據(jù)時(shí)先構(gòu)建了一個(gè)JavaBean,這個(gè)JavaBean的id屬性是為null,因?yàn)閕d不需要插入到數(shù)據(jù)庫(kù)中去 ,那么當(dāng)我將數(shù)據(jù)插入成功之后系統(tǒng)會(huì)自動(dòng)給該對(duì)象的id屬性賦值,值為剛剛插入那條數(shù)據(jù)的id,這就稱作主鍵回填。這個(gè)在我們開(kāi)發(fā)中也是非常常見(jiàn)的需求,我可能希望知道剛剛插入成功的數(shù)據(jù)的id是多少,而很多時(shí)候id可能都是按照某種既定規(guī)則去生成,我們?cè)诓迦胫安⒉恢獣?,這種時(shí)候就可以使用主鍵回填。實(shí)際上想配置主鍵回填很簡(jiǎn)單,我們先來(lái)看看UserMapper中的方法:

public int insertUser(User user);

這個(gè)方法就是普普通通的UserMapper中的方法,再來(lái)看看userMapper.xml中是怎么定義的:

<insert id="insertUser" parameterType="u" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user2(user_name,password,address) VALUES (#{userName},#{password},#{address})
    </insert>

首先keyProperty屬性指定了哪個(gè)是主鍵字段,useGeneratedKeys的含義則是告訴mybatis這個(gè)主鍵是否使用數(shù)據(jù)庫(kù)內(nèi)置的策略生成,OK,這樣寫了之后,我們?cè)傧驍?shù)據(jù)庫(kù)插入一條數(shù)據(jù),如下:

    @Test
    public void test7() {
        SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            User user = new User(null, "奧巴牛", "123456", "米國(guó)");
            int i = userMapper.insertUser(user);
            System.out.println("i:"+i+";id:"+user.getId());
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

    }

注意,這里的i表示受影響的行數(shù),在這里就是插入的行數(shù),我們?cè)跇?gòu)造User對(duì)象的時(shí)候id是為null,數(shù)據(jù)插入成功之后再來(lái)打印id屬性,我們來(lái)看看結(jié)果:

插入成功之后mybatis已經(jīng)給id屬性賦值了,值即為剛剛插入數(shù)據(jù)。當(dāng)然這種我們是按照數(shù)據(jù)庫(kù)的規(guī)則自動(dòng)生成id,有的時(shí)候生成id的規(guī)則需要我們自定義,當(dāng)然,mybatis也給我們提供了相應(yīng)的方式。

insert中主鍵自定義

假設(shè)有這樣一種需求,當(dāng)我往數(shù)據(jù)庫(kù)中插入一條數(shù)據(jù)的時(shí)候,如果此時(shí)表為空,則這條數(shù)據(jù)的id我設(shè)置為1,如果表不為空,那我找到表中最大的id,然后給其加2作為即將添加數(shù)據(jù)的id,這種也算是較常見(jiàn)的需求,我們來(lái)看看怎么實(shí)現(xiàn)吧。
先在UserMapper中定義相關(guān)方法:

public int insertUser2(User user);

這個(gè)方法很普通,沒(méi)啥特殊的地方,然后在userMapper.xml中定義insert節(jié)點(diǎn),如下:

<insert id="insertUser2" parameterType="u" useGeneratedKeys="true" keyProperty="id">
      <selectKey keyProperty="id" resultType="long" order="BEFORE">
          SELECT if(max(id) is null,1,max(id)+2) as newId FROM user3
      </selectKey>
        INSERT INTO user3(id,user_name,password,address) VALUES (#{id},#{userName},#{password},#{address})
    </insert>

這里我們使用了selectKey來(lái)進(jìn)行了簡(jiǎn)單的處理。selectKey中的keyProperty屬性表示selectKey中的sql語(yǔ)句的查詢結(jié)果應(yīng)該被設(shè)置的目標(biāo)屬性,我們這里當(dāng)然是要設(shè)置為id了,然后我在下文好使用這個(gè)id,selectKey的resultType屬性表示查詢結(jié)果的返回類型,注意這個(gè)類型要和User類中id的類型一致,selectKey中的order=”BEFORE”表示在插入操作之前選擇主鍵,order的另一個(gè)取值A(chǔ)FTER表示執(zhí)行完插入操作之后再選擇主鍵,關(guān)于這一塊小伙伴可以參考這篇博客Mybatis 示例之 SelectKey 。OK,最后我們來(lái)看看調(diào)用:

    @Test
    public void test8() {
        SqlSession sqlSession = null;
        try {
            sqlSession = DBUtils.openSqlSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            User user = new User(null, "米歇爾", "222222", "米國(guó)");
            int i = userMapper.insertUser2(user);
            System.out.println("i:"+i+";id:"+user.getId());
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

    }

OK,以上就是select和insert的一些配置細(xì)則,剩下的update和delete和這兩個(gè)差不多,我就不再贅述。

本文案例下載:
本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test27-mybatis5。

到此這篇關(guān)于mybatis映射器配置小結(jié)的文章就介紹到這了,更多相關(guān)mybatis映射器配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Spring Cloud微服務(wù)架構(gòu)下的WebSocket解決方案

    詳解Spring Cloud微服務(wù)架構(gòu)下的WebSocket解決方案

    這篇文章主要介紹了詳解Spring Cloud微服務(wù)架構(gòu)下的WebSocket解決方案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • 淺析java中Integer傳參方式的問(wèn)題

    淺析java中Integer傳參方式的問(wèn)題

    以下是對(duì)java中Integer傳參方式的問(wèn)題進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-09-09
  • Eclipse?Jetty?server漏洞解決辦法

    Eclipse?Jetty?server漏洞解決辦法

    最近給?個(gè)客戶部署項(xiàng)?,但是客戶的安全稽核有點(diǎn)變態(tài),居然說(shuō) Eclipse Jetty Server?危漏洞,這篇文章主要給大家介紹了關(guān)于Eclipse?Jetty?server漏洞解決的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java中replace與replaceAll的區(qū)別與測(cè)試

    Java中replace與replaceAll的區(qū)別與測(cè)試

    replace和replaceAll是JAVA中常用的替換字符的方法,下面這篇文章主要給大家介紹了關(guān)于Java中replace與replaceAll的區(qū)別與測(cè)試,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • java策略枚舉:消除在項(xiàng)目里大批量使用if-else的優(yōu)雅姿勢(shì)

    java策略枚舉:消除在項(xiàng)目里大批量使用if-else的優(yōu)雅姿勢(shì)

    這篇文章主要給大家介紹了關(guān)于Java徹底消滅if-else的8種方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2021-06-06
  • MyBatis執(zhí)行SQL的兩種方式小結(jié)

    MyBatis執(zhí)行SQL的兩種方式小結(jié)

    本文主要介紹了MyBatis執(zhí)行SQL的兩種方式小結(jié),主要包括SqlSession 發(fā)送SQL和SqlSession獲取Mapper接口,通過(guò)Mapper接口發(fā)送SQL,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • SpringBoot?Web依賴教程

    SpringBoot?Web依賴教程

    這篇文章主要介紹了SpringBoot?Web依賴教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • SpringCloud及Nacos服務(wù)注冊(cè)IP選擇問(wèn)題解決方法

    SpringCloud及Nacos服務(wù)注冊(cè)IP選擇問(wèn)題解決方法

    這篇文章主要介紹了SpringCloud及Nacos服務(wù)注冊(cè)IP選擇問(wèn)題,為什么注冊(cè)的IP和真實(shí)IP不符合呢,原因是Nacos客戶端在注冊(cè)服務(wù)時(shí)會(huì)從機(jī)器網(wǎng)卡中選擇一個(gè)IP來(lái)注冊(cè),所以,當(dāng)注冊(cè)了的是非真實(shí)IP后,另一臺(tái)機(jī)器調(diào)用時(shí)是不可能調(diào)通的,知道問(wèn)題原因就是解決方法,一起看看吧
    2024-01-01
  • Java Volatile關(guān)鍵字你真的了解嗎

    Java Volatile關(guān)鍵字你真的了解嗎

    這篇文章主要為大家介紹了Java Volatile關(guān)鍵字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • druid ParserException類錯(cuò)誤問(wèn)題及解決

    druid ParserException類錯(cuò)誤問(wèn)題及解決

    這篇文章主要介紹了druid ParserException類錯(cuò)誤問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評(píng)論