mybatis關系映射之一對多和多對一
本實例使用用戶和訂單的例子做說明: 一個用戶可以有多個訂單, 一個訂單只對應一個用戶。(其中應用到注釋)
1.代碼的結構

2. 建表語句:
CREATE DATABASE test;
USE test;
CREATE TABLE person(
personId VARCHAR(36) PRIMARY KEY,
personName VARCHAR(64),
personAddress VARCHAR(128),
personTel VARCHAR(11)
);
CREATE TABLE orders(
orderId VARCHAR(36) PRIMARY KEY,
orderNumber VARCHAR(20),
orderPrice INT,
pid VARCHAR(36)
);
INSERT INTO person VALUES('1', '木子', '湖北', '110');
INSERT INTO person VALUES('2', '木子大大', '武漢', '120');
INSERT INTO person VALUES('1', '木子苗苗', '天門', '119');
INSERT INTO orders VALUES('1', '001', 100, '1');
INSERT INTO orders VALUES('2', '002', 200, '1');
INSERT INTO orders VALUES('3', '003', 300, '2');
INSERT INTO orders VALUES('4', '004', 400, '2');
INSERT INTO orders VALUES('5', '005', 500, '3');
SELECT p.*, o.* FROM person p JOIN orders o ON (p.personId=o.pid) WHERE p.personId = '1' ;
*指顯示所有字段
3. 用戶實體:
package com.mybatis.domain;
import java.util.List;
import lombok.Data;
@Data//注釋(Person為單方)
public class Person {
private String personid;
private String personname;
private String personaddress;
private String persontel;
//這個代表多方里面的內容(Orders)
private List<Orders> orders;
@Override
public String toString() {
return "Person [personid=" + personid + ", personname=" + personname
+ ", personaddress=" + personaddress + ", persontel="
+ persontel + ", orders=" + orders + "]";
}
}
4. 訂單實體:
package com.mybatis.domain;
import lombok.Data;
@Data//(Orders為多方)
public class Orders {
private String orderid;
private String ordernumber;
private Integer orderprice;
//對象(單方Person)與外鍵進行關聯(lián)
private Person person;
}
5.寫PersonMapper.java的接口
package com.mybatis.dao.mapper;
import com.mybatis.domain.Orders;
import com.mybatis.domain.Person;
import java.util.List;
public interface PersonMapper {
int deleteByPrimaryKey(String personid);
int insert(Person record);
Person selectByPrimaryKey(String personid);
List<Person> selectAll();
int updateByPrimaryKey(Person record);
//一對多查詢(根據id查詢)
public List<Orders> findPersonAndOrders(String pid);
//一對多查詢返回一個對象
public Person selectPersonById(String id);
}
6. 一對多實體配置: PersonMapper.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.mybatis.dao.mapper.PersonMapper" >
<resultMap id="PersonResultMap" type="com.mybatis.domain.Person" >
<id column="personId" property="personid" jdbcType="VARCHAR" />
<result column="personName" property="personname" jdbcType="VARCHAR" />
<result column="personAddress" property="personaddress" jdbcType="VARCHAR" />
<result column="personTel" property="persontel" jdbcType="VARCHAR" />
<!-- 一對多的關系(這個是關聯(lián)集合)這個是Orders里面的多方 -->
<!-- property: 指的是集合屬性的名, ofType:指的是集合中元素的類型的路徑 (實現(xiàn)類)-->
<collection property="orders" ofType="com.mybatis.domain.Orders">
<!-- id有一個單獨標簽 -->
<id column="orderId" property="orderid"/>
<!--column指sql中字段的名字 property指java中對應sql中屬性的名 -->
<result column="orderNumber" property="ordernumber"/>
<result column="orderPrice" property="orderprice"/>
</collection>
</resultMap>
<!-- 根據id查詢Person, 關聯(lián)將Orders查詢出來(注意放置的位置) -->
<select id="findPersonAndOrders" parameterType="String" resultMap="PersonResultMap">
SELECT p.*,o.* FROM person o,orders b WHERE o.personid=#{pid};
</select>
<select id="selectPersonById" parameterType="string" resultMap="PersonResultMap">
select p.*, o.* from person p, orders o where p.personId = o.pid and p.personId = #{id}
</select>
</mapper>
7.寫OrdersMapper.java的接口
package com.mybatis.dao.mapper;
import com.mybatis.domain.Orders;
import java.util.List;
public interface OrdersMapper {
int deleteByPrimaryKey(String orderid);
int insert(Orders record);
Orders selectByPrimaryKey(String orderid);
List<Orders> selectAll();
int updateByPrimaryKey(Orders record);
//多查一 根據id
public Orders selectOrderById(String oid);
//多查一 根據orderNumber
public Orders selectOrderNumber(String number);
}
8.多對一實體配置: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.mybatis.dao.mapper.OrdersMapper" >
<resultMap id="OrdersResultMap" type="com.mybatis.domain.Orders" >
<id column="orderId" property="orderid" jdbcType="VARCHAR" />
<result column="orderNumber" property="ordernumber" jdbcType="VARCHAR" />
<result column="orderPrice" property="orderprice" jdbcType="INTEGER" />
<!--
<result column="pid" property="pid" jdbcType="VARCHAR" />
-->
<!-- 多對一的關系 這個是Person里面的單方 -->
<!-- property: 指的是屬性的值, javaType:指的是屬性的類型的路徑 (實現(xiàn)類)-->
<association property="person" javaType="com.mybatis.domain.Person">
<!--注意:在此column和property的值要一樣都為Person的屬性 -->
<id column="personid" property="personid"/>
<result column="personname" property="personname"/>
<result column="personaddress" property="personaddress"/>
<result column="persontel" property="persontel"/>
</association>
</resultMap>
<!-- 根據id查詢Order, 關聯(lián)將Person查詢出來 -->
<select id="selectOrderById" parameterType="string" resultMap="OrdersResultMap">
select p.*, o.* from person p, orders o where p.personId = o.pid and o.orderId = #{oid}
</select>
<!-- 根據orderNumber查詢Order, 關聯(lián)將Person查詢出來 -->
<select id="selectOrderNumber" parameterType="string" resultMap="OrdersResultMap">
select p.*, o.* from person p, orders o where p.personId = o.pid and o.orderId = #{number}
</select>
</mapper>
9.其他配置
db.properties配置(sql語句的基本鏈接)
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/wang1?useUnicode=true&characterEncoding=utf8
db.username=root
db.password=123456
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.xml(逆向生成domain、dao層)
<?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>
<!-- mybatis核心配置文件 -->
<!-- 加載java的配置文件或者聲明屬性信息 -->
<properties resource="db.properties">
</properties>
<!-- alias別名 -->
<typeAliases> <!--這里需要修改 domain層的路徑-->
<typeAlias type="com.mybatis.domain.Person" alias="person" />
<typeAlias type="com.mybatis.domain.Orders" alias="orders" />
</typeAliases>
<!-- 配置mybatis的環(huán)境信息,與spring整合,該信息由spring來管理
如果說我們需要連接數據庫,那么必須在mybatis中配置環(huán)境 運行環(huán)境
-->
<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> <!--這里需要修改 dao層的路徑-->
<mapper resource="com\mybatis\dao\mapper\PersonMapper.xml"/>
<mapper resource="com\mybatis\dao\mapper\OrdersMapper.xml"/>
</mappers>
</configuration>
generatorConfig.xml配置(對MySQL進行操作)下面標紅部分根據自己建立的進行修改
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration> D盤中要有此包mysql-connector-java-5.1.7-bin.jar
<classPathEntry location="D:\mysql-connector-java-5.1.7-bin.jar" />
<context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple">
<!-- 自動識別數據庫關鍵字,默認false,如果設置為true,根據SqlReservedWords中定義的關鍵字列表;
一般保留默認值,遇到數據庫關鍵字(Java關鍵字),使用columnOverride覆蓋 -->
<property name="autoDelimitKeywords" value="false" />
<!-- 生成的Java文件的編碼 -->
<property name="javaFileEncoding" value="UTF-8" />
<!-- beginningDelimiter和endingDelimiter:指明數據庫的用于標記數據庫對象名的符號,比如ORACLE就是雙引號,MYSQL默認是`反引號; -->
<property name="beginningDelimiter" value="`" />
<property name="endingDelimiter" value="`" />
<!-- 注釋生成器 -->
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 必須要有的,使用這個配置鏈接數據庫 @TODO:是否可以擴展 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/wang1" userId="root" password="123456">
<!-- 這里面可以設置property屬性,每一個property屬性都設置到配置的Driver上 -->
</jdbcConnection>
<!-- java模型創(chuàng)建器,是必須要的元素 負責:1,key類(見context的defaultModelType);2,java類;3,查詢類
targetPackage:生成的類要放的包,真實的包受enableSubPackages屬性控制;
targetProject:目標項目,指定一個存在的目錄下,生成的內容會放到指定目錄中,如果目錄不存在,MBG不會自動建目錄 -->
<javaModelGenerator targetPackage="com.mybatis.domain" targetProject="mybatis03/src">
<!-- for MyBatis3/MyBatis3Simple 自動為每一個生成的類創(chuàng)建一個構造方法,構造方法包含了所有的field;而不是使用setter; -->
<property name="constructorBased" value="false" />
<!-- for MyBatis3 / MyBatis3Simple 是否創(chuàng)建一個不可變的類,如果為true, 那么MBG會創(chuàng)建一個沒有setter方法的類,
取而代之的是類似constructorBased的類 -->
<property name="immutable" value="false" />
</javaModelGenerator>
<!-- 生成SQL map的XML文件生成器, 注意,在Mybatis3之后,我們可以使用mapper.xml文件+Mapper接口(或者不用mapper接口),
或者只使用Mapper接口+Annotation,所以,如果 javaClientGenerator配置中配置了需要生成XML的話,這個元素就必須配置
targetPackage/targetProject:同javaModelGenerator -->
<sqlMapGenerator targetPackage="com.mybatis.dao.mapper" targetProject="mybatis03/src">
<!-- 在targetPackage的基礎上,根據數據庫的schema再生成一層package,最終生成的類放在這個package下,默認為false -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 對于mybatis來說,即生成Mapper接口,注意,如果沒有配置該元素,那么默認不會生成Mapper接口 targetPackage/targetProject:同javaModelGenerator
type:選擇怎么生成mapper接口(在MyBatis3/MyBatis3Simple下):
1,ANNOTATEDMAPPER:會生成使用Mapper接口+Annotation的方式創(chuàng)建(SQL生成在annotation中),不會生成對應的XML;
2,MIXEDMAPPER:使用混合配置,會生成Mapper接口,并適當添加合適的Annotation,但是XML會生成在XML中;
3,XMLMAPPER:會生成Mapper接口,接口完全依賴XML;
注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER -->
<javaClientGenerator targetPackage="com.mybatis.dao.mapper" type="XMLMAPPER" targetProject="mybatis03/src">
<!-- 在targetPackage的基礎上,根據數據庫的schema再生成一層package,最終生成的類放在這個package下,默認為false -->
<property name="enableSubPackages" value="true" />
<!-- 可以為所有生成的接口添加一個父接口,但是MBG只負責生成,不負責檢查 <property name="rootInterface"
value=""/> -->
</javaClientGenerator>
<!--逆向生成的文件-->
<table tableName="person" delimitIdentifiers="true">
<!-- 參考 javaModelGenerator 的 constructorBased屬性 -->
<property name="constructorBased" value="false" />
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
<table tableName="orders" delimitIdentifiers="true">
<!-- 參考 javaModelGenerator 的 constructorBased屬性 -->
<property name="constructorBased" value="false" />
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
</context>
</generatorConfiguration>
10.測試文件
package com.mybatis.test;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import lombok.Data;
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.mybatis.dao.mapper.OrdersMapper;
import com.mybatis.dao.mapper.PersonMapper;
import com.mybatis.domain.Orders;
import com.mybatis.domain.Person;
public class TestStudentMapper {
SqlSessionFactory sessionFactory = null;
// 這方法之前
@Before
public void setup() throws Exception {
String resource = "mybatis.xml";
// 這個是加載配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
// 得到會話工廠
sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
//查詢一對多 根據這個person里面的id號就能查詢出這個用戶有多少個訂單記錄
// @Test
public void testSelectPersonById(){
SqlSession sq = sessionFactory.openSession();
// 得到dao層的實現(xiàn)類
PersonMapper u = sq.getMapper(PersonMapper.class);
Person person = u.selectPersonById("2");
System.out.println(person);
}
//多對一 根據多對一id進行查詢
// @Test//多對一關聯(lián)查詢
public void testSelectOrderById(){
SqlSession sq = sessionFactory.openSession();
// 得到dao層的實現(xiàn)類
OrdersMapper u = sq.getMapper(OrdersMapper.class);
Orders od = u.selectOrderById( "2");
System.out.println(od.getPerson().getPersonname());
System.out.println(od.getPerson().getPersonaddress());
}
@Test//多對一關聯(lián)查詢
public void testSelectOrderNumber(){
SqlSession sq = sessionFactory.openSession();
// 得到dao層的實現(xiàn)類
OrdersMapper u = sq.getMapper(OrdersMapper.class);
Orders od = u.selectOrderNumber("001");
System.out.println(od.getPerson().getPersonname());
System.out.println(od.getPerson().getPersonaddress());
}
}
如有問題請多多指教!希望給您帶來幫助!祝您生活愉快。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關內容請查看下面相關鏈接
相關文章
Java 字節(jié)數組(byte[])和整型(int)的相互轉換
在Java編程中,有時需要將字節(jié)類型(byte)轉換為整數類型(int),或者反過來轉換,本文主要介紹了Java 字節(jié)數組(byte[])和整型(int)的相互轉換,感興趣的可以了解一下2023-12-12
idea無法打斷點,單擊或雙擊代碼行左側區(qū)域無效的解決
這篇文章主要介紹了idea無法打斷點,單擊或雙擊代碼行左側區(qū)域無效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
Java反射(JDK)與動態(tài)代理(CGLIB)詳解
下面小編就為大家?guī)硪黄獪\談Java反射與動態(tài)代理。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2021-08-08

