当前位置: 首页 > news >正文

Mybatis 简单练习,自定义sql关联查询

目录结构

mybatis-02/
├── pom.xml
└── src/├── main/│   ├── java/│   │   └── com/│   │       └── demo/│   │           ├── mapper/│   │           │   ├── DepartMapper.java│   │           │   ├── DepartMapper.xml│   │           │   ├── EmployeeMapper.java│   │           │   └── EmployeeMapper.xml│   │           ├── model/│   │           │   ├── Depart.java│   │           │   └── Employee.java│   │           ├── test/│   │           │   ├── DepartTest.java│   │           │   └── EmployeeTest.java│   │           └── util/│   │               └── MybatisUtil.java│   └── resources/│       ├── db.properties│       └── mybatis-config.xml└── test/└── java/└── com/└── demo/ // (空目录)

该项目是一个基于MyBatis框架的员工和部门管理的模拟项目demo,主要实现以下功能:

1. 技术架构

  • 核心框架 :MyBatis(ORM持久层框架)
  • 数据库 :MySQL(通过 db.properties 配置连接信息)
  • 项目构建 :Maven(通过 pom.xml 管理依赖)

2. 主要功能

(1)数据模型设计

  • 部门表(Depart) :包含部门ID(depid)和部门名称(depname)
  • 员工表(Employee) :包含员工ID、姓名、薪水、入职日期、地址和部门ID(多对一关联部门)

(2)数据库操作

  • 部门管理 :
    • 通过 DepartMapper 实现部门查询,支持级联查询部门下的所有员工(一对多关系)
  • 员工管理 :
    • 基础查询:查询所有员工信息(关联部门名称)
    • 条件查询:根据地址模糊查询和薪水范围筛选员工
    • 更新操作:动态更新员工信息(支持部分字段更新)
    • 批量查询:通过员工ID数组批量查询员工

(3)技术实现要点

  • MyBatis核心配置 :
    • mybatis-config.xml 配置数据库环境和映射器扫描
    • 自定义 MybatisUtil 工具类管理SqlSession生命周期
  • 高级映射 :
    • 使用 处理实体类与数据库表字段映射
    • 通过 实现员工到部门的多对一关联
    • 通过 实现部门到员工的一对多关联
  • 动态SQL :
    • 使用 和 实现条件查询
    • 使用 实现批量ID查询

3. 项目结构特点

  • 采用标准MVC分层架构,分离模型(model)、映射器(mapper)和工具类(util)
  • 配置文件与代码分离,通过属性文件管理数据库连接信息
  • SQL语句与Java代码解耦,统一在XML映射文件中维护

总结

该项目是一个典型的MyBatis入门示例,演示了如何使用MyBatis进行数据库CRUD操作、处理关联关系及编写动态SQL,适合作为MyBatis框架的学习案例。

实体类

package com.demo.model;import java.util.List;public class Depart {private Integer depid;private String depname;
//处理一对多的关联方式private List<Employee> employees;public Integer getDepid() {return depid;}public void setDepid(Integer depid) {this.depid = depid;}public String getDepname() {return depname;}public void setDepname(String depname) {this.depname = depname;}public List<Employee> getEmployees() {return employees;}public void setEmployees(List<Employee> employees) {this.employees = employees;}
}package com.demo.model;import java.util.Date;public class Employee {private Integer empid;private String empname;private Double bsaralry;private Date hiredate;private String address;private Integer depid;//处理多对一的关联private Depart depart;public Integer getEmpid() {return empid;}public void setEmpid(Integer empid) {this.empid = empid;}public String getEmpname() {return empname;}public void setEmpname(String empname) {this.empname = empname;}public Double getBsaralry() {return bsaralry;}public void setBsaralry(Double bsaralry) {this.bsaralry = bsaralry;}public Date getHiredate() {return hiredate;}public void setHiredate(Date hiredate) {this.hiredate = hiredate;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Integer getDepid() {return depid;}public void setDepid(Integer depid) {this.depid = depid;}public Depart getDepart() {return depart;}public void setDepart(Depart depart) {this.depart = depart;}
}

mapper.java

package com.demo.mapper;import com.demo.model.Depart;public interface DepartMapper {Depart getDepartByDepname(String depname);
}package com.demo.mapper;import com.demo.model.Employee;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface EmployeeMapper {List<Employee>getEmpList();List<Employee> getEmployeeByAddressAndBsaralry(@Param("address") String address,@Param("bsaralry") Double bsaralry);int updateEmployee(Employee employee);List<Employee> getEmpsByEmpId(Integer[] idArray);
}

mapper.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.demo.mapper.DepartMapper"><resultMap id="departResultMap" type="com.demo.model.Depart"><id property="depid" column="did"></id><result property="depname" column="depname"></result>
<!--collection:处理一堆多关联关键节点property:对应的是实体类中属性的名称ofType:描述该集合中的每个元素的类型--><collection property="employees" ofType="com.demo.model.Employee"><id property="empid" column="empid"></id><result property="empname" column="empname"></result><result property="bsaralry" column="bsaralry"></result><result property="hiredate" column="hiredate"></result><result property="address" column="address"></result><result property="depid" column="depid"></result></collection></resultMap><!--parameterType="java.lang.String"  或string,,小写 --><select id="getDepartByDepname" parameterType="java.lang.String" resultMap="departResultMap">selectd.depid as did,d.depname,e.*from employee e,depart dwhere d.depid=e.depid and depname=#{depname}</select>
</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.demo.mapper.EmployeeMapper"><resultMap id="empResultMap" type="com.demo.model.Employee"><!--private Integer empid;private String empname;private String bsaralry;private Date hiretime;private String address;private Integer depid;
--><!--1.id节点:property:实体类中的oid(实体类中唯一能够表示一个对象的属性,,主键),也就是和结果集对应的实体类中的属性column:就是结果集中的主键字段2.result节点:property:实体类中的属性名column:结果集中的字段名property=“与实体类中的名一致”column=“与数据库中的一致”    --><id property="empid" column="empid"></id><result property="empname" column="empname"></result><result property="bsaralry" column="bsaralry"></result><result property="hiredate" column="hiredate"></result><result property="address" column="address"></result><result property="depid" column="depid"></result><!--//处理多对一的关联private Depart depart;--><!-- association节点,专门写多对一(一对一)property:对应实体类中的属性名JavaType:对应该属性的Java类型名--><association property="depart" javaType="com.demo.model.Depart"><id property="depid" column="did"></id><result property="depname" column="depname"></result></association></resultMap><select id="getEmpList" resultMap="empResultMap">select e.*,d.depid as did,depnamefrom employee einner join depart d on e.depid = d.depid</select><!--    &lt;!&ndash;动态sql语句    &ndash;&gt;--><!--    <select id="getEmployeeByAddressAndBsaralry" resultType="com.demo.model.Employee">--><!--        select * from employee--><!--&lt;!&ndash;<where></where> 1.如果有条件满足的话,那么久拼装where关键字,如果没有的话就不拼接关键字--><!--2.如果在sql语句条件的前面有and或or的时候,会自动去掉--><!--&ndash;&gt;--><!--        <where>--><!--            <if test="address!=null and address!=''">--><!--                &lt;!&ndash;address like '%福建省%'&ndash;&gt;--><!--                &lt;!&ndash;concat拼接字符串的函数&ndash;&gt;--><!--                address like concat ('%',#{address},'%')--><!--            </if>--><!--            &lt;!&ndash;转义符&ndash;&gt;--><!--            <if test="bsaralry!=null">--><!--                and bsaralry &gt;#{bsaralry}--><!--            </if>--><!--        </where>--><!--    </select>--><!--动态sql语句    --><select id="getEmployeeByAddressAndBsaralry" resultType="com.demo.model.Employee">select * from employee<!--prefix:前缀,代表trim节点内sql片段的开始部分prefixOverrides:用来描述去掉sql片段中and或者or的关键字--><trim prefix="where" prefixOverrides="and |or"><if test="address!=null and address!=''">and address like concat ('%',#{address},'%')</if><!--转义符--><if test="bsaralry!=null"><!-- &gt;转义符,抓成>大于 -->and bsaralry &gt;#{bsaralry}</if></trim></select><update id="updateEmployee" parameterType="com.demo.model.Employee">update employee<set><if test="empname!=null and empname!=''">empname=#{empname},</if><if test="bsaralry!=null">bsaralry=#{bsaralry},</if><if test="hiredate!=null">hiredate=#{hiredate},</if><if test="address!=null and address!=''">address=#{address},</if><if test="depid!=null">depid=#{depid}</if></set><where><!--test="实体类中的属性"--><if test="empid!=null">empid=#{empid}</if></where></update><select id="getEmpsByEmpId" resultType="com.demo.model.Employee">select *from employeewhere empid in<!--for(Employee e :list){}1. foreach节点中属性的说明array:接受数组,是一个集合open:描述的是in后面左面的(close:描述的是in后面右面的)separator:描述的是数组中的元素的,分隔符item:迭代的变量2.迭代的集合类型可以是数组、List、Set、Map、Map.Entry。根据阅读官网描述如下:你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。--><foreach collection="array" open="(" close=")" separator="," item="empid">#{empid}</foreach></select>
<!--choose  when  otherwise --></mapper>

单元测试

package com.demo.test;import com.demo.mapper.DepartMapper;
import com.demo.model.Depart;
import com.demo.model.Employee;
import com.demo.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.List;public class DepartTest {@Testpublic void getDepartByDepname() {SqlSession sqlSession = null;try {sqlSession = MybatisUtil.createSqlSession();Depart depart = sqlSession.getMapper(DepartMapper.class).getDepartByDepname("财务部");if (null != depart) {System.out.println("部门编号:" + depart.getDepid());System.out.println("部门名称:" + depart.getDepname());System.out.println("*************************************");//关键List<Employee> employees = depart.getEmployees();if (null != employees && employees.size() > 0) {for (Employee e : employees) {System.out.println(e.getEmpid() + "--" + e.getEmpname() + "--" + e.getBsaralry() + "--"+ e.getHiredate() + "--" + e.getAddress() + "--" + e.getDepid());}}}sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {MybatisUtil.closeSqlSession(sqlSession);}}
}package com.demo.test;import com.demo.mapper.EmployeeMapper;
import com.demo.model.Employee;
import com.demo.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.Date;
import java.util.List;public class EmployeeTest {@Testpublic void getEmpList() {SqlSession sqlSession = null;try {sqlSession = MybatisUtil.createSqlSession();List<Employee> list = sqlSession.getMapper(EmployeeMapper.class).getEmpList();if (null != list) {for (Employee e : list) {System.out.println(e.getEmpid() + "--" + e.getEmpname() + "--" + e.getBsaralry() + "--"+ e.getHiredate() + "--" + e.getAddress() + "--" + e.getDepid() + "--" + e.getDepart().getDepid() + "--" +e.getDepart().getDepname());System.out.println("==============================");}}sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {MybatisUtil.closeSqlSession(sqlSession);}}@Testpublic void getEmployeeByAddressAndBsaralry() {SqlSession sqlSession = null;try {sqlSession = MybatisUtil.createSqlSession();//动态sql只用if,这两个值必须都要写String address = "市";Double bsaralry = null;List<Employee> list = sqlSession.getMapper(EmployeeMapper.class).getEmployeeByAddressAndBsaralry(address, bsaralry);if (null != list) {for (Employee e : list) {System.out.println(e.getEmpid() + "--" + e.getEmpname() + "--" + e.getBsaralry() + "--"+ e.getHiredate() + "--" + e.getAddress() + "--" + e.getDepid());System.out.println("==============================");}}sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {MybatisUtil.closeSqlSession(sqlSession);}}@Testpublic void updateEmployee() {SqlSession sqlSession = null;try {sqlSession = MybatisUtil.createSqlSession();Employee employee = new Employee();employee.setEmpid(1012);employee.setEmpname("孙策");employee.setBsaralry(10000D);employee.setAddress("新疆乌鲁木齐市");employee.setHiredate(new Date());employee.setDepid(1);int rows = sqlSession.getMapper(EmployeeMapper.class).updateEmployee(employee);System.out.println("影响行数:" + rows);sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {MybatisUtil.closeSqlSession(sqlSession);}}@Testpublic void getEmpsByEmpId() {SqlSession sqlSession = null;try {sqlSession = MybatisUtil.createSqlSession();Integer[] idArray =new Integer[] {1002,1003,1004,1005,1006};List<Employee> list = sqlSession.getMapper(EmployeeMapper.class).getEmpsByEmpId(idArray);if (null != list) {for (Employee e : list) {System.out.println(e.getEmpid() + "--" + e.getEmpname() + "--" + e.getBsaralry() + "--"+ e.getHiredate() + "--" + e.getAddress() + "--" + e.getDepid());System.out.println("==============================");}}sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {MybatisUtil.closeSqlSession(sqlSession);}}
}

工具类

package com.demo.util;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.Reader;public class MybatisUtil {private static SqlSessionFactory factory;static {//1.创建SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();try {//2.创建SqlSessionFactory 对象String configFile = "mybatis-config.xml";Reader reader = Resources.getResourceAsReader(configFile);factory = builder.build(reader);} catch (IOException e) {e.printStackTrace();}}/*** 创建SqlSession对象** @return*/public static SqlSession createSqlSession() {/*** 1)openSession(boolean)默认为true,当为true时候自动提交事务* 2)添加,修改,删除必须提交事物,查询可以提交也可以不提交*/return factory.openSession(false);//默认值为true}//关闭public  static void closeSqlSession(SqlSession sqlSession){if (null!=sqlSession){sqlSession.close();}}
}

配置文件

db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
username=root
password=1234

mybatis-conig.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--添加数据库的属性文件  --><properties resource="db.properties"></properties><!--开发模式,测试模式,线上模式我们这配置成开发模式--><environments default="development"><environment id="development"><!-- 设置事物模式--><transactionManager type="jdbc"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><mappers>
<!--    相对地址--><mapper resource="com\demo\mapper\EmployeeMapper.xml"></mapper><mapper resource="com\demo\mapper\DepartMapper.xml"></mapper></mappers>
</configuration>

pom.xm


<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.demo</groupId><artifactId>employee-mybatis-02</artifactId><version>1.0-SNAPSHOT</version><name>employee-mybatis-02</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target><mybatis.version>3.2.8</mybatis.version><mysql.version>8.0.33</mysql.version><junit.version>4.12</junit.version></properties><dependencies><!-- Mybatis框架 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><!-- MySql数据库 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!--Junit 测试框架    --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency></dependencies><!--配置资源文件--><build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource></resources></build>
</project>
http://www.lryc.cn/news/610182.html

相关文章:

  • 卸油管链接检测误检率↓76%:陌讯多模态融合算法实战解析
  • Dbeaver数据库的安装和使用(保姆级别)
  • 基于FAISS和Ollama的法律智能对话系统开发实录-【大模型应用班-第5课 RAG技术与应用学习笔记】
  • Ubuntu系统VScode实现opencv(c++)图像一维直方图
  • 机器学习【六】readom forest
  • 微服务配置管理:Spring Cloud Alibaba Nacos 实践
  • 电子电气架构 ---智能电动汽车嵌入式软件开发过程中的block点
  • Nginx服务做负载均衡网关
  • 36.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--缓存Token
  • FPGA学习笔记——简单的乒乓缓存(RAM)
  • 飞算JavaAI需求转SpringBoot项目沉浸式体验
  • android内存作假通杀补丁(4GB作假8GB)
  • labview连接PLC的三种方式
  • 设计模式(一)——抽象工厂模式
  • ES集群规划与调优
  • 进程间通信:管道与共享内存
  • 移动前后端全栈项目
  • 读写分离有那些坑?
  • 16.8 华为昇腾CANN架构深度实战:3大核心引擎解析与性能优化216%秘籍
  • 手搓TCP服务器实现基础IO
  • falsk windows 服务器部署-解决服务器外无法访问
  • javacc学习笔记 02、JavaCC 语法描述文件的格式解析
  • Sklearn 机器学习 数据聚类 肘部法则选择聚类数目
  • 昇思学习营-模型推理和性能优化学习心得
  • MS-DOS 常用指令集
  • 【清除pip缓存】Windows上AppData\Local\pip\cache内容
  • 我的世界进阶模组开发教程——附魔(2)
  • (二)软件工程
  • 论文阅读笔记:《Dataset Distillation by Matching Training Trajectories》
  • 在CentOS 7上安装配置MySQL 8.0完整指南