flea-db使用之JPA接入

2023-10-26

本节内容需要了解JPA封装内容,请参见笔者 上篇博文

1. 准备工作

为了演示JPA接入,需要先准备如下:

  1. MySQL数据库 (客户端可以使用 navicat for mysql)

  2. 新建测试数据库 fleajpatest
    在这里插入图片描述

  3. 新建测试表 student
    在这里插入图片描述
    建表语句如下:

    DROP TABLE IF EXISTS `student`;
    CREATE TABLE `student` (
      `stu_id` int(10) NOT NULL AUTO_INCREMENT COMMENT '学生编号',
      `stu_name` varchar(255) NOT NULL COMMENT '学生姓名',
      `stu_age` tinyint(2) NOT NULL COMMENT '学生年龄',
      `stu_sex` tinyint(1) NOT NULL COMMENT '学生性别(1:男 2:女)',
      `stu_state` tinyint(2) NOT NULL COMMENT '学生状态(0:删除 1:在用)',
      PRIMARY KEY (`stu_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    

2. 接入讲解

2.1 实体类

新建如下实体类Student,对应测试表student

/**
 * <p> 学生表对应的实体类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
@Entity
@Table(name = "student")
public class Student implements FleaEntity {

    private static final long serialVersionUID = 1267943552214677159L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "STUDENT_SEQ")
    @SequenceGenerator(name = "STUDENT_SEQ")
    @Column(name = "stu_id", unique = true, nullable = false)
    private Long stuId; // 学生编号

    @Column(name = "stu_name", nullable = false)
    private String stuName; // 学生姓名

    @Column(name = "stu_age", nullable = false)
    private Integer stuAge; // 学生年龄

    @Column(name = "stu_sex", nullable = false)
    private Integer stuSex; // 学生性别(1:男 2:女)

    @Column(name = "stu_state", nullable = false)
    private Integer stuState; // 学生状态(0:删除 1:在用)

	// ... 省略get和set方法
    
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}

2.2 持久化单元DAO层实现

上篇博文说到,增加一个持久化单元配置,便需要增加一个持久化单元DAO层实现。针对本次演示新增持久化单元 fleajpa,持久化配置文件 fleajpa-persistence.xml, Spring配置中新增数据库事务管理者配置,相关内容可参考上一篇博文。下面贴出本次演示的持久化单元DAO层实现代码:

/**
 * <p> FleaJpa数据源DAO层父类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public class FleaJpaDAOImpl<T> extends AbstractFleaJPADAOImpl<T> {
	// 持久化单元,持久化配置文件中定义,spring配置中持久化接口工厂初始化参数
    @PersistenceContext(unitName="fleajpa")
    protected EntityManager entityManager;

    @Override
    // 持久化事务管理者, spring配置文件中定义
    @Transactional("fleaJpaTransactionManager")
    public boolean remove(long entityId) throws Exception {
        return super.remove(entityId);
    }

	// ...其他实现省略

    @Override
    protected EntityManager getEntityManager() {
        return entityManager;
    }

}

2.3 配置介绍

详细配置信息,可以参考笔者上篇博文,这里不再赘述。
涉及文件 fleajpa-persistence.xmlapplicationContext.xml

2.4 学生DAO层接口

IStudentDAO 继承了抽象Flea JPA DAO层接口,并定义了两个方法,分别获取学生信息列表(分页)和学生总数。

/**
 * <p> 学生DAO层接口 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public interface IStudentDAO extends IAbstractFleaJPADAO<Student> {

    /**
     * <p> 学生信息列表 (分页) </p>
     *
     * @param name      学生姓名,可以模糊查询
     * @param sex       性别
     * @param minAge    最小年龄
     * @param maxAge    最大年龄
     * @param pageNum   查询页
     * @param pageCount 每页总数
     * @return 学生信息列表
     * @throws DaoException 数据操作层异常
     * @since 1.0.0
     */
    List<Student> getStudentList(String name, Integer sex, Integer minAge, Integer maxAge, int pageNum, int pageCount) throws DaoException;

    /**
     * <p> 学生总数 </p>
     *
     * @param name   学生姓名,可以模糊查询
     * @param sex    性别
     * @param minAge 最小年龄
     * @param maxAge 最大年龄
     * @return 学生总数
     * @throws DaoException 数据操作层异常
     * @since 1.0.0
     */
    int getStudentCount(String name, Integer sex, Integer minAge, Integer maxAge) throws DaoException;

}

2.5 学生DAO层实现

StudentDAOImpl 是学生信息的数据操作层实现,继承持久化单元DAO层实现类,并实现了上述学生DAO层接口自定义的两个方法。 具体如何使用 FleaJPAQuery 可以参见下面代码 :

/**
 * <p> 学生DAO层实现类 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
@Repository("studentDAO")
public class StudentDAOImpl extends FleaJpaDAOImpl<Student> implements IStudentDAO {

    @Override
    @SuppressWarnings(value = "unchecked")
    public List<Student> getStudentList(String name, Integer sex, Integer minAge, Integer maxAge, int pageNum, int pageCount) throws DaoException {
        FleaJPAQuery query = initQuery(name, sex, minAge, maxAge, null);
        List<Student> studentList;
        if (pageNum > 0 && pageCount > 0) {
        	// 分页查询
            studentList = query.getResultList((pageNum - 1) * pageCount, pageCount);
        } else {
        	// 全量查询
            studentList = query.getResultList();
        }
        return studentList;
    }

    @Override
    @SuppressWarnings(value = "unchecked")
    public long getStudentCount(String name, Integer sex, Integer minAge, Integer maxAge) throws DaoException {
        FleaJPAQuery query = initQuery(name, sex, minAge, maxAge, Long.class);
        // 统计数目
        query.countDistinct();
        Object result = query.getSingleResult();
        return Long.parseLong(StringUtils.valueOf(result));
    }

    private FleaJPAQuery initQuery(String name, Integer sex, Integer minAge, Integer maxAge, Class<?> result) throws DaoException{
        FleaJPAQuery query = getQuery(result);
        // 拼接 查询条件
        // 根据姓名 模糊查询, attrName 为 实体类 成员变量名,并非表字段名
        if (StringUtils.isNotEmpty(name)) {
            query.like("stuName", name);
        }
        // 查询性别
        if (ObjectUtils.isNotEmpty(sex)) {
            query.equal("stuSex", sex);
        }
        // 查询年龄范围
        if (ObjectUtils.isNotEmpty(minAge)) {
            // 大于等于
            query.ge("stuAge", minAge);
        }
        if (ObjectUtils.isNotEmpty(maxAge)) {
            // 小于等于
            query.le("stuAge", maxAge);
        }
        return query;
    }
}

2.6 学生SV层接口

IStudentSV 继承抽象Flea JPA SV层接口,并定义两个方法,分别获取学生信息列表(分页)和学生总数。

/**
 * <p> 学生SV层接口定义 </p>
 *
 * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
public interface IStudentSV extends IAbstractFleaJPASV<Student> {

    /**
     * <p> 学生信息列表 (分页) </p>
     *
     * @param name      学生姓名,可以模糊查询
     * @param sex       性别
     * @param minAge    最小年龄
     * @param maxAge    最大年龄
     * @param pageNum   查询页
     * @param pageCount 每页总数
     * @return 学生信息列表
     * @throws DaoException 数据操作层异常
     * @since 1.0.0
     */
    List<Student> getStudentList(String name, Integer sex, Integer minAge, Integer maxAge, int pageNum, int pageCount) throws DaoException;

    /**
     * <p> 学生总数 </p>
     *
     * @param name   学生姓名,可以模糊查询
     * @param sex    性别
     * @param minAge 最小年龄
     * @param maxAge 最大年龄
     * @return 学生总数
     * @throws DaoException 数据操作层异常
     * @since 1.0.0
     */
    long getStudentCount(String name, Integer sex, Integer minAge, Integer maxAge) throws DaoException;

}

2.7 学生SV层实现

StudentSVImpl 继承抽象Flea JPA SV层实现类,并实现了上述学生SV层接口的两个自定义方法。具体实现参见如下代码:

/**
 * <p> 学生SV层实现类 </p>
 *  * @author huazie
 * @version 1.0.0
 * @since 1.0.0
 */
@Service("studentSV")
public class StudentSVImpl extends AbstractFleaJPASVImpl<Student> implements IStudentSV {
	// 注入学生DAO层实现类
    @Autowired
    @Qualifier("studentDAO") 
    private IStudentDAO studentDao; 

    @Override
    public List<Student> getStudentList(String name, Integer sex, Integer minAge, Integer maxAge, int pageNum, int pageCount) throws DaoException {
        return studentDao.getStudentList(name, sex, minAge, maxAge, pageNum, pageCount);
    }

    @Override
    public long getStudentCount(String name, Integer sex, Integer minAge, Integer maxAge) throws DaoException {
        return studentDao.getStudentCount(name, sex, minAge, maxAge);
    }
	// 可参见AbstractFleaJPASVImpl里的实现
    @Override
    protected IAbstractFleaJPADAO<Student> getDAO() {
        return studentDao;
    }
}

2.8 JPA接入自测

2.8.1 新增学生信息

	private ApplicationContext applicationContext;

    @Before
    public void init() {
        applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        LOGGER.debug("ApplicationContext={}", applicationContext);
    }
	
	@Test
    public void testInsertStudent() {
        try {
            IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV");
            Student student = new Student();
            student.setStuName("张三");
            student.setStuAge(18);
            student.setStuSex(1);
            student.setStuState(1);
            studentSV.save(student);

            student = new Student();
            student.setStuName("李四");
            student.setStuAge(19);
            student.setStuSex(1);
            student.setStuState(1);
            studentSV.save(student);

            student = new Student();
            student.setStuName("王二麻子");
            student.setStuAge(20);
            student.setStuSex(1);
            student.setStuState(1);
            studentSV.save(student);

        } catch (Exception e) {
            LOGGER.error("Exception : ", e);
        }
    }

执行结果:
在这里插入图片描述

2.8.2 更新学生信息

 	@Test
    public void testStudentUpdate() {
        try {
            IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV");
            // 根据主键查询学生信息
            Student student = studentSV.query(3L);
            LOGGER.debug("Before : {}", student);
            student.setStuName("王三麻子");
            student.setStuAge(19);
            // 更新学生信息
            studentSV.update(student);
            // 最后再根据主键查询学生信息
            student = studentSV.query(3L);
            LOGGER.debug("After : {}", student);
        } catch (Exception e) {
            LOGGER.error("Exception : ", e);
        }
    }

运行结果:
在这里插入图片描述

2.8.3 删除学生信息

    @Test
    public void testStudentDelete() {
        try {
            IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV");
            // 根据主键查询学生信息
            Student student = studentSV.query(3L);
            LOGGER.debug("Before : {}", student);
            // 删除学生信息(里面会先去将学生实体信息查出来,然后再删除)
            studentSV.remove(3L);
            // 最后再根据主键查询学生信息
            student = studentSV.query(3L);
            LOGGER.debug("After : {}", student);
        } catch (Exception e) {
            LOGGER.error("Exception : ", e);
        }
    }

运行结果:
在这里插入图片描述

2.8.4 查询学生信息(按条件分页查询)

表里自行再插入些数据,用于测试查询,查询结果因各自表数据而异;
目前我表中数据如下:
在这里插入图片描述

  	@Test
    public void testStudentQueryPage() {
        try {

            IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV");
            List<Student> studentList = studentSV.getStudentList("张三", 1, 18, 20, 1, 5);
            LOGGER.debug("Student List = {}", studentList);
        } catch (Exception e) {
            LOGGER.error("Exception : ", e);
        }
    }

运行结果:
在这里插入图片描述

2.8.5 查询学生总数(按条件查询)

	@Test
    public void testStudentQueryCount() {
        try {
            IStudentSV studentSV = (IStudentSV) applicationContext.getBean("studentSV");
            long count = studentSV.getStudentCount("张三", 1, 18, 20);
            LOGGER.debug("Student Count = {}", count);
        } catch (Exception e) {
            LOGGER.error("Exception : ", e);
        }
    }

运行结果:
在这里插入图片描述

总结

看到这里,我们的JPA接入工作已经成功完成,本demo工程可以移步到GitHub查看 flea-jpa-test
在JPA封装介绍博文中,针对Flea JPA查询对象还存在的一个并发问题,将在后续的博文《flea-db使用之基于对象池的FleaJPAQuery》中介绍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

flea-db使用之JPA接入 的相关文章

  • 51单片机实现串口通信(主单片机到从单片机发送LED流水灯)

    其实这是个51单片机串口通信的小例子 课堂上老师说你们可以去尝试弄一下 于是就去网上找一下资料 就做了这个实验 先把一个作为主机 用来发送数据 另一个作为从机 用来接收数据 将两个程序各自烧录到对应的板子上去 并将主机的TX P3 0 接到
  • VS C++ 生成类图

    C 中如何快速清晰的了解定义类型及类型之间的关联关系 一个好的类图有助于你快速了解 那么怎么去生成一个类图呢 下面步骤可以帮到你 一 安装类设计器组件 1 确定是否已经安装 类设计器 如果未安装 可以打开 工具 gt 获取工具和功能 或者直
  • springboot Junit单元测试默认事务不提交

    目录 一 Junit初次使用 二 Junit事务问题 1 默认不提交事务 默认回滚 2 设置rollback 让Junit提交事务 一 Junit初次使用 因为以前总觉得Junit单元测试配置比较繁琐 代码功能大多使用main方法或者pos
  • SD秋叶安装教程

    前言 本部署整合包基于开源项目 stable diffusion webui制作 部署包作者 秋葉aaaki 免责声明 本安装包及启动器免费提供 无任何盈利目的 电脑配置要求 操作系统 windows10以后 CPU 不做强制要求 内存 推
  • 输出斐波那契数列的每一项,每五个换行

    7 2 利用数组计算斐波那契数列 15 分 本题要求编写程序 利用数组计算菲波那契 Fibonacci 数列的前N项 每行输出5个 题目保证计算结果在长整型范围内 Fibonacci数列就是满足任一项数字是前两项的和 最开始两项均定义为1
  • FFmpeg录制流

    FFmpeg下windows安装 下载地址 http ffmpeg org download html windows 下载 ffmpeg release essentials zip 这个文件名 解压后将bin目录加到环境变量path 录
  • 内存使用(分段、分区、分页、多级页表、快表)--OS

    内存使用 内存使用 将程序放在内存中 PC指向内存地址 首先 我们需要让程序进入内存 举个例子 int main int argc char argv text entry 入口地址 call main call exit main ret

随机推荐

  • windows默认文件(桌面、下载、文档等)设置为C盘根路径后怎么修改回去

    桌面 下载 文档等设置为C盘根路径后怎么修改回去 1 问题 2 解决办法 2 1 按 Win R 调出运行窗口 输入 regedit 并按回车 2 2 在弹出的注册表窗口里 打开下面路径 计算机 HKEY CURRENT USER SOFT
  • 数据结构——迪杰斯特拉(Dijkstra)算法

    迪杰斯特拉算法又叫狄克斯特拉算法 是从一个顶点到其余各顶点的最短路径算法 解决的是有权图中最短路径问题 迪杰斯特拉算法主要特点是从起始点开始 采用贪心算法的策略 每次遍历到始点距离最近且未访问过的顶点的邻接节点 直到扩展到终点为止 以下是数
  • 【Golang】切片(slice)

    文章目录 切片 直接声明新的切片 append 函数为切片添加元素 复制切到另一个切片 从切片中删除元素 从开头位置删除 从中间位置删除 从尾部删除 切片 切片 slice 是对数组的一个连续片段的引用 所以切片是一个引用类型 这个片段可以
  • scss 转为 less

    tnpm install less plugin sass2less g sass2less scss dir name less rm rf scss 转载于 https www cnblogs com lyraLee p 1048966
  • virtualbox的虚拟机联不通外网的问题

    问题描述 在网卡配置上按照网上的操作配置好了 但是仍然联不通外网 ip地址显示为127 0 0 1 解决 通过输入dhclient v命令解决
  • Spring框架常用注解及通配符总结

    Autowired 自动注入 默认是类型匹配 使用配置文件需要set 使用注解不需要 只需要类属性 Autowired可以和 Qualifier beanName 配合着使用 Qualifier beanName 多个相同类型的bean 标
  • 基于深度学习的目标检测方法综述

    引言 现有的深度学习的目标检测方法 可以大致分为两类 一 基于候选区域的目标检测方法 二 基于回归的目标检测方法 依据方法的提出时间 可以构建出如下时间线 2014 CVPR R CNN 1 2015 arXiv DenseBox 14 2
  • 「开源项目」现代化开源Linux服务器运维管理面板-1Panel

    1Panel 基本介绍 1Panel 是新一代的 Linux 服务器运维管理面板 产品优势 快速建站 深度集成 Wordpress 和 Halo 域名绑定 SSL 证书配置等一键搞定 高效管理 通过 Web 端轻松管理 Linux 服务器
  • arm汇编中感叹号/叹号的作用

    arm汇编中存在一个神奇的可选后缀 一般是在寄存器或寻址方式之后 对于加了叹号的情况 访问内存时先根据寻址方式更改寄存器的值 再按照该已经更新的值访问内存
  • 基于深度学习的目标检测算法概述

    摘要 目标检测是计算机视觉的一个重要分支 其目的是准确判断图像或视频中的物体类别并定位 传统的目标检测方法包括这三个步骤 区域选择 提取特征和分类回归 这样的检测方法存在很多问题 现已难以满足检测对性能和速度的要求 基于深度学习的目标检测方
  • 电子元器件/模块供应商汇总

    晶振 WIFI MLCC电容
  • Python制作模拟按键摘录,pyautogui库及该库在某些窗口不生效的问题部分解决措施(PyDirectInput库、winio驱动级模拟)

    文章目录 toc 一 使用pyautogui库 1 安装pyautogui库 2 导入并在py中使用 1 导包 2 基本鼠标控制 3 基本键盘控制 4 屏幕截图 5 图片位置识别 3 存在问题 二 使用PyDirectInput库解决某些游
  • 机器学习——数据清洗,特征选择

    数据清洗的方法 设置阈值去掉异常值 随机森林预测去掉点的数值加进去 onehot编码 不适用于决策树和随机森林 先将一个属性分成几个类别 然后再将样本的数据变成矩阵01 1表示其所在类别 会导致特征数增多 数据清洗代码实现 import n
  • Linux磁盘扩容详解

    公司项目服务器是买的阿里的 原来的项目是外包出去别人做的 用户图片上传保存到了服务器上 500G的磁盘空间硬生生给用完了 怎么搞 扩容呗 大概思路就是从阿里那再买一块磁盘 添加到ESC实例上 然后挂载 然后格式化磁盘文件 然后把老图片mv过
  • STL sort排序算法详细介绍

    用于C 中 对给定区间所有元素进行排序 头文件是 include
  • selenium中键盘操作:Keys类

    一 前言 selenium提供了比较完整的键盘操作 在使用的模拟键盘操作之前需要我们导入Keys类 from selenium webdriver common keys import Keys 二 常用的非组合键操作 1 回车键 Keys
  • python循环综合运用

    循环很重要 计算机很蠢 唯一的优势就是按照指令不停的执行 所以决定在说一下 break语句 用在循环体中 迫使循环立即终止 即跳出所在循环体 继续执行循环体后面的语句 sum 0 i 1 while i sum i i 1 if i gt
  • 生成随机mask以及根据mask对两幅图片进行合并

    前言 对图像处理的一些操作还是需要掌握的嘿嘿 随机mask生成 这里代码参考MAT的一份代码 https github com fenglinglwb MAT blob main datasets mask generator 256 py
  • 机器人学基础(2)-微分运动和速度-雅可比矩阵计算、雅可比矩阵求逆、计算关节运动速度

    机器人学基础 2 微分运动和速度 雅可比矩阵计算 雅可比矩阵求逆 计算关节运动速度 本文知识点 坐标系的微分运动 坐标系之间的微分变化 机器人和机器人手坐标系的微分运动 雅可比矩阵的计算 雅可比矩阵求逆 雅可比矩阵和微分算子之间的关联 文章
  • flea-db使用之JPA接入

    JPA接入 1 准备工作 2 接入讲解 2 1 实体类 2 2 持久化单元DAO层实现 2 3 配置介绍 2 4 学生DAO层接口 2 5 学生DAO层实现 2 6 学生SV层接口 2 7 学生SV层实现 2 8 JPA接入自测 2 8 1