1. 程式人生 > >Mybatis詳解(二)

Mybatis詳解(二)

Mybatis

Mybatis對映檔案

MyBatis 的真正強大在於它的對映語句,對映器的 XML 檔案相對簡單。如果拿它跟JDBC 程式碼進行對比,你會立即發現省掉了將近 95% 的程式碼。MyBatis 就是針對 SQL 構建的,並且比普通的方法做的更好。

SQL 對映檔案有很少的幾個頂級元素(按照它們應該被定義的順序):

cache – 給定名稱空間的快取配置。
cache-ref – 其他名稱空間快取配置的引用。
resultMap – 是最複雜也是最強大的元素,用來描述如何從資料庫結果集中來載入物件。
sql – 可被其他語句引用的可重用語句塊。
insert – 對映插入語句
update – 對映更新語句
delete – 對映刪除語句
select – 對映查詢語句 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

select

select 元素有很多屬性允許你配置,來決定每條語句的作用細節。

這裡寫圖片描述

insert, update 和 delete

這裡寫圖片描述

insert詳解

插入語句的配置規則非常豐富,在插入語句裡面有一些額外的屬性和子元素用來處理主鍵的生成,而且有多種生成方式,我們來詳細說明一下。

1.首先,如果你的資料庫支援自動生成主鍵的欄位,那麼你可以設定 useGeneratedKeys=”true”,然後再把 keyProperty 設定到目標屬性上就OK。這樣當我們插入之後,我們的物件會自動設定資料庫返回的主鍵。 

<insert id="insertUser" parameterType="com.cad.domain.User" useGeneratedKeys="true" keyProperty="id">
    insert into user(username,birthday,sex,address) values(#{username}
,#{birthday},#{sex},#{address}) </insert>
  • 1
  • 2
  • 3
  • 4
  • 5
2.如果你的資料庫還支援多行插入, 你也可以傳入一個Authors陣列或集合,並返回自動生成的主鍵。 

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="AuthorList" separator=","
> (#{item.username}, #{item.password}, #{item.email}, #{item.bio}) </foreach> </insert>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

sql

這個元素可以被用來定義可重用的 SQL 程式碼段,可以包含在其他語句中。它可以被靜態地(在載入引數) 引數化. 不同的屬性值通過包含的例項變化.

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  from some_table t1
    cross join some_table t2
</select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

parameterType(輸入型別)

我們傳入的引數可以是簡單資料型別,或者物件,前一天我們已經演示過,這裡有一個點需要注意。

預設情況下,使用#{}格式的語法會導致 MyBatis 建立預處理語句屬性並安全地設定值。這樣做更安全,更迅速,通常也是首選做法,不過有時你只是想直接在 SQL 語句中插入一個不改變的字串。比如,:ORDER BY ${columnName}。這裡 MyBatis 不會修改或轉義字串。以這種方式接受從使用者輸出的內容並提供給語句中不變的字串是不安全的,會導致潛在的 SQL 注入攻擊,因此要麼不允許使用者輸入這些欄位,要麼自行轉義並檢驗。

resultMap

resultType可以指定將查詢結果對映為pojo,但需要pojo的屬性名和sql查詢的列名一致方可對映成功。如果sql查詢欄位名和pojo的屬性名不一致,可以通過resultMap將欄位名和屬性名作一個對應關係 ,resultMap實質上還需要將查詢結果對映到pojo物件中。resultMap可以實現將查詢結果對映為複雜型別的pojo,比如在查詢結果對映物件中包括pojo和list實現一對一查詢和一對多查詢。

例如:當我們使用resultType時

<select id="selectUsers" resultType="User">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select> 

其實MyBatis會自動建立一個 ResultMap,基於資料庫屬性名來對映列到 JavaBean 的屬性上,所以必須得保證資料庫欄位名和JavaBean屬性一致。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
如果列名沒有精確匹配,你可以在列名上使用 select 字句的別名(一個 基本的 SQL 特性)來匹配屬性。

<select id="selectUsers" resultType="User">
  select
    user_id             as "id",
    user_name           as "userName",
    hashed_password     as "hashedPassword"
  from some_table
  where id = #{id}
</select> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
但是,Mybatis給我們提供了簡便強大的resultMap
例如,我們的實體類user_sex和資料庫欄位sex不匹配

public class User implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String username;// 使用者姓名
    private String user_sex;// 性別
    private Date birthday;// 生日
    private String address;// 地址
}  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

    <!--type為返回型別-->
    <resultMap type="com.cad.domain.User" id="userResultMap">
        <!--property為屬性,column為對應的資料庫欄位,這樣再查詢就能匹配上-->
        <result property="user_sex" column="sex" />
    </resultMap>

    <select id="findUserById" parameterType="int" resultMap="userResultMap">
        select * from user where id =#{id}
    </select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

快取

MyBatis 包含一個非常強大的查詢快取特性,它可以非常方便地配置和定製。MyBatis 3 中的快取實現的很多改進都已經實現了,使得它更加強大而且易於配置。

預設情況下是沒有開啟快取的,除了區域性的 session 快取,可以增強變現而且處理迴圈 依賴也是必須的。要開啟二級快取,你需要在你的 SQL 對映檔案中新增一行

<cache/>  
  • 1

這個簡單的一行有如下的功能:

  • 對映語句檔案中的所有 select 語句將會被快取。
  • 對映語句檔案中的所有 insert,update 和 delete 語句會重新整理快取。
  • 快取會使用 Least Recently Used(LRU,最近最少使用的)演算法來收回。
  • 根據時間表(比如 no Flush Interval,沒有重新整理間隔), 快取不會以任何時間順序 來重新整理。
  • 快取會儲存列表集合或物件(無論查詢方法返回什麼)的 1024 個引用。
  • 快取會被視為是 read/write(可讀/可寫)的快取,意味著物件檢索不是共享的,而 且可以安全地被呼叫者修改,而不干擾其他呼叫者或執行緒所做的潛在修改。

快取有一些屬性:

  • eviction:收回策略,四個值:LRU ,FIFO,SOFT ,WEAK

  • lushInterval(重新整理間隔):可以被設定為任意的正整數,而且它們代表一個合理的毫秒 形式的時間段。預設情況是不設定,也就是沒有重新整理間隔,快取僅僅呼叫語句時重新整理。

  • size(引用數目):可以被設定為任意正整數,要記住你快取的物件數目和你執行環境的 可用記憶體資源數目。預設值是 1024。

  • readOnly(只讀):屬性可以被設定為 true 或 false。只讀的快取會給所有呼叫者返回緩 存物件的相同例項。因此這些物件不能被修改。這提供了很重要的效能優勢。可讀寫的快取 會返回快取物件的拷貝(通過序列化) 。這會慢一些,但是安全,因此預設是 false。

Mybatis還可以自定義快取,可以自行去參考文件。

動態sql

MyBatis 的強大特性之一便是它的動態 SQL。我們使用JDBC時會手動拼接條件,Mybatis解決了這一情況。

if標籤

動態 SQL 通常要做的事情是有條件地包含 where 子句的一部分。

    <!--根據id和姓名查詢使用者-->
    <select id="findUserByIdAndUsername" parameterType="com.cad.domain.User" resultType="com.cad.domain.User">
        select * from user 
        where 1=1
        <if test="id !=null and id!=''">
            and id=#{id}
        </if>
        <if test="username !=null and username !=''">
            and username =#{username}
        </if>
    </select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
public class MybatisTest {

    @Test
    public void test() throws IOException {
        String resource="config/sqlMapConfig.xml";

        InputStream in=Resources.getResourceAsStream(resource);
        SqlSessionFactoryBuilder builder= new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(in);
        SqlSession sqlSession=factory.openSession();  
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);  
        User user=new User();
        user.setId(10);
        user.setUsername("張三");
        List<User> list=userMapper.findUserByIdAndUsername(user);
        for(User u:list) {
            System.out.println(u);
        }
    } 

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

choose, when, otherwise標籤

有些時候,我們不想用到所有的條件語句,而只想從中選擇。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。

例如:提供了“id”就按“id”查詢,提供了“username”就按“username”查詢,若兩者都沒有提供,就按照otherwise裡面的條件查詢*。其實是蠻雞肋的一功能。

    <!-- 根據id和名字查詢使用者 -->
    <select id="findUserByIdAndUsername" parameterType="com.cad.domain.User" resultType="com.cad.domain.User">
        select * from user 
        where 1=1
        <choose>
            <when test="id != null">
              AND id = #{id}
            </when>
            <when test="username != null and username !=''">
              AND username = #{username}
            </when>
            <otherwise>
              AND sex = 1
            </otherwise>        
        </choose>
    </select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

where標籤

上面的例子我們都需要寫where 1=1,因為如果不寫,條件拼接就會出現很多錯誤,Mybatis通過where標籤幫我們解決了這個問題。

    <select id="findUserByIdAndUsername" parameterType="com.cad.domain.User" resultType="com.cad.domain.User">
        select * from user 
        <where>
            <if test="id != null">
              AND id = #{id}
            </if>
            <if test="username != null and username !=''">
              AND username = #{username}
            </if>   
        </where>
    </select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

foreach標籤

動態 SQL 的另外一個常用的必要操作是需要對一個集合進行遍歷,通常是在構建 IN 條件語句的時候。

//建立一個物件,封裝一個ids
public class QueryVo {
    private List<Integer> ids;

    public List<Integer> getIds() {
        return ids;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
    <!-- 根據多個id查詢使用者資訊 -->
    <select id="findUserByIds" parameterType="com.cad.domain.QueryVo"  resultType="com.cad.domain.User"> 
        select * from user 
        where id in
        <!--如果集合是物件封裝起來的,可以直接使用屬性名字。-->
        <foreach collection="ids" item="item" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
public class MybatisTest {

    @Test
    public void test() throws IOException {
        String resource="config/sqlMapConfig.xml";

        InputStream in=Resources.getResourceAsStream(resource);
        SqlSessionFactoryBuilder builder= new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(in);
        SqlSession sqlSession=factory.openSession();  
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);   
        List<Integer> l=new ArrayList<Integer>();
        l.add(10);
        l.add(16);
        l.add(22);
        QueryVo queryVo=new QueryVo();
        queryVo.setIds(l);
        List<User> list=userMapper.findUserByIds(queryVo);
        for(User u:list) {
            System.out.println(u);
        }
    } 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

如果我們的list在某個物件內部,那麼foreach時,collection可以直接使用list名字。如果我們直接new了一個數組或者list集合,collection屬性必須使用array或者list,這樣才能遍歷到。

關聯查詢

前面我們講了將簡單的資料對映到物件中,可惜實際工作中的任務不總是這麼簡單,往往多個物件之間存在著各種關聯關係,我們來看看使用Mybatis怎麼處理。我們還是需要使用到resultMap

一對一對映

1.我們建立Order表與User表關聯 

CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '下單使用者id',
  `number` varchar(32) NOT NULL COMMENT '訂單號',
  `createtime` datetime NOT NULL COMMENT '建立訂單時間',
  `note` varchar(100) DEFAULT NULL COMMENT '備註',
  PRIMARY KEY (`id`),
  KEY `FK_orders_1` (`user_id`),
  CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ;


INSERT INTO `orders` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);
INSERT INTO `orders` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);
INSERT INTO `orders` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
2.建立對應的實體類  

public class Orders  implements Serializable{

    private static final long serialVersionUID = 1L;

    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;

    private User user;


    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number == null ? null : number.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note == null ? null : note.trim();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
3.編寫對映檔案 

<mapper namespace="com.cad.domain.OrdersMapper"> 
    <resultMap type="com.cad.domain.Orders" id="orders"> 
        <!--只會對映指定的欄位,其他未顯式指定的都為null-->
        <id property="id" column="id"/>
        <result property="userId" column="user_id"/>
        <result property="number" column="number"/>
        <!--用association表示關聯的物件,property為屬性名,javaType為型別-->
        <association property="user" javaType="com.cad.domain.User">
            <id column="user_id" property="id"/>
            <result property="username" column="username"/>
        </association>
    </resultMap>

    <select id="findOrders" resultMap="orders">
        SELECT * FROM orders LEFT JOIN USER ON orders.user_id=user.id
    </select>
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
4.編寫Mapper介面,將對映檔案新增到核心配置檔案中,然後測試 

public class MybatisTest {

    @Test
    public void test() throws IOException {
        String resource="config/sqlMapConfig.xml";

        InputStream in=Resources.getResourceAsStream(resource);
        SqlSessionFactoryBuilder builder= new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(in);
        SqlSession sqlSession=factory.openSession();  
        OrdersMapper mapper=sqlSession.getMapper(OrdersMapper.class); 
        List<Orders> list=mapper.findOrders();
        for(Orders o:list) {
            System.out.println("order:"+o.toString());
            System.out.println("user:"+o.getUser().toString());
        }
    } 

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

一對多關聯

1.我們在user實體類中新增orders欄位

public class User implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String username;// 使用者姓名
    private String sex;// 性別
    private Date birthday;// 生日
    private String address;// 地址
    private List<Orders> orders;



    public List<Orders> getOrders() {
        return orders;
    }
    public void setOrders(List<Orders> orders) {
        this.orders = orders;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }


    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex
                + ", birthday=" + birthday + ", address=" + address + ",orders"+orders+"]";
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
2.配置對映檔案 

    <resultMap type="com.cad.domain.User" id="users">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <!--這裡使用ofType指定集合內部儲存物件的型別-->
        <collection property="orders" ofType="com.cad.domain.Orders">
            <id column="oid" property="id"/>
            <result property="number" column="number"/>
        </collection>
    </resultMap>
    <select id="findUserOrders" resultMap="users">
        SELECT u.*,o.id oid,o.number FROM  user u LEFT JOIN orders o ON o.user_id=u.id
    </select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
3.將方法新增到mapper介面中,我們測試一下 
public class MybatisTest {

    @Test
    public void test() throws IOException {
        String resource="config/sqlMapConfig.xml";

        InputStream in=Resources.getResourceAsStream(resource);
        SqlSessionFactoryBuilder builder= new SqlSessionFactoryBuilder();
        SqlSessionFactory factory=builder.build(in);
        SqlSession sqlSession=factory.openSession();  
        OrdersMapper mapper=sqlSession.getMapper(OrdersMapper.class); 
        List<User> list=mapper.findUserOrders();
        for(User u:list) {
            System.out.println("user:"+u.toString());

        }
    } 

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

Mybatis整合Spring

1.建立空專案,匯入jar包 ,mybtias-spring.jar很重要,可以去maven下載
  • 1
  • 2

這裡寫圖片描述

2.建立SqlMapConfig.xml配置檔案 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <mappers>
        <!--對映該包下的所有對映檔案-->
        <package name="com.cad.mapper"/>
    </mappers>
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
3.建立Mapper介面和Mapper對映檔案  

public interface UserMapper {
    public List<User> findUsers();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
<?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.cad.mapper.UserMapper">
    <select id="findUsers" resultType="com.cad.domain.User">
        select * from user
    </select>
</mapper>   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
4.建立Spring配置檔案applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

<!-- 配置資料庫連線池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"></property>
    <property name="user" value="root"></property>
    <property name="password" value="123456"></property>
</bean> 
<!-- 配置sqlSession工廠 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 配置核心配置檔案 -->
    <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
    <!-- 配置資料來源 -->
    <property name="dataSource" ref="dataSource"></property>
</bean>  

<!-- 配置介面,幫我們生成代理實現類 -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <!--傳入工廠和介面-->
    <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    <property name="mapperInterface" value="com.cad.mapper.UserMapper"></property>
</bean>

</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
5.測試一下 

public class TestDemo {

    @Test
    public void test() {
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        //獲取介面實現類
        UserMapper mapper=(UserMapper)applicationContext.getBean("userMapper");
        List<User> list=mapper.findUsers();
        for(User user:list) {
            System.out.println(user.toString());
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

上面的整合看似簡便了不少,但是有一個嚴重的問題。我們每多一個Mapper介面,就得需要在Spring配置檔案中多加一個配置,這是一個很繁瑣並且工作量很大的工作,Mybatis為我們提供了一個掃描包的功能,可以直接將該包下的介面建立實現類。

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

<!-- 配置資料庫連線池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"></property>
    <property name="user" value="root"></property>
    <property name="password" value="123456"></property>
</bean> 
<!-- 配置sqlSession工廠 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 配置核心配置檔案 -->
    <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
    <!-- 配置資料來源 -->
    <property name="dataSource" ref="dataSource"></property>
</bean> 

<!--配置掃描方式,建立代理類,不用配置id,每個代理類的id就是介面名,首字母小寫-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--配置包-->
    <property name="basePackage" value="com.cad.mapper"/>
</bean>

</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

Mybatis逆向工程

我們實際開發中,動輒上