踩坑Mybatis + Mybatis-plus + MyBatis-plus-join

数据库里有两张表

tb_bursary和tb_student

tb_bursary里关联了tb_student.id作为外键

由于tb_student表可以单独操作,而tb_bursary需要联合tb_student查询

所以一开始,我是用mybatis-plus + mybaits混合的模式

mybatis-plus单独操作tb_student表,mybatis操作tb_bursary.

tb_student部分代码如下:

@Data
@TableName("tb_student")
public class Student {

    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    private String sno;
    private String name;
    private char gender = '男';
    private String password;
    private String email;
    private String telephone;
    private String address;
    private String introducation;
    private String portraitPath;
    private String clazzName;

}
public interface StudentService extends IService<Student> {


    Student login(LoginForm loginForm);


    Student getStudentById(Long userId);

    List<Student> getAllStudent();

    IPage<Student> getStudentByOpr(Page<Student> pageParam, Student student);
}
@Repository
public interface StudentMapper extends BaseMapper<Student> {

}
@Service("stuService") 
@Transactional 
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
    @Override
    public Student login(LoginForm loginForm) {
        QueryWrapper<Student> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("name",loginForm.getUsername());
        queryWrapper.eq("password",MD5.encrypt(loginForm.getPassword()));

        Student student = baseMapper.selectOne(queryWrapper);
        return student;
    }
//.....省略其他方法
}

tb_bursary则使用mybatis来联合查询:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Bursary {
    Integer id;
    Student students;
    String bursary;
    String is_approve;
    String approver;
    String approve_datetime;
    String create_time;
    String remarks;
}
public interface BursaryMapper {
    List<Bursary> getAllBursary(String name);

    void editBursary(Bursary bursary);

    void addBursary(Bursary bursary);

    void delBursaryByIds(@Param("ids") List<Integer> ids);

    void delBursaryById(Integer id);
}
public interface BursaryService {
    List<Bursary> getAllBursary(String name);
    void editBursary(Bursary bursary);

    void addBursary(Bursary bursary);

    void delBursaryByIds(List<Integer> ids);

    void delBursaryById(Integer id);
}
@Service
@Transactional
public class BursaryServiceImpl implements BursaryService {

    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);

    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    BursaryMapper mapper = sqlSession.getMapper(BursaryMapper.class);

    public BursaryServiceImpl() throws IOException {
    }

    @Override
    public List<Bursary> getAllBursary(String name) {
        if(!name.isEmpty())
        {
            name = "%" + name + "%";
        }
        List<Bursary> result = mapper.getAllBursary(name);
        return result;
    }
//...省略其他方法
}

BursaryMapper.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.example.demo.mapper.BursaryMapper">
    <resultMap id="bursaryResultMap" type="com.example.demo.pojo.Bursary">
        <id column="id" property="id"/>
        <result property="bursary" column="bursary" />
        <result property="is_approve" column="is_approve" />
        <result property="approver" column="approver" />
        <result property="approve_datetime" column="approve_datetime" />
        <result property="create_time" column="create_time" />
        <result property="remarks" column="remarks" />

        <collection property="students" ofType="com.example.demo.pojo.Student" >
            <id column="student_id" property="id"/>
            <result property="sno" column="student_sno"/>
            <result property="name" column="student_name"/>
        </collection>
    </resultMap>

    <select id="getAllBursary" resultMap="bursaryResultMap">
        select b.id, b.bursary,
        b.is_approve, b.approver, b.approve_datetime,
        b.create_time, b.remarks,
        s.id as student_id, s.sno as student_sno, s.name a
        from tb_bursary b left join tb_student s on b.student_id  = s.id
        <where>
            <if test="name!=null and name!='' ">
                and s.name like #{name}
            </if>
        </where>
    </select>

    <update id="editBursary">
        update tb_bursary set bursary = #{bursary}, is_approve = #{is_approve},
        <if test="is_approve !=null and is_approve ==1">
            approver = #{approver}, approve_datetime = now(),
        </if>
        remarks = #{remarks} where id = #{id}
    </update>

    <insert id="addBursary">
        INSERT INTO tb_bursary
        (student_id, bursary, is_approve,
        <if test="is_approve !=null and is_approve ==1">
            approver, approve_datetime,
        </if>
        create_time, remarks)
        VALUES(#{students.id}, #{bursary}, #{is_approve},
        <if test="is_approve !=null and is_approve ==1">
            #{approver}, now(),
        </if>
        CURRENT_TIMESTAMP, #{remarks});
    </insert>

    <delete id="delBursaryById" parameterType="Integer">
        delete from tb_bursary where id = #{id}
    </delete>

    <!--批量删除-->
    <delete id="delBursaryByIds" parameterType="Integer">
        delete from tb_bursary where id in
        <foreach collection="ids" separator="," item="id" open="(" close=")">
            #{id}
        </foreach>
    </delete>
</mapper>

jdbc.properties:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/zhxy_db?serverTimezone=GMT%2B8
jdbc.username=aaa
jdbc.password=123456

mybatis-config.xml:

<?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>
    <properties resource="jdbc.properties"></properties>
    <typeAliases>
        <package name="com.example.demo.pojo" />
    </typeAliases>
    <plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <property name="helperDialect" value="mysql"/>
        <property name="offsetAsPageNum" value="true"/>
        <property name="rowBoundsWithCount" value="true"/>
        <property name="pageSizeZero" value="true"/>
        <property name="reasonable" value="true"/>
        <property name="params" value="pageNum=start;pageSize=limit;"/>
        <property name="supportMethodsArguments" value="true"/>
        <property name="returnPageInfo" value="check"/>
    </plugin>
    </plugins>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/BursaryMapper.xml"/>
    </mappers>
</configuration>

项目运行后,发现mybatis和mybatis-plus是可以共存于项目中的,互不干扰。但是tb_bursury使用mybatis需要额外配置config和mapper。于是决定使用MyBatis-plus-join解决联表查询的问题。

Bursary修改如下:

Bursary不能直接用student类了,直接把需要的字段写出来

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_bursary")
public class Bursary {
    @TableId(value = "id",type = IdType.AUTO)
    Integer id;
    //Student students; //这里不能直接用Student类了
    Integer student_id;
    Integer student_sno;
    String student_name;
    String bursary;
    String is_approve;
    String approver;
    String approve_datetime;
    String create_time;
    String remarks;
}
@Repository
public interface BursaryMapper extends MPJBaseMapper<Bursary> {

}
public interface BursaryService{
    List<Bursary> getAllBursary(int currentPage, int pageSize, String name);
    void editBursary(Bursary bursary);

    void addBursary(Bursary bursary);

    void delBursaryByIds(List<Integer> ids);

    void delBursaryById(Integer id);
}
@Service
@Transactional
public class BursaryServiceImpl implements BursaryService {

    @Resource
    private BursaryMapper bursaryMapper;


    public BursaryServiceImpl() throws IOException {
    }

    @Override
    public List<Bursary> getAllBursary(int currentPage, int pageSize, String name) {
        MPJLambdaWrapper<Bursary> mpjLambdaWrapper = new MPJLambdaWrapper<>();
        mpjLambdaWrapper.selectAll(Bursary.class)
                .selectAs(Student::getId, Bursary::getStudent_id)
                .selectAs(Student::getSno, Bursary::getStudent_sno)
                .selectAs(Student::getName, Bursary::getStudent_name).leftJoin(Student.class, Student::getId,
                        Bursary::getStudent_id);
        if(!name.isEmpty())
        {
            mpjLambdaWrapper.like(Student::getName, name);
        }

        IPage<Bursary> ipage = bursaryMapper.selectJoinPage(new Page<>(currentPage, pageSize), Bursary.class,
                mpjLambdaWrapper);
        return ipage.getRecords();
    }
    
    @Override
    public void addBursary(Bursary bursary) {
        try {
            bursaryMapper.insert(bursary);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

//...省略其他方法
}

修改完毕,运行,报错:

Ambiguous collection type for property 'students'. You must specify 'javaType' or 'resultMap'

经过检查,发现是因为mybatis-plus-join和mybatis不能共存,一旦使用plus-join插件,就必须删除BursaryMapper.xml和mybatis-config.xml

再次运行,错误没有了,但是又报错了:

java.lang.NoSuchMethodError: com.baomidou.mybatisplus.core.metadata.TableInfo.havePK()Z

再仔细检查,发现是我用了selectAll(Bursary.class)去检索bursary的所有字段,但是下面又用selectAs(Student::getId, Bursary::getStudent_id)去检索student的三个字段,这里很明显重复了。

于是修改为:

@Override
    public List<Bursary> getAllBursary(int currentPage, int pageSize, String name) {
        MPJLambdaWrapper<Bursary> mpjLambdaWrapper = new MPJLambdaWrapper<>();
        //mpjLambdaWrapper.selectAll(Bursary.class)
        mpjLambdaWrapper.select(Bursary::getId)
                .select(Bursary::getBursary)
                .select(Bursary::getIs_approve)
                .select(Bursary::getApprover)
                .select(Bursary::getApprove_datetime)
                .select(Bursary::getCreate_time)
                .select(Bursary::getRemarks)
                .selectAs(Student::getId, Bursary::getStudent_id)
                .selectAs(Student::getSno, Bursary::getStudent_sno)
                .selectAs(Student::getName, Bursary::getStudent_name).leftJoin(Student.class, Student::getId,
                        Bursary::getStudent_id);
        if(!name.isEmpty())
        {
            mpjLambdaWrapper.like(Student::getName, name);
        }

        IPage<Bursary> ipage = bursaryMapper.selectJoinPage(new Page<>(currentPage, pageSize), Bursary.class,
                mpjLambdaWrapper);
        return ipage.getRecords();
    }

成功:

生成的SQL:

 SELECT t.id,t.bursary,t.is_approve,t.approver,t.approve_datetime,t.create_time,t.remarks,t1.id AS student_id,t1.sno AS student_sno,t1.name AS student_name FROM tb_bursary t LEFT JOIN tb_student t1 ON t1.id = t.student_id

结论:

Mybatis是可以和Mybatis-plus共存于项目的,但是不推荐,因为代码整体风格会不统一。

使用了Mybatis-plus-join则不能同时用Mybatis,需要删除所有Mybatis的配置。

记录一下,便于以后查阅。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/583976.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

学习 Rust 第 22 天:mini_grep 第 2 部分

书接上文&#xff0c;在本文中&#xff0c;我们学习了如何通过将 Rust 程序的逻辑移至单独的库箱中并采用测试驱动开发 (TDD) 实践来重构 Rust 程序。通过在实现功能之前编写测试&#xff0c;我们确保了代码的可靠性。我们涵盖了基本的 Rust 概念&#xff0c;例如错误处理、环境…

小程序SSL证书更新指南

随着网络技术的不断发展&#xff0c;小程序已经成为许多企业和个人进行业务推广和服务提供的重要平台。在享受小程序带来的便利和高效的同时&#xff0c;我们也必须重视其安全性问题。SSL证书作为保障小程序数据传输安全的重要手段&#xff0c;其更新工作不容忽视。本文将为大家…

在线教程|零门槛部署 Llama 3,70B 版本只占 1.07G 存储空间,新用户免费体验 8B 版本

4 月 18 日&#xff0c;Meta 宣布开源 Llama 3&#xff0c;这个号称「迄今为止最好的开源大模型」一经发布&#xff0c;立刻引爆科技圈&#xff01; 发布当天恰逢斯坦福大学教授、AI 顶尖专家吴恩达的生日&#xff0c;作为 AI 开源倡导者&#xff0c;他激动地发文表示&#xff…

CogAgent:开创性的VLM在GUI理解和自动化任务中的突破

尽管LLMs如ChatGPT在撰写电子邮件等任务上能够提供帮助&#xff0c;它们在理解和与GUIs交互方面存在挑战&#xff0c;这限制了它们在提高自动化水平方面的潜力。数字世界中的自主代理是许多现代人梦寐以求的理想助手。这些代理能够根据用户输入的任务描述自动完成如在线预订票务…

【doghead】ubuntu构建libuv

按照官方的文档2024年3月的版本。首先构建libuv 最终构建的还得了test 构建过程 zhangbin@DESKTOP-1723CM1:/mnt/d/XTRANS/thunderbolt/ayame/zhb-bifrost$ ls Bifrost-202403 README.md draw player-only worker 大神的带宽估计.png zhangbin@DESKTOP-1723CM1:/mnt/d/XTRANS/…

计算机网络 备查

OSI 七层模型 七层模型协议各层实现的功能 简要 详细 TCP/IP协议 组成 1.传输层协议 TCP 2.网络层协议 IP 协议数据单元&#xff08;PDU&#xff09;和 封装 数据收发过程 数据发送过程 1. 2.终端用户生成数据 3.数据被分段&#xff0c;并加上TCP头 4.网络层添加IP地址信息…

React + 项目(从基础到实战) -- 第十期

目标 学会react 状态管理工具 使用redux管理用户状态 Context 跨层级传递,不像props层层传递类似于Vue的provide/inject用于:切换主题颜色,切换语言 useReducer useState 的替代方案 简化版的redux MobX 1. MobX 介绍 MobX 中文文档 声明式的修改数据 , 像vue state ac…

【算法基础实验】图论-UnionFind连通性检测之quick-union

Union-Find连通性检测之quick-union 理论基础 在图论和计算机科学中&#xff0c;Union-Find 或并查集是一种用于处理一组元素分成的多个不相交集合&#xff08;即连通分量&#xff09;的情况&#xff0c;并能快速回答这组元素中任意两个元素是否在同一集合中的问题。Union-Fi…

55.基于SpringBoot + Vue实现的前后端分离-旅游管理系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的旅游管理系统设计与实现管理工作系统…

【Node.js工程师养成计划】之express框架

一、Express 官网&#xff1a;http://www.expressjs.com.cn express 是一个基于内置核心 http 模块的&#xff0c;一个第三方的包&#xff0c;专注于 web 服务器的构建。 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用&…

docker学习笔记3:VmWare CentOS7安装与静态ip配置

文章目录 一、安装CentOS71、下载centos镜像2、安装二、设置静态ip三、xshell连接centos本专栏的docker环境是在centos7里安装,因此首先需要会安装centos虚拟机。 本篇博客介绍如何在vm虚拟机里安装centos7。 一、安装CentOS7 1、下载centos镜像 推荐清华源,下载如下版本 …

使用量排名前50的GPTs趋势和特征

Chatgpt的gpt商店已经有几千gpts了。目前哪些gpts比较受欢迎呢&#xff1f;有哪些趋势和投资呢? 根据whatplugin.ai&#xff08;截止日期为2024年3月&#xff09;&#xff0c;使用量最多的50个gpts数据分析结果如下&#xff1a; GPTs类型的分布情况如下&#xff1a; 图像生成…

案例-部门管理-删除

黑马程序员JavaWeb开发教程 文章目录 一、查看页面原型二、查看接口文档三、开发1、Controller2、Service&#xff08;1&#xff09;service接口层&#xff08;3&#xff09;service实现层 3、Mapper4、Postman 一、查看页面原型 二、查看接口文档 三、开发 1、Controller 因…

Keepalived+LVS实现Nginx集群配置

Nginx1和Nginx2组成集群&#xff0c;为了实现负载均衡&#xff0c;在集群的前端配置了LVS服务&#xff0c;但是一台LVS容器产生单点故障&#xff0c;因此需要过Keepalived实现LVS的高可用集群 192.168.136.55node1keepalived192.168.136.56node2keeplived192.168.136.57 node3n…

Excel 中用于在一个范围中查找特定的值,并返回同一行中指定列的值 顺序不一样 可以处理吗

一、需求 Excel 中&#xff0c;在一列&#xff08;某范围内&#xff09;查找另一列特定的值&#xff0c;并返回同一行中另一指定列的值&#xff0c; 查找列和返回列的顺序不一样 二、 实现 1、下面是一个使用 INDEX 和 MATCH 函数的例子&#xff1a; 假设你有以下数据&…

CI/CD:基于kubernetes的Gitlab搭建

1. 项目目标 &#xff08;1&#xff09;熟悉使用k8s环境搭建Gitlab &#xff08;2&#xff09;熟练应用Gitlab基本配置 2. 项目准备 2.1. 规划节点 主机名 主机IP 节点规划 k8s-master 10.0.1.1 kube_master k8s-node1 10.0.1.2 kube_node k8s-node2 10.0.1.3 k…

影响外汇交易盈利的因素有哪些?

外汇交易就是通过汇率的差价来赚取相应的利润。在外汇交易中&#xff0c;投资者是否可以盈利&#xff0c;主要取决于是否正确的判断了市场趋势和行情。投资者在交易过程中受到主观和客观的因素影响&#xff0c;具体包含这些内容。 影响外汇交易盈利的因素有哪些&#xff1f; 1、…

【酱浦菌-爬虫项目】爬取学术堂论文信息

1. 首先&#xff0c;代码定义了一个名为 url 的变量&#xff0c;它是一个包含三个网址的集合&#xff08;或者说是一个集合的字典&#xff09;。这些网址分别是&#xff1a; - ‘http://www.xueshut.com/lwtimu/127966.html’ - ‘http://www.xueshut.com/lwtimu/12…

nmap扫描工控设备的脚本支持

参考资料 转自&#xff08;http://www.360doc.com/content/15/1201/11/26186435_517125254.shtml&#xff09; 介绍 NMAP是一款强大的网络扫描工具&#xff0c;除了普通的TCP/IP网络扫描之外&#xff0c;NMAP的扩展脚本功能为我们提供了更为广阔的应用范围。 针对脚本学习可…

Python使用设计模式中的建筑模式将数据写入Excel且满足条件内容标红

对于这个任务&#xff0c;适合使用"Builder"设计模式。Builder模式的主要目的是将对象的构建与其表示分离&#xff0c;以便相同的构建过程可以创建不同的表示。在这个情况下&#xff0c;我们需要一个构建器来逐行构建Excel表格&#xff0c;并根据给定的数据添加相应的…