mybatis框架之多表关联关系(基于xml文件)
表与表之间都有哪些关系?
- 一对一关系: 一个订单只能对应一个用户
- 一对多关系: 一个用户可以对应多个订单
- 多对多关系: 多个订单详情对应多个商品
一对一关系示例
-
这里演示两种方式实现一对一关系,使用resultType和使用resultMap的方式,代码中有注释讲解
-
表结构
- myuser表结构
- orders表结构
- myuser表结构
-
po层实体类代码
- myuser表映射的实体类MyUser类:
import java.sql.Date; /** * 这是数据库user表对应的java实体类 * 属性值对应数据库表的每个字段 * * 并生成它的set get方法和tostring方法 */ public class MyUser { private Integer id; private String username; private Date birthday; private String sex; private String address; 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 Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "MyUser{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } }
- orders表映射的实体类Order类
import java.sql.Date; /* * 这是数据库商品表对应的java实体类 * 表中的字段映射java类中的属性名 * 并生成它的set get和tostring方法 * */ public class Order { private Integer id; private Integer user_id; private String number; private Date createtime; private String note; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUser_id() { return user_id; } public void setUser_id(Integer user_id) { this.user_id = user_id; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } 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; } @Override public String toString() { return "Order{" + "id=" + id + ", user_id=" + user_id + ", number='" + number + '\'' + ", createtime=" + createtime + ", note='" + note + '\'' + '}'; } }
- Order类的一个扩展类,这个类是使用resultMap的方式实现一对一关系时使用。
/* * 这是order类的扩展类,继承order类 * 在order的基础上增加username address属性 *在映射文件中使用resultMap的方式时,使用 * */ public class OrderCustom extends Order { private String username; private String address; //这个是使用resultmap 将数据先映射到一个map中 private MyUser myUser; public MyUser getMyUser() { return myUser; } public void setMyUser(MyUser myUser) { this.myUser = myUser; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
- 配置你的全局核心配置文件,注意更改你的数据源的,数据库,用户名,密码。
<?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> <environments default="dev"> <environment id="dev"> <!-- 设置事务类型--> <transactionManager type="JDBC"></transactionManager> <!-- 设置数据源类型--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/你的库"/> <property name="username" value="用户名"/> <property name="password" value="密码"/> </dataSource> </environment> </environments> <!-- 注入你的映射文件--> <mappers> <mapper resource="ordertouserMapper.xml"></mapper> </mappers> </configuration>
- 配置一对一的映射文件,注意映射文件编写好要在全局配置文件中添加。
<?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的路径,如果使用getmap的话就要写映射接口的路径--> <mapper namespace="com.wdhcr.onetoone.mapper"> <!-- 第一种方式:这是多表查询的多表之间一对一的关系--> <select id="orderToUserOneToOne" resultType="com.wdhcr.onetomany.po.OrderCustom"> select orders.*,myuser.username,myuser.address from orders,myuser where orders.user_id = myuser.id </select> <!-- 第二种方式:依旧是一对一关系。但是使用resultmap的方式,映射到一个resultmap中--> <!-- 创建一个resultmap 这里是映射到到order的一个扩展类上,这个扩展类中添加myuser属性--> <resultMap id="oneToOneResultMap" type="com.wdhcr.onetoone.po.OrderCustom"> <!-- 当字段是主键时使用id标签column字段名映射property是实体类中的属性名--> <id column="id" property="id"></id> <result column="user_id" property="user_id"></result> <result column="number" property="number"></result> <result column="createtime" property="createtime"></result> <result column="note" property="note"></result> <!--添加实体类中的其他类对象的属性--> <association property="myUser" javaType="com.wdhcr.onetoone.po.MyUser"> <result column="id" property="id"></result> <result column="username" property="username"></result> <result column="birthday" property="birthday"></result> <result column="sex" property="sex"></result> <result column="address" property="address"></result> </association> </resultMap> <!--一对一关系的验证,使用resultmap的方式--> <select id="onetooneResultMap" resultMap="oneToOneResultMap"> select orders.*,myuser.username,myuser.address from orders,myuser where orders.user_id = myuser.id </select> </mapper>
- 接下来就是测试类代码:
import com.wdhcr.onetoone.po.OrderCustom; 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class Test { public static void main(String[] args) throws IOException { //注意此处的路径 //加载 mybatis 配置文件 InputStream resourceAsStream = Resources.getResourceAsStream("ConfigMapper.xml"); //构建sqlSession的工厂 SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream); //根据 sqlSessionFactory 产生 session SqlSession sqlSession = build.openSession(); //第一种方式:使用resultype的方式验证数据库表之间一对一关系 // List<OrderCustom> orderCustoms = sqlSession.selectList("com.wdhcr.onetoone.mapper.orderToUserOneToOne"); // for (OrderCustom orderCustom : orderCustoms) { // System.out.println(orderCustom); // } //第二种方式使用resulmap的方式验证数据库表之间一对一关系 List<OrderCustom> orderCustoms= sqlSession.selectList("com.wdhcr.onetoone.mapper.onetooneResultMap"); for (OrderCustom orderCustom : orderCustoms) { System.out.println(orderCustom); } } }
-
以上就实现多表之间一对一关系(一个订单对应一个用户)
一对多的关系
-
使用resultMap的方式
-
表结构
- myuser表结构
- orders表结构
- orderdetail表结构
- myuser表结构
-
po层实体类代码
- myuser表映射的实体类MyUser类:
import java.sql.Date; /** * 这是数据库user表对应的java实体类 * 属性值对应数据库表的每个字段 * * 并生成它的set get方法和tostring方法 */ public class MyUser { private Integer id; private String username; private Date birthday; private String sex; private String address; 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 Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "MyUser{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } }
- orders表映射的实体类Order类
import java.sql.Date; /* * 这是数据库商品表对应的java实体类 * 表中的字段映射java类中的属性名 * 并生成它的set get和tostring方法 * */ public class Order { private Integer id; private Integer user_id; private String number; private Date createtime; private String note; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUser_id() { return user_id; } public void setUser_id(Integer user_id) { this.user_id = user_id; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } 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; } @Override public String toString() { return "Order{" + "id=" + id + ", user_id=" + user_id + ", number='" + number + '\'' + ", createtime=" + createtime + ", note='" + note + '\'' + '}'; } }
- orderdetail表映射的实体类OrderDetail类
/* * 这是映射订单表中的字段对应的实体类 * 有对应数据库表中字段的属性 * 并生成get set方法和tostring方法 * */ public class OrderDetail { private Integer id; private Integer orders_id; private Integer items_id; private Integer items_num; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getOrders_id() { return orders_id; } public void setOrders_id(Integer orders_id) { this.orders_id = orders_id; } public Integer getItems_id() { return items_id; } @Override public String toString() { return "OrderDetail{" + "id=" + id + ", orders_id=" + orders_id + ", items_id=" + items_id + ", items_num=" + items_num + '}'; } public void setItems_id(Integer items_id) { this.items_id = items_id; } public Integer getItems_num() { return items_num; } public void setItems_num(Integer items_num) { this.items_num = items_num; } }
- order类的一个扩展类
/* * 这是order类的扩展类,继承order类 * 在order的基础上增加username address属性 * * */ public class OrderCustom extends Order { private String username; private String address; //这个是使用resultmap 将数据先映射到一个map中 private MyUser myUser; //验证一对多的关系,一个订单对应多个明细 private OrderDetail orderDetail; public OrderDetail getOrderDetail() { return orderDetail; } public void setOrderDetail(OrderDetail orderDetail) { this.orderDetail = orderDetail; } public MyUser getMyUser() { return myUser; } public void setMyUser(MyUser myUser) { this.myUser = myUser; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
-
配置你的全局核心配置文件,注意更改你的数据源的,数据库,用户名,密码。
<?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> <environments default="dev"> <environment id="dev"> <!-- 设置事务类型--> <transactionManager type="JDBC"></transactionManager> <!-- 设置数据源类型--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- 注入你的映射文件--> <mappers> <!--添加一对多的映射文件--> <mapper resource="oneTomany.xml"></mapper> </mappers> </configuration>
-
配置一对多的映射文件,注意映射文件编写好要在全局配置文件中添加。
<?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的路径,如果使用getmap的话就要写映射接口的路径--> <mapper namespace="com.wdhcr.onetomany.mapper"> <!-- 创建一个resultmap 这里是映射到到order的一个扩展类上,这个扩展类中添加myuser属性--> <resultMap id="oneToOneResultMap" type="com.wdhcr.onetomany.po.OrderCustom"> <!-- 当字段是主键时使用id标签column字段名映射property是实体类中的属性名--> <id column="id" property="id"></id> <result column="user_id" property="user_id"></result> <result column="number" property="number"></result> <result column="createtime" property="createtime"></result> <result column="note" property="note"></result> <!--添加实体类中的其他类对象的属性--> <association property="myUser" javaType="com.wdhcr.onetomany.po.MyUser"> <result column="id" property="id"></result> <result column="username" property="username"></result> <result column="birthday" property="birthday"></result> <result column="sex" property="sex"></result> <result column="address" property="address"></result> </association> </resultMap> <!--使用resultmap验证一对多的关系,使这个resultmap继承上面的resultmap, 使其可使用上面resultmap中的属性,并添加自己的属性--> <resultMap id="onTomany" type="com.wdhcr.onetomany.po.OrderCustom" extends="oneToOneResultMap"> <association property="orderDetail" javaType="com.wdhcr.onetomany.po.OrderDetail"> <result column="id" property="id"></result> <result column="orders_id" property="orders_id"></result> <result column="items_id" property="items_id"></result> <result column="items_num" property="items_num"></result> </association> </resultMap> <!--验证多表之间一对多的关系--> <select id="oneToManySelect" resultMap="onTomany"> SELECT myuser.`username`,myuser.`birthday`,myuser.`address`,orders.`createtime`, orders.`number`,orders.`note` FROM myuser,orders,orderdetail WHERE myuser.`id`=orders.`user_id` AND orders.id=orderdetail.`orders_id` </select> </mapper>
-
测试类代码:
import com.wdhcr.onetomany.po.OrderCustom; 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class Test { public static void main(String[] args) throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("ConfigMapper.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = build.openSession(); List<OrderCustom> orderCustoms=sqlSession.selectList("com.wdhcr.onetomany.mapper.oneToManySelect"); for (OrderCustom orderCustom : orderCustoms) { //因为有tostring方法,所以直接打印对象即可 System.out.println(orderCustom); } } }
多对多关系
-
表结构
- myuser表结构
- orders表结构
- orderdetail表结构
- items表结构
- myuser表结构
-
orders表映射的实体类Order类,注意是实现多对多的关系,一个用户可以有多个订单,所以添加了一个 List myOrderslist属性
import java.util.Date; import java.util.List; /** * 这是数据库user表对应的java实体类 * 属性值对应数据库表的每个字段 * * 并生成它的set get方法和tostring方法 * 由于要实现多对多的关系,所以在user类中添加订单属性,还是多个订单 */ public class Myuser { private Integer id; private String username; private Date birthday; private String sex; private String address; //用户下面有你的 定单的列表---一个用户下面可以有很多的订单 private List<Orders> myOrderslist; public List<Orders> getMyOrderslist() { return myOrderslist; } public void setMyOrderslist(List<Orders> myOrderslist) { this.myOrderslist = myOrderslist; } 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 Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Myuser{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + ", myOrderslist=" + myOrderslist + '}'; } }
-
orders表映射的实体类Order类
import java.sql.Date; import java.util.List; /* * 这是数据库商品表对应的java实体类 * 表中的字段映射java类中的属性名 * 并生成它的set get和tostring方法 * 一个订单下可以有多个订单明细,所以添加 * List<OrderDetail> getOrderDetailslist()属性 * */ public class Orders { private Integer id; private Integer user_id; private Integer number; private Date createtime; private Myuser myuser; public Myuser getMyuser() { return myuser; } public void setMyuser(Myuser myuser) { this.myuser = myuser; } // 一个订单下面可以有很的多的订单明细 public List<OrderDetail> getOrderDetailslist() { return orderDetailslist; } public void setOrderDetailslist(List<OrderDetail> orderDetailslist) { this.orderDetailslist = orderDetailslist; } private List<OrderDetail> orderDetailslist; public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } private String note; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUser_id() { return user_id; } public void setUser_id(Integer user_id) { this.user_id = user_id; } public Integer getNumber() { return number; } public void setNumber(Integer number) { this.number = number; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } @Override public String toString() { return "Orders{" + "id=" + id + ", user_id=" + user_id + ", number=" + number + ", createtime=" + createtime + ", note='" + note + '\'' + ", myuser=" + myuser + ", orderDetailslist=" + orderDetailslist + '}'; } }
-
orderdetail表映射的实体类OrderDetail类
/* * 这是映射订单表中的字段对应的实体类 * 有对应数据库表中字段的属性 * 并生成get set方法和tostring方法 * */ public class OrderDetail { private Integer id; private Integer order_id; private Integer items_id; private Integer items_num; //这个就是在你的商品明细中有一个商品 //从用户----订单---订单明细---商品 private Items items; public Items getItems() { return items; } public void setItems(Items items) { this.items = items; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getOrder_id() { return order_id; } public void setOrder_id(Integer order_id) { this.order_id = order_id; } public Integer getItems_id() { return items_id; } public void setItems_id(Integer items_id) { this.items_id = items_id; } public Integer getItems_num() { return items_num; } public void setItems_num(Integer items_num) { this.items_num = items_num; } @Override public String toString() { return "OrderDetail{" + "id=" + id + ", order_id=" + order_id + ", items_id=" + items_id + ", items_num=" + items_num + ", items=" + items + '}'; } }
-
items表映射的实体类Item类
import java.util.Arrays; import java.util.Date; /** * 这是数据库items表对应的java实体类 * 属性值对应数据库表的每个字段 * <p> * 并生成它的set get方法和tostring方法 */ public class Items { @Override public String toString() { return "Items [id=" + id + ", name=" + name + ", price=" + price + ", detail=" + detail + ", pic=" + Arrays.toString(pic) + ", createtime=" + createtime + "]"; } private Integer id; private String name; private Double price; private String detail; private byte[] pic; private Date createtime; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public byte[] getPic() { return pic; } public void setPic(byte[] pic) { this.pic = pic; } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } }
-
全局核心配置文件,注意你的库,用户名,密码
<?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> <environments default="dev"> <environment id="dev"> <!-- 设置事务类型--> <transactionManager type="JDBC"></transactionManager> <!-- 设置数据源类型--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/库"/> <property name="username" value="用户名"/> <property name="password" value="密码"/> </dataSource> </environment> </environments> <!-- 注入你的映射文件--> <mappers> <!--添加多对多关系映射文件--> <mapper resource="manyToMany.xml"></mapper> </mappers> </configuration>
-
多对多关系映射文件
<?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的路径,如果使用getmap的话就要写映射接口的路径--> <mapper namespace="com.wdhcr"> <resultMap type="com.wdhcr.manytomany.po.Myuser" id="userAndItemsResultMap"> <!-- 用户信息 里面对应有订单信息--> <id column="id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> <!-- 订单信息 里面对应有订单详细信息--> <collection property="myOrderslist" ofType="com.wdhcr.manytomany.po.Orders"> <id column="id" property="id"/> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 订单明细里面对应有商品信息 --> <collection property="orderDetailslist" ofType="com.wdhcr.manytomany.po.OrderDetail"> <id column="id" property="id"/> <result column="orders_id" property="orders_id"/> <result column="items_id" property="items_id"/> <result column="items_num" property="items_num"/> <!-- 商品信息 --> <association property="items" javaType="com.wdhcr.manytomany.po.Items"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="price" property="price"/> <result column="createtime" property="createtime"/> </association> </collection> </collection> </resultMap> <select id="manytomany" resultMap="userAndItemsResultMap"> SELECT myuser.*,orders.`number`,orders.`createtime`,orders.`note`,orderdetail.`items_id`,orderdetail.`items_num`,items.`nam e`,items.`price` FROM myuser,orders,orderdetail,items WHERE myuser.`id`=orders.`user_id` AND orderdetail.`orders_id`=orders.`id`AND orderdetail.`items_id`=items.`id` </select> </mapper>
-
测试类代码:
import com.wdhcr.manytomany.po.Myuser; 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class Test { public static void main(String[] args) throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("ConfigMapper.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = build.openSession(); List<Myuser> myusers = sqlSession.selectList("com.wdhcr.manytomany"); for (Myuser myuser : myusers) { System.out.println(myuser); } } }
-
以上就是mybatis框架中多表之间的关系及其代码实现