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)与外键进行关联

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" />

<!-- 一对多的关系(这个是关联集合)这个是Orders里面的多方 -->

<!-- property: 指的是集合属性的名, ofType:指的是集合中元素的类型的路径 (实现类)-->

<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, 关联将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:指的是属性的类型的路径 (实现类)-->

<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, 关联将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, 关联将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的环境信息,与spring整合,该信息由spring来管理

如果说我们需要连接数据库,那么必须在mybatis中配置环境 运行环境

-->

<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模型创建器,是必须要的元素 负责:1,key类(见context的defaultModelType);2,java类;3,查询类

targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制;

targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录 -->

<javaModelGenerator targetPackage="com.mybatis.domain" targetProject="mybatis03/src">

<!-- for MyBatis3/MyBatis3Simple 自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter; -->

<property name="constructorBased" value="false" />

<!-- for MyBatis3 / MyBatis3Simple 是否创建一个不可变的类,如果为true, 那么MBG会创建一个没有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的方式创建(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层的实现类

PersonMapper u = sq.getMapper(PersonMapper.class);

Person person = u.selectPersonById("2");

System.out.println(person);

}

//多对一 根据多对一id进行查询

// @Test//多对一关联查询

public void testSelectOrderById(){

SqlSession sq = sessionFactory.openSession();

// 得到dao层的实现类

OrdersMapper u = sq.getMapper(OrdersMapper.class);

Orders od = u.selectOrderById( "2");

System.out.println(od.getPerson().getPersonname());

System.out.println(od.getPerson().getPersonaddress());

}

@Test//多对一关联查询

public void testSelectOrderNumber(){

SqlSession sq = sessionFactory.openSession();

// 得到dao层的实现类

OrdersMapper u = sq.getMapper(OrdersMapper.class);

Orders od = u.selectOrderNumber("001");

System.out.println(od.getPerson().getPersonname());

System.out.println(od.getPerson().getPersonaddress());

}

}

如有问题请多多指教!希望给您带来帮助!祝您生活愉快。

总结

以上是 mybatis关系映射之一对多和多对一 的全部内容, 来源链接: utcz.com/z/312813.html

回到顶部