首页 文章 精选 留言 我的

精选列表

搜索[frame],共1873篇文章
优秀的个人博客,低调大师

flea-frame-db使用之JPA接入

JPA接入 本节内容需要了解JPA封装内容,请参见笔者 上篇博文。 准备工作 为了演示JPA接入,需要先准备如下: MySQL数据库 (客户端可以使用 navicat for mysql) 新建测试数据库 fleajpatest 新建测试表 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; 接入讲解 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方法 } 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; } } 3. 配置介绍 详细配置信息,可以参考笔者上篇博文,这里不再赘述。涉及文件 fleajpa-persistence.xml 和 applicationContext.xml 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; } 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; } } 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; } 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; } } 8. JPA接入自测 新增学生信息 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); } } 执行结果: 更新学生信息 @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); } } 运行结果: 删除学生信息 @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); } } 运行结果: 查询学生信息(按条件分页查询)表里自行再插入些数据,用于测试查询,查询结果因各自表数据而异;目前我表中数据如下: @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); } } 运行结果: 查询学生总数(按条件查询) @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-frame-db使用之封装JDBC接入

封装JDBC接入 本篇将要演示 FleaJDBCHelper 的使用,该工具类封装了基本的JDBC增删改查的操作,只需简单几步即可实现数据库操作。 1. 准备工作 为了演示JDBC接入(参考 JPA接入 中的准备工作),需要如下准备: MySQL数据库 (客户端可以使用 navicat for mysql) 新建测试数据库 fleajpatest 新建测试表 student 2. 接入讲解 2.1 JDBC数据源配置 数据源配置独立出来,定义在 flea-config.xml 中,可添加多个JDBC数据库配置【即 config-items 节点】。 <?xml version="1.0" encoding="UTF-8"?> <flea-config> <!-- 其他配置省略 --> <config-items key="mysql-fleajpatest" desc="JDBC数据库配置【key=数据库系统-数据库或数据库用户】"> <config-item key="driver" desc="mysql数据库驱动名">com.mysql.jdbc.Driver</config-item> <config-item key="url" desc="mysql数据库连接地址">jdbc:mysql://localhost:3306/fleajpatest?useUnicode=true&characterEncoding=UTF-8</config-item> <config-item key="user" desc="mysql数据库登录用户名">root</config-item> <config-item key="password" desc="mysql数据库登录密码">root</config-item> </config-items> </flea-config> 2.2 定义Flea数据库单元 -- FleaDBUnit 每个 FleaDBUnit 中, database 和 name 对应上述 config-items 中的 key;driver、url、user、password 分别对应上述 config-item 中的配置。 /** * <p> Flea 数据库单元 </p> * * @author huazie */ public class FleaDBUnit { private String database; // 数据库管理系统名 private String name; // 数据库名 或 数据库用户名 private String driver; // 数据库驱动名 private String url; // 数据库连接地址 private String user; // 数据库登录用户名 private String password; // 数据库登录密码 // 省略 set 和 get方法 } 2.3 定义Flea数据库操作类 -- FleaDBOperation FleaDBOperation 封装了JDBC的数据库操作对象,包括数据库连接对象 Connection、数据库预编译状态对象 PreparedStatement 和 数据库结果集对象 ResultSet。该类继承 Closeable,实现 close 方法,用于每次 JDBC 数据库操作后释放资源【这里用到了 try-with-resource 语法糖 】。 /** * <p> Flea数据库操作 </p> * * @author huazie */ public class FleaDBOperation implements Closeable { private Connection connection; private PreparedStatement preparedStatement; private ResultSet resultSet; @Override public void close() { FleaJDBCConfig.close(connection, preparedStatement, resultSet); } // 省略 set 和 get方法 } 2.4 定义Flea JDBC配置类 --- FleaJDBCConfig FleaJDBCConfig 中的 init(String mDatabase, String mName) 方法用于初始化本次操作的数据库管理系统【mDatabase】、数据库名或数据库用户 【mName】,两者对应数据库配置 config-items 中的 key 。 /** * <p> 读取数据库的配置信息,该信息存在于flea-config.xml中 </p> * * @author huazie */ public class FleaJDBCConfig { private static volatile FleaJDBCConfig config; private static final ConcurrentMap<String, FleaDBUnit> fleaDBUnits = new ConcurrentHashMap<>(); private FleaJDBCConfig() { } /** * <p> 读取数据库相关配置信息 </p> * * @return JDBC配置对象 */ public static FleaJDBCConfig getConfig() { if (ObjectUtils.isEmpty(config)) { synchronized (FleaJDBCConfig.class) { if (ObjectUtils.isEmpty(config)) { config = new FleaJDBCConfig(); } } } return config; } /** * <p> 使用之前先初始化 </p> * * @param mDatabase 数据库管理系统名称 * @param mName 数据库名 或 数据库用户 */ public static void init(String mDatabase, String mName) { FleaFrameManager.getManager().setDBConfigKey(mDatabase, mName); } /** * <p> 建立数据库连接 </p> * * @return 数据库连接对象 * @since 1.0.0 */ public Connection getConnection() { Connection conn = null; FleaDBUnit fleaDBUnit; String dbConfigKey = FleaFrameManager.getManager().getDBConfigKey(); if (!fleaDBUnits.containsKey(dbConfigKey)) { synchronized (fleaDBUnits) { if (!fleaDBUnits.containsKey(dbConfigKey)) { fleaDBUnits.put(dbConfigKey, getFleaDBUnit(dbConfigKey)); } } } fleaDBUnit = fleaDBUnits.get(dbConfigKey); try { // 请正确初始化数据库管理系统和数据库(或数据库用户) ObjectUtils.checkEmpty(fleaDBUnit, DaoException.class, "ERROR-DB-DAO0000000013"); Class.forName(fleaDBUnit.getDriver()); conn = DriverManager.getConnection(fleaDBUnit.getUrl(), fleaDBUnit.getUser(), fleaDBUnit.getPassword()); } catch (Exception e) { LOGGER.error("获取数据库连接异常 :{}", e.getMessage()); } return conn; } /** * <p> 读取指定配置键的数据库相关配置信息 </p> * * @param dbConfigKey 数据库配置键 * @return 数据库配置信息类对象 */ private FleaDBUnit getFleaDBUnit(String dbConfigKey) { FleaDBUnit fDBUnit = null; if (StringUtils.isNotBlank(dbConfigKey)) { fDBUnit = new FleaDBUnit(); String[] dbConfigKeyArr = StringUtils.split(dbConfigKey, CommonConstants.SymbolConstants.HYPHEN); if (ArrayUtils.isNotEmpty(dbConfigKeyArr) && CommonConstants.NumeralConstants.INT_TWO == dbConfigKeyArr.length) { fDBUnit.setDatabase(dbConfigKeyArr[0]); fDBUnit.setName(dbConfigKeyArr[1]); } fDBUnit.setDriver(FleaConfigManager.getConfigItemValue(dbConfigKey, DBConfigConstants.DB_CONFIG_DRIVER)); fDBUnit.setUrl(FleaConfigManager.getConfigItemValue(dbConfigKey, DBConfigConstants.DB_CONFIG_URL)); fDBUnit.setUser(FleaConfigManager.getConfigItemValue(dbConfigKey, DBConfigConstants.DB_CONFIG_USER)); fDBUnit.setPassword(FleaConfigManager.getConfigItemValue(dbConfigKey, DBConfigConstants.DB_CONFIG_PASSWORD)); } return fDBUnit; } /** * <p> 释放连接Connection </p> * * @param conn 数据库连接对象 */ private static void closeConnection(Connection conn) { try { if (ObjectUtils.isNotEmpty(conn)) { conn.close(); } } catch (SQLException e) { } } /** * <p> 释放statement </p> * * @param statement Statement对象 */ private static void closeStatement(Statement statement) { try { if (ObjectUtils.isNotEmpty(statement)) { statement.close(); } } catch (SQLException e) { } } /** * <p> 释放ResultSet结果集 </p> * * @param rs 结果集对象 */ private static void closeResultSet(ResultSet rs) { try { if (ObjectUtils.isNotEmpty(rs)) { rs.close(); } } catch (SQLException e) { } } /** * <p> 释放资源 </p> * * @param conn 数据库连接对象 * @param statement 数据库状态对象 * @param rs 数据库结果集对象 */ public static void close(Connection conn, Statement statement, ResultSet rs) { closeResultSet(rs); closeStatement(statement); closeConnection(conn); } // 省略一些close方法 } 上述 init 方法中,使用了 FleaFrameManager.getManager().setDBConfigKey,这里是将 JDBC连接的数据库配置添加到了线程对象中 ThreadLocal 中,代码如下: // 当前线程采用JDBC连的数据库前缀配置 private static ThreadLocal<String> sDBLocal = new ThreadLocal<>(); /** * <p> 获取当前线程中使用JDBC连接的数据库配置键 </p> * * @return 当前线程中使用JDBC连接的数据库配置键 */ public String getDBConfigKey() { return sDBLocal.get(); } /** * <p> 设置当前线程中使用JDBC连接的数据库配置键 </p> * * @param dbSysName 数据库系统名 * @param dbName 数据库名 */ public void setDBConfigKey(String dbSysName, String dbName) { if (StringUtils.isNotBlank(dbSysName) && StringUtils.isNotBlank(dbName)) { sDBLocal.set(dbSysName.toLowerCase() + CommonConstants.SymbolConstants.HYPHEN + dbName.toLowerCase()); } } 2.4 定义 Flea JDBC工具类 --- FleaJDBCHelper 在使用 FleaJDBCHelper 之前,一定要先调用一下 init。 3. 接入自测 -- StudentJDBCTest 3.1 JDBC新增数据 @Test public void testStudentInsert() throws Exception { // 初始化数据库配置,用于获取具体操作数据源 FleaJDBCConfig.init(DBSystemEnum.MySQL.getName(), "fleajpatest"); String sql = "insert into student(stu_name, stu_age, stu_sex, stu_state) values(?, ?, ?, ?)"; List<Object> paramList = new ArrayList<Object>(); paramList.add("huazie"); paramList.add(25); paramList.add(1); paramList.add(1); int ret = FleaJDBCHelper.insert(sql, paramList); LOGGER.debug("RESULT = {}", ret); } 执行结果: 3.2 JDBC查询数据 这里的查询语句,可以是复杂SQL,返回结果 List<Map<String, Object>> @Test public void testStudentQuery() throws Exception { FleaJDBCConfig.init(DBSystemEnum.MySQL.getName(), "fleajpatest"); String sql = "select * from student where stu_state = ?"; List<Object> paramList = new ArrayList<Object>(); paramList.add(1); LOGGER.debug("RESULT LIST = {}", FleaJDBCHelper.query(sql, paramList)); } 执行结果: @Test public void testStudentSingleQuery() throws Exception { FleaJDBCConfig.init(DBSystemEnum.MySQL.getName(), "fleajpatest"); String sql = "select count(*) from student where stu_state = ?"; List<Object> paramList = new ArrayList<Object>(); paramList.add(1); LOGGER.debug("COUNT = {}", FleaJDBCHelper.querySingle(sql, paramList)); } 执行结果: 3.3 JDBC更新数据 @Test public void testStudentUpdate() throws Exception { FleaJDBCConfig.init(DBSystemEnum.MySQL.getName(), "fleajpatest"); String sql = "update student set stu_state = ? where stu_name = ?"; List<Object> paramList = new ArrayList<Object>(); paramList.add(2); paramList.add("huazie"); int ret = FleaJDBCHelper.update(sql, paramList); LOGGER.debug("RESULT = {}", ret); } 执行结果: 3.4 JDBC删除数据 @Test public void testStudentDelete() throws Exception { FleaJDBCConfig.init(DBSystemEnum.MySQL.getName(), "fleajpatest"); String sql = "delete from student where stu_name = ? and stu_state = ? "; List<Object> paramList = new ArrayList<Object>(); paramList.add("huazie"); paramList.add(2); int ret = FleaJDBCHelper.delete(sql, paramList); LOGGER.debug("RESULT = {}", ret); } 执行结果:

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册