Mybatis中使用association及collection进行一对多双向关联示例(含XML版与注解版)
XML版本:
实体类:
package com.sunwii.mybatis.bean; import java.util.ArrayList;
import java.util.List; import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString; @Data
@ToString
@NoArgsConstructor
public class Dept {
private Integer id;
private String name;
private List<Employee> employees = new ArrayList<Employee>(); public Dept(Integer id) {
this.id = id;
} public String toLazyString() {
return "Dept:{id: "+this.id+" ; name: "+this.name+"}";
}
}
package com.sunwii.mybatis.bean; import lombok.Data;
import lombok.NoArgsConstructor; @Data
@NoArgsConstructor
public class Employee {
protected Integer id;
protected String name;
protected Dept dept; public Employee(Integer id) {
this.id = id;
} public String toLazyString() {
return "Employee:{id: " + this.id + "; name: " + this.name + "}";
} @Override
public String toString() {
return "Employee(id=" + this.id + ", name=" + this.name + ", dept={id=" + this.dept.getId() + ", name="
+ this.dept.getName() + "})";
}
}
Mapper接口:
package com.sunwii.mybatis.mapper; import com.sunwii.mybatis.bean.Dept; public interface DeptMapper {
public Dept selectById(Integer id);
public int insertDept(Dept dept);
public int updateDept(Dept dept);
public int deleteDept(Dept dept);
}
package com.sunwii.mybatis.mapper; import com.sunwii.mybatis.bean.Employee; public interface EmployeeMapper {
public Employee selectById(Integer id);
public int insertEmployee(Employee employee);
public int updateEmployee(Employee employee);
public int deleteEmployee(Employee employee);
}
Mapper映射文件:
<?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.sunwii.mybatis.mapper.DeptMapper">
<resultMap type="Dept" id="DeptMap_basic">
<id property="id" column="did" />
<result property="name" column="name" />
</resultMap>
<resultMap type="Dept" id="DeptMap" extends="DeptMap_basic">
<!-- 一对多关联:使用select引用方式 -->
<collection property="employees" column="did" ofType="Employee" select="com.sunwii.mybatis.mapper.EmployeeMapper.selectByDept" fetchType="lazy">
</collection>
</resultMap> <select id="selectById" parameterType="Integer"
resultMap="DeptMap">
select id as did, name from t_dept d where d.id=#{id}
</select> <insert id="insertDept" parameterType="Dept" keyColumn="id"
keyProperty="id" useGeneratedKeys="true">
insert into t_dept(name)
values(#{name})
</insert> <update id="updateDept" parameterType="Dept">
update t_dept set
name=#{name}
where id=#{id}
</update> <delete id="deleteDept" parameterType="Dept">
delete from t_dept
where
id=#{id}
</delete>
</mapper>
<?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.sunwii.mybatis.mapper.EmployeeMapper">
<resultMap type="Employee" id="EmployeeMap_basic">
<id property="id" column="id" />
<result property="name" column="name" />
</resultMap>
<resultMap type="Employee" id="EmployeeMap" extends="EmployeeMap_basic">
<!-- 多对一关联:使用select引用方式 -->
<association property="dept" column="dept_id"
javaType="Dept"
select="com.sunwii.mybatis.mapper.DeptMapper.selectById"
fetchType="lazy" />
</resultMap>
<select id="selectById" parameterType="Integer"
resultMap="EmployeeMap">
select id, name, dept_id from t_employee e where e.id=#{id}
</select>
<select id="selectById2" parameterType="Integer"
resultMap="EmployeeMap">
select e.id id, e.name name,d.id did,d.name dname from
t_employee e
inner join t_dept
d on e.dept_id=d.id and e.id=#{id}
</select> <select id="selectByDept" parameterType="Integer"
resultMap="EmployeeMap_basic">
select id, name, dept_id from t_employee e where
e.dept_id=#{dept.id}
</select> <insert id="insertEmployee" parameterType="Employee"
keyColumn="id" keyProperty="id" useGeneratedKeys="true">
insert into t_employee(name
<if test="dept!=null">
,dept_id
</if>
)
values(#{name}
<if test="dept!=null">
,#{dept.id}
</if>
)
</insert> <update id="updateEmployee" parameterType="Employee">
update t_employee set
name=#{name} ,dept_id=#{dept.id}
where id=#{id}
</update> <delete id="deleteEmployee" parameterType="Employee">
delete from t_employee
where id=#{id}
</delete>
</mapper>
业务层接口实现类:
package com.sunwii.mybatis.service.impl; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import com.sunwii.mybatis.bean.Dept;
import com.sunwii.mybatis.mapper.DeptMapper;
import com.sunwii.mybatis.service.DeptService; @Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper; @Override
public Dept getDept(Integer id) {
return deptMapper.selectById(id);
} @Override
@Transactional
public void insertDept(Dept dept) {
deptMapper.insertDept(dept);
} @Override
@Transactional
public void updateDept(Dept dept) {
deptMapper.updateDept(dept);
} @Override
@Transactional
public void deleteDept(Dept dept) {
deptMapper.deleteDept(dept);
} }
package com.sunwii.mybatis.service.impl; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import com.sunwii.mybatis.mapper.DeptMapper;
import com.sunwii.mybatis.mapper.EmployeeMapper;
import com.sunwii.mybatis.service.EmployeeService;
import com.sunwii.mybatis.bean.*; @Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
@Autowired
private DeptMapper deptMapper; @Override
public Employee getEmployee(Integer id) {
return employeeMapper.selectById(id);
} @Override
@Transactional
public void insertEmployee(Employee employee) {
Dept dept = employee.getDept();
//如果需要的话,就先新增部门
if(dept!=null && dept.getId()==null) {
deptMapper.insertDept(dept);
} employeeMapper.insertEmployee(employee);
} @Override
@Transactional
public void updateEmployee(Employee employee) {
employeeMapper.updateEmployee(employee);
} @Override
@Transactional
public void deleteEmployee(Employee employee) {
employeeMapper.deleteEmployee(employee);
} }
Spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd"> <!-- 引入jdbcs配置文件 -->
<context:property-placeholder
location="classpath:jdbc.properties" /> <!-- 数据库连接池 -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
<property name="maxActive" value="210" />
<property name="maxIdle" value="50" />
</bean> <!-- mybatis -->
<bean id="sessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation"
value="classpath:mybatis-config.xml" />
<property name="mapperLocations"
value="classpath:com/sunwii/mybatis/bean/*.xml" />
</bean> <!-- Mapper动态代理开发扫描 -->
<mybatis:scan base-package="com.sunwii.mybatis.mapper" /> <!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 事务注解 -->
<tx:annotation-driven
transaction-manager="transactionManager" /> <!-- 组件扫描 -->
<!-- Service扫描 -->
<context:component-scan
base-package="com.sunwii.mybatis.service.impl" />
</beans>
Mybatis配置文件:
<?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>
<settings>
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false" />
</settings> <typeAliases>
<package name="com.sunwii.mybatis.bean" />
</typeAliases> </configuration>
测试类:
package com.sunwii.mybatis.test.one2many; import org.junit.Test;
import org.springframework.context.ApplicationContext; import com.sunwii.mybatis.bean.Dept;
import com.sunwii.mybatis.bean.Employee;
import com.sunwii.mybatis.service.DeptService;
import com.sunwii.mybatis.service.EmployeeService;
import com.sunwii.mybatis.util.SpringUtil; public class TestOne2Many {
private ApplicationContext context = SpringUtil.getContext();
private EmployeeService employeeService = (EmployeeService)context.getBean(EmployeeService.class);
private DeptService deptService = (DeptService)context.getBean(DeptService.class); @Test
public void testEmployeeInsert() {
// 多对一:添加。
Employee employee = new Employee();
employee.setName("e-1");
Dept dept = deptService.getDept(1);
employee.setDept(dept); employeeService.insertEmployee(employee); } @Test
public void testEmployeeInsert2() {
// 多对一:添加。
Employee employee = new Employee();
employee.setName("e-2");
//Dept dept = deptService.getDept(1);
//employee.setDept(dept); employeeService.insertEmployee(employee); } @Test
public void testEmployeeSelect() {
// 多对一:查询。
int id = 16;
Employee employee = employeeService.getEmployee(id); System.out.println(employee.toLazyString());
System.out.println(employee);
} @Test
public void testEmployeeUpdate() {
// 多对一:更新。
int id = 15;
Employee employee = employeeService.getEmployee(id);
employee.setName("eeeeeeeeeeeee15");
employeeService.updateEmployee(employee);
} @Test
public void testEmployeeDelete() {
// 多对一:删除。
int id=15;
Employee employee = new Employee(id);
employeeService.deleteEmployee(employee); } @Test
public void testDeptSelect() {
// 一对多:更新。
int id=1;
Dept dept = deptService.getDept(id);
System.out.println(dept.toLazyString());
System.out.println(dept);
} @Test
public void testDeptUpdate() {
// 一对多:更新。
int id=2;
Dept dept = new Dept(id);
dept.setName("ddddddddd2");
deptService.updateDept(dept);
}
}
注解版本:
注解版本只是将Mapper映射文件去掉,将映射注解到Mapper接口中(并使用了动态sql提供器),其它东西不变。
Mapper接口(注解版):
package com.sunwii.mybatis.mapper; import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.mapping.FetchType; import com.sunwii.mybatis.bean.Dept; public interface DeptMapper {
public static final String select = "select id,name from t_dept where id=#{id}";
public static final String insert = "insert into t_dept(name) values(#{name})";
public static final String update = "update t_dept set name=#{name}";
public static final String delete = "delete from t_dept where id=#{id}"; public static final String one2many = "com.sunwii.mybatis.mapper.EmployeeMapper.selectByDept"; @Select(select)
@Results(id = "DeptMap", value= {
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "employees", column = "id",
many = @Many(
select = one2many,
fetchType = FetchType.LAZY))
})
public Dept selectById(Integer id); @Insert(insert)
@Options(keyColumn = "id", keyProperty = "id", useGeneratedKeys = true)
public int insertDept(Dept dept); @Update(update)
public int updateDept(Dept dept); @Delete(delete)
public int deleteDept(Dept dept);
}
package com.sunwii.mybatis.mapper; import java.util.List; import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.mapping.FetchType; import com.sunwii.mybatis.bean.Employee;
import com.sunwii.mybatis.provider.EmployeeDynamicSqlProvider; public interface EmployeeMapper {
public static final String select = "select id,name,dept_id from t_employee where id=#{id}";
public static final String selectByDept = "select id,name from t_employee where dept_id=#{deptId}";
public static final String insert = null;// dynamic sql provider
public static final String update = "update t_employee set name=#{name},dept_id=#{dept.id}";
public static final String delete = "delete from t_employee where id=#{id}"; public static final String many2one = "com.sunwii.mybatis.mapper.DeptMapper.selectById"; @Select(select)
@Results(id="EmployeeMap", value= {
@Result(property = "id",column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "dept",column = "dept_id",
one = @One(
select = many2one,
fetchType = FetchType.LAZY))
})
public Employee selectById(Integer id); @Select(selectByDept)
@Results(id="EmployeeMap_basic", value= {
@Result(property = "id",column = "id"),
@Result(property = "name", column = "name")
})
public List<Employee> selectByDept(Integer deptId); @InsertProvider(type = EmployeeDynamicSqlProvider.class, method = "insert")
@Options(keyColumn = "id", keyProperty = "id", useGeneratedKeys = true)
public int insertEmployee(Employee employee); @Update(update)
public int updateEmployee(Employee employee); @Delete(delete)
public int deleteEmployee(Employee employee);
}
动态SQL提供器:
package com.sunwii.mybatis.provider; import org.apache.ibatis.jdbc.SQL; import com.sunwii.mybatis.bean.Employee; public class EmployeeDynamicSqlProvider {
private SQL NOTNULLSET(String columnAndValue, SQL sqlObject, Object object) {
if(object!=null) {
return sqlObject.SET(columnAndValue);
} return sqlObject;
} private SQL NOTNULLVALUES(String column, String value, SQL sqlObject, Object object) {
if(object!=null) {
return sqlObject.VALUES(column,value);
} return sqlObject;
} public String insert(Employee employee) {
return new SQL() {
{
INSERT_INTO("t_employee");
VALUES("name", "#{name}"); NOTNULLVALUES("dept_id","#{dept.id}",this, employee.getDept());
}
}.toString();
}
}
多对多的示例:
https://www.cnblogs.com/dreamyoung/p/11804936.html
Mybatis中使用association及collection进行一对多双向关联示例(含XML版与注解版)的更多相关文章
- Mybatis中使用collection进行多对多双向关联示例(含XML版与注解版)
Mybatis中使用collection进行多对多双向关联示例(含XML版与注解版) XML版本: 实体类: @Data @NoArgsConstructor public class Course ...
- Mybatis中使用association及collection进行自关联示例(含XML版与注解版)
XML版本: 实体类: @Data @ToString @NoArgsConstructor public class Dept { private Integer id; private Strin ...
- Mybatis中使用association进行关联的几种方式
这里以一对一单向关联为例.对使用或不使用association的配置进行举例. 实体类: @Data @ToString @NoArgsConstructor public class IdCard ...
- JPA学习---第九节:JPA中的一对多双向关联与级联操作
一.一对多双向关联与级联操作 1.创建项目,配置文件代码如下: <?xml version="1.0" encoding="UTF-8"?> < ...
- JPA中的一对多双向关联与级联操作
学习Spring有两周时间了 , 个人觉得服务端主要实现的是数据关系的维护和数据结构的制定 , 以及由业务需求产生的CRUD , 只要保证对前端提供的接口稳定高效响应 , 具体的前端实现完全不关心. ...
- Hibernate从入门到精通(九)一对多双向关联映射
上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映射,即在一的 ...
- Hibernate(九)一对多双向关联映射
上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关 内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映 射,即在 ...
- Hibernate 一对多双向关联Demo
以Classes[班级]和Student[学生]为例的Demo //Classes.java public class Classes implements Serializable { privat ...
- hibernate 一对多双向关联 详解
一.解析: 1. 一对多双向关联也就是说,在加载班级时,能够知道这个班级所有的学生. 同时,在加载学生时,也能够知道这个学生所在的班级. 2.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...
随机推荐
- 【技术博客】Git Flow模型管理代码版本
参考GIT版本管理:Git Flow模型,在此基础上加入了自己的理解,增加人员分工和相应代码,并根据本次项目的实际情况进行相应修改. 在本学期的软件工程开发过程中,我们从alpha阶段就使用了git ...
- leetcode:124. 二叉树中的最大路径和
题目描述: 给定一个非空二叉树,返回其最大路径和. 本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列.该路径至少包含一个节点,且不一定经过根节点. 示例 1: 输入: [1,2,3] 1 ...
- nohup: 无法运行命令"java": 没有那个文件或目录
问题 在一个Linux服务器上有shell 脚本如下: nohup java -jar test.jar >> ./nohup.out 2>&1 & 直接执行脚本 s ...
- jquery ajax Uncaught TypeError :Illegal invocation 报错
使用jquery ajax异步提交的时候报Uncaught TypeError :Illegal invocation错误,报错如图: 基本上,导致这个错误的原因一般有以下两点: 1.请求类型有误,如 ...
- Linux CentOS7 下无图形界面安装Oracle11G R2版本
01,系统 Centos7 数据库版本 Oracle_11gR2 ,以及硬件要求 内存不能小于 1G,可用硬盘不小于8G Swap分区空间不小于2G grep MemTotal /proc/memin ...
- CSS布局:sticky定位
stick定位一如其名:它随“正常”文档流而动,直到规定位置,尔后“粘”在那里:或者,当它发现自己可以跟随“正常”文档流而脱离sticky位置时,就果断离开从而加入文档流. 代码与效果如下: < ...
- Windows删除文件夹下的指定格式文件(递归删除)
问题描述: 今天遇到一个需求,需要对文件夹进行文件筛选.目录结构较为复杂(目录较多,层次较深),数据量较大(总共60GB左右). 鉴于上述情况,直接排除了人工处理方式(否则小伙伴们会打死我的). 解决 ...
- 百度AI身份证识别demo,使用js提交图片数据
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...
- dva+umi+antd项目从搭建到使用
先创建一个新项目,具体步骤请参考https://www.cnblogs.com/darkbluelove/p/11338309.html 一.添加document.ejs文件(参考文档:https:/ ...
- PHP匹配中文,匹配车牌号
/** * 车牌号 * 字母全部大写 * @param $str * @return string */ public static function checkCar($str) { $patter ...