1. 程式人生 > 實用技巧 >mybatis(二)

mybatis(二)

目錄:

1、資料模型分析

  1)明確每張表儲存的資訊
  2)明確每張表中關鍵欄位(主鍵、外來鍵、非空)
  3)明確資料庫中表與表之間的外來鍵關係
  4)明確業務中表與表的關係(建立在具體的業務)

2、一對一對映(結果型別使用resultType)

  需求:查詢訂單資訊,關聯查詢使用者資訊(主資訊:訂單資訊,從資訊:使用者資訊)

    主資訊:orders表 從資訊:user表

  sql 指令碼

create database db_mybatis_01 default character set utf8;
use db_mybatis_01;

------------ user ------------
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) NOT NULL COMMENT '使用者名稱稱', `birthday` date DEFAULT NULL COMMENT '生日', `sex` char(1) DEFAULT NULL COMMENT '性別', `address` varchar(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=
27 DEFAULT CHARSET=utf8; insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'王五',NULL,'2',NULL), (2,'張三','2014-07-10','1','北京市'), (3,'張小明',NULL,'1','河南鄭州'), (4,'陳小明',NULL,'1','河南鄭州'), (5,'張三丰',NULL,'1','河南鄭州'), (6,'陳小明',NULL,'1','河南鄭州'), (7,'王五',NULL,NULL,NULL); ------------ orders ------------
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 ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; insert into `orders`(`id`,`user_id`,`number`,`createtime`,`note`) values (3,1,'1000010','2015-02-04 13:22:35',NULL), (4,1,'1000011','2015-02-03 13:22:41',NULL), (5,2,'1000012','2015-02-12 16:13:23',NULL);
View Code

  實體類 User

public class User {
    private int id;
    private String username; // 使用者名稱
    private Date birthday; // 生日
    private String sex; // 性別
    private String address; // 地址
    // getXxx和setXxx
}

  實體類 Orders

public class Orders {
    private Integer id;
    private Integer userId; // 下單使用者id
    private String number; // 訂單號
    private Date createtime; // 建立訂單時間
    private String note; // 備註
    // getXxx和setXxx
}

  訂單擴充套件類 OrdersExt

public class OrdersExt extends Orders {
    private String username;
    private String sex;
    // getter和setter方法
}

  db.properties

db.driver=com.mysql.jdbc.Driver
db.url=jdbc\:mysql\://localhost\:3306/db_mybatis_01?useUnicode\=true&characterEncoding\=utf8
db.username=root
db.password=

  log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

  mybatis全域性配置檔案 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>
    <!-- 載入properties檔案或者宣告屬性資訊 <property name="db.username" value="123" /> -->
    <properties resource="db.properties">
    </properties>

    <!-- <settings></settings> -->

    <!-- 自定義別名 -->
    <typeAliases>
        <!-- 單個別名定義 -->
        <!-- <typeAlias type="com.oy.mybatis.po.User" alias="user"/> -->

        <!-- 批量別名定義(推薦) -->
        <!-- package:指定包名稱來為該包下的po類宣告別名,預設的別名就是類名(首字母大小寫都可) -->
        <package name="com.oy.domain" />
    </typeAliases>

    <!-- 配置mybatis的環境資訊,與spring整合後,該資訊由spring來管理 -->
    <environments default="development">
        <environment id="development">
            <!-- 配置JDBC事務控制,由mybatis進行管理 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置資料來源,採用mybatis連線池 -->
            <dataSource type="POOLED">
                <property name="driver" value="${db.driver}" />
                <property name="url" value="${db.url}" />
                <property name="username" value="${db.username}" />
                <property name="password" value="${db.password}" />
            </dataSource>
        </environment>
    </environments>

    <!-- 載入對映檔案 -->
    <mappers>
        <mapper resource="OrdersMapper.xml"/>

        <!-- 批量載入對映檔案 -->
        <!-- <package name="com.oy.mybatis.mapper" /> -->
    </mappers>
</configuration>

  OrdersMapper

public interface OrdersMapper {
    public List<OrdersExt> findOrdersAndUser();
}

  OrdersMapper.xml

<?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.oy.mapper.OrdersMapper">

    <select id="findOrdersAndUser" resultType="com.oy.domain.OrdersExt">
        SELECT 
        orders.`id`,orders.`user_id` userId,orders.`number`,
        user.`username`,user.`sex` 
        FROM orders,user 
        WHERE orders.`user_id` = user.`id`
    </select>

</mapper>

  測試類

package com.oy.test;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import com.oy.domain.OrdersExt;
import com.oy.mapper.OrdersMapper;

public class Test1 {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void testFindOrdersAndUser() throws Exception {
        // 建立OrdersMapper物件
        SqlSession sqlSession = sqlSessionFactory.openSession();
        OrdersMapper mapper = sqlSession.getMapper(OrdersMapper.class);

        List<OrdersExt> orderExtList = mapper.findOrdersAndUser();
        for (OrdersExt o : orderExtList) {
            System.out.println(o.getId() + "--" + o.getUserId() + "--" + o.getNumber() 
            + "--" + o.getUsername() + "--" + o.getSex());
        }
        
        sqlSession.close();
    }
}

  注意:由於實體類Orders中屬性userId對應表列名為user_id,所以sql語句中使用了別名。
  也可以通過定義resultMap來實現上面的問題:實體類Orders中屬性userId對應表列名為user_id。

<resultMap type="com.oy.domain.OrdersExt" id="RstMap">   
    <id column="id" property="id"/>   
    <id column="user_id" property="userId"/>  
    <id column="number" property="number"/>  
    <id column="username" property="username"/>
    <id column="sex" property="sex"/>
</resultMap>

<select id="findOrdersAndUser" resultMap="RstMap">
    SELECT 
    orders.`id`,orders.`user_id`,orders.`number`,
    user.`username`,user.`sex` 
    FROM orders,user 
    WHERE orders.`user_id` = user.`id`
</select>

3、一對一對映(使用resultMap)---對上個案例的補充

  擴充套件類

public class OrdersExt extends orders{
    private User user;
    //getter和setter方法
}

  對映檔案OrdersMapper.xml

<resultMap type="com.oy.domain.OrdersExt" id="RstMap">   
    <id column="id" property="id"/>   
    <result column="user_id" property="userId"/>  
    <result column="number" property="number"/>  
    <result column="username" property="user.username"/>
    <result column="sex" property="user.sex"/>
</resultMap>

<select id="findOrdersAndUser" resultMap="RstMap">
    SELECT 
    orders.`id`,orders.`user_id`,orders.`number`,
    user.`username`,user.`sex` 
    FROM orders,user 
    WHERE orders.`user_id` = user.`id`
</select>

  另外,也可以使用<association>來實現一對一對映

<resultMap type="com.oy.domain.OrdersExt" id="RstMap">   
    <id column="id" property="id"/>   
    <result column="user_id" property="userId"/>  
    <result column="number" property="number"/>  
    <!--使用者資訊(一對一)-->
    <association property="user" javaType="com.oy.domain.User">
        <id column="user_id" property="id"/>   //不寫不會報錯,但是會影響效能
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
    </association>
</resultMap>

<select id="findOrdersAndUser" resultMap="RstMap">
    SELECT 
    orders.`id`,orders.`user_id`,orders.`number`,
    user.`username`,user.`sex` 
    FROM orders,user 
    WHERE orders.`user_id` = user.`id`
</select>

4、一對多對映

  需求:查詢使用者資訊,關聯查詢訂單資訊(一個使用者有多個訂單,所以是一對多)

  擴充套件類

public class UserExt extends User{
    private List<Orders> orderList;
    //getter和setter方法
}

  對映檔案

<!-- 查詢所有使用者 -->
<resultMap type="com.oy.domain.UserExt" id="userExtRst">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="birthday" property="birthday"/>
    <result column="sex" property="sex"/>
    <result column="address" property="address"/>
    
    <collection property="orderList" ofType="com.oy.domain.Orders">
        <id column="ordersId" property="id"/>
        <result column="createtime" property="createtime"/>
        <result column="number" property="number"/>
    </collection>
</resultMap>

<select id="findAll" resultMap="userExtRst">
    select user.id,user.username,user.birthday,user.sex,user.address,
    orders.id ordersId,orders.createtime,orders.number
    from user,orders
    where user.id=orders.user_id
</select>

---