一.一對多映射.
1.1 一對多映射之根據多的一方關聯查詢一的一方
示例:查詢出具體的訂單信息,同時也查詢出來訂單的用戶信息.
引入的訂單表如下所示:
框選出來的為具體的外鍵.
訂單的Pojo類如下所示:
創建OrdersMapper接口.
書寫ordersMapper.xml.先書寫SQL語句:
SELECT o.id,o.user_id,o.number,u.username,u.sex
FROM ORDERS o,
USER u WHERE o.user_id=u.id;
我們發現,由於查詢出來的一些column無法映射到對應的屬性里面去.因此我們采用resultMap的形式.
查詢出來的u.username,u.sex這些屬性無法直接賦值到column對應的屬性中去.因此,采用<association>標簽去賦值.<association>的<id>屬性標識了關聯對象的id.<result>屬性標識了關聯對象的其他屬性.具體做
法參見注釋.
Mapper的配置如下:
<mapper namespace="com.xyy.mapper.OrdersMapper"> <resultMap type="com.xyy.po.Orders" id="orderResultMap"> <id column="id" property="id"/> <result column="number" property="number"/> <!-- association標識了關聯對象的屬性.property表示屬性名.javaType表示具體的類 --> <association property="user" javaType="com.xyy.po.User"> <!-- 和resultMap的配置方法一樣,property為具體映射的屬性名,column為查詢出來的結果名 --> <id property="id" column="user_id"/> <result property="username" column="username"/> <result property="sex" column="sex"/> </association> </resultMap> <select id="findOrders" resultMap="orderResultMap"> SELECT o.id,o.user_id,o.number,u.username,u.sex FROM ORDERS o, USER u WHERE o.user_id=u.id; </select> </mapper>
測試:
1.2 一對多映射之根據一的一方關聯查詢多的一方
訂單明細是指在商城中下單的時候,可能會購買不同的物品,一個物品可能購買不止一個,那么一個物品項對應的就是一個訂單明細
訂單類和訂單明細類,對應一對多.一個訂單可以有不止一個訂單明細,而一個訂單明細必然屬於一個訂單.
引入訂單明細的表:
引入訂單明細的Pojo類:
需求分析:
查詢所有的訂單,同時關聯查詢出所有的訂單明細.
OrdersMapper類中的對應方法已經有了,我們需要做的就是在Orders類中添加訂單明細的字段:
書寫SQL:
SELECT o.id,o.user_id,o.number,u.username,u.sex,od.id,od.items_num FROM ORDERS o, USER u,orderdetail od WHERE o.user_id=u.id and od.orders_id=o.id;
執行后的查詢結果如下所示:
可以看出orderdetail的id的列名以id1的形式列了出來,這是因為在書寫sql的時候,查詢的id列名與orders表的id列名重復了.解決方法是給orderdetail查詢id的查詢結果起一個別名:detailId
改寫OrdersMapper對應的配置文件..同樣需要配置resultMap.這里用到了新的標簽,<collections>.<collections>可以完成對於集合類型的屬性的映射.具體操作方法如下:
<resultMap type="com.xyy.po.Orders" id="orderResultMap"> <id column="id" property="id"/> <result column="number" property="number"/> <!-- 配置user相關的映射信息 --> <association property="user" javaType="com.xyy.po.User"> <id property="id" column="user_id"/> <result property="username" column="username"/> <result property="sex" column="sex"/> </association> <!-- 配置orderdetails相關的信息 --> <!--collection用於指定集合類型的映射.property指定對應的集合名稱.ofType指定集合中存放的數據的類型 --> <collection property="detailList" ofType="com.xyy.po.Orderdetail"> <!-- id和result指定了需要配置的列和屬性名和映射 --> <id column="detailId" property="id"/> <result column="items_num" property="itemsNum"/> </collection> </resultMap>
這樣就完成了一對多的映射.接下來就可以直接調用指定的方法查詢出對應的結果了:
二.多對多映射
物品(items)和訂單(orders)是多對多映射.兩者實際上是通過OrderDetails中間表完成了關聯.
需求:查詢用戶.同時查詢出用戶所關聯的所有的訂單,同時查詢出訂單所對應的所有的訂單項以及訂單項所對應的物品.
分析表之間的關系:
用戶與訂單是一對多關系.訂單和訂單項是一對多關系.訂單項和物品是一對一的關系.
理清表之間的關系后,就可以去寫Pojo類了:
User類:
Orders類:
OrderDetail類:
Items類:
書寫SQL語句如下.為了方便,為每一個表的主鍵都起了別名:
SELECT u.id uid,u.username, o.id oid,o.number,od.id odid,od.items_num, i.id iid,i.name,i.price FROM user u,orders o,orderdetail od,items i WHERE u.id=o.user_id AND o.id=od.orders_id AND od.items_id=i.id;
書寫Mapper配置文件.根據表與表之間的對應關系,書寫映射關系:
<resultMap type="com.xyy.po.User" id="userManyToManyMap"> <!--配置user --> <id column="uid" property="id"/> <result column="username" property="username"/> <!-- 配置user對應的Orders 一對多 --> <collection property="orders" ofType="com.xyy.po.Orders"> <id column="oid" property="id"/> <result column="number" property="number"/> <!-- 配置orders對應的orderdetail一對多 --> <collection property="detailList" ofType="com.xyy.po.Orderdetail"> <id column="odid" property="id"/> <result column="items_num" property="itemsNum"/> <!-- 配置orderdetail對應的items 一對一--> <association property="items" javaType="com.xyy.po.Items"> <id column="iid" property="id"/> <result column="name" property="name"/> <result column="price" property="price"/> </association> </collection> </collection> </resultMap> <select id="findAllUsers" resultMap="userManyToManyMap"> SELECT u.id uid,u.username, o.id oid,o.number,od.id odid,od.items_num, i.id iid,i.name,i.price FROM user u,orders o,orderdetail od,items i WHERE u.id=o.user_id and o.id=od.orders_id AND od.items_id=i.id; </select>
測試:
三.mybatis整合spring
3.1.搭建環境.
導入jar包,pojo類,導入db.properties配置文件
db.properties如下:
db.driverClass=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8 db.username=root db.password=root
3.2.建立SqlMapConfig.xml.
在剛開始SqlMapConfig.xml中不需要書寫任何信息.(因為數據庫連接信息交給spring去管理了.)
3.3.采用傳統Dao方式開發
3.3.1 建立User.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="test1"> <select id="findUserById" parameterType="int" resultType="com.xyy.po.User"> SELECT * FROM USER WHERE id=#{id} </select> </mapper>
在SqlMapConfig.xml中引入User.xml
3.3.2 .書寫Dao
注意,SqlSessionDaoSupport是由spring提供的便捷操作的類.
3.3.3 建立spring配置文件.
需要配置的包括datasource,sqlSessionFactory和dao
<!-- 引入配置文件 --> <context:property-placeholder location="classpath:db.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${db.driverClass}"></property> <property name="jdbcUrl" value="${db.url}"></property> <property name="user" value="${db.username}"></property> <property name="password" value="${db.password}"></property> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 引入mybatis全局的配置文件 --> <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"></property> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="userDao" class="com.xyy.dao.impl.UserDaoImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean>
3.3.4 測試
@ContextConfiguration("classpath:spring/applicationContext.xml") @RunWith(SpringJUnit4ClassRunner.class) public class testMybatis { @Autowired private UserDao udao; @Test public void testMyBatis() { User user = udao.findUserById(1); System.out.println(user); } }
3.4. 采用mapper代理的方式開發
3.4.1 建立UserMapper接口
3.4.2 建立UserMapper.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"> <!--namespace需要和mapper的全限定名保持一致--> <mapper namespace="com.xyy.mapper.UserMapper"> <select id="findUserById" parameterType="int" resultType="user"> SELECT * FROM USER WHERE id=#{id} </select> </mapper>
3.4.3 書寫applicationContext.xml
配置datasource,sqlsessionfactory與傳統dao幾乎完全一致.需要注意的是,mapper代理開發可以不去書寫mybatis全局配置文件!
此外,我們需要在applicationContext.xml中,去批量生成代理的mapper對象.具體做法如下所示:
3.4.4 測試
@ContextConfiguration("classpath:spring/applicationContext.xml") @RunWith(SpringJUnit4ClassRunner.class) public class testMybatis { @Autowired private UserMapper mapper; @Test public void testMyBatis2() { User user=mapper.findUserById(1); System.out.println(user); } }