为了避免sql编写在Java代码里面,所以实现类型mybaits的功能,把sql语句编写在xml文件中,这样可以统一管理sql语句,维护更加容易。
1. 首先编写配置sql语句的xml的dtd文件,dtd文件主要是规范xml的,在编写sql语句的配置文件中主要有五个标签:select , update , insert , delete , import
其中select有两个属性id(保证所有的sql语句id唯一),resultClass(查询语句返回的对象,可以使具体的实体类,也可以是Map,List);import只有一个resource属性,指定导入的xml的位置,其他的标签都只有一个id属性。dtd文件如下,存放在hqhop-framework-common项目的/src/main/resources/META-INF下:
</pre><pre name="code" class="html"><!ELEMENT sqls-configs (import | insert | delete | update | select )*> <!ELEMENT insert (#PCDATA)> <!ATTLIST insert id ID #REQUIRED> <!ELEMENT delete (#PCDATA)> <!ATTLIST delete id ID #REQUIRED> <!ELEMENT update (#PCDATA)> <!ATTLIST update id ID #REQUIRED> <!ELEMENT select (#PCDATA)> <!ATTLIST select resultClass CDATA #REQUIRED> <!ATTLIST select id ID #REQUIRED> <!ELEMENT import EMPTY> <!ATTLIST import resource CDATA #REQUIRED>
2. sql配置文件的参考事例:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sqls-configs PUBLIC "-//SQLS//MAIN CONFIG DTD//EN" "http://kf.hqhop.com:8888/hqhop-framework-sqls.dtd"> <sqls-configs> <select <span style="color:#ff0000;">id="select1"</span> resultClass="<span style="color:#ff0000;">com.hqhop.framework.shiro.entity.User</span>"> select * from t_base_user where id =:id </select><pre name="code" class="html"><span style="white-space:pre"> </span><select <span style="color:#ff0000;">id="select2"</span> resultClass="<span style="color:#ff0000;">java.util.Map</span>"> select * from t_base_user where id = ? </select>
<pre name="code" class="html"><span style="white-space:pre"> </span><select <span style="color:#ff0000;">id="select3" </span>resultClass="<span style="color:#ff0000;">java.util.List</span>"> select * from t_base_user where id = ? </select>
<update id="update"></update><insert id="insert"></insert><delete id="delete"></delete><import resource="classpath:sql/test.xml" /></sqls-configs>
3. 解析sql的配置文件,类目录结构
实现主要就用到了这4个类,首先把每一条sql语句的信息存放到SQL对象中,然后在把SQL对象和配置的sql的id对应存放到SQLContext,当我们在使用的时候就直接去SQLContext中去取。
SQL.java
public class SQL { private String id; //sql的id private String sql; //具体的sql private Class resultClass; //返回的实体类,只对select标签有效 public SQL(String id, String sql, String resultClass) { this.id = id; this.sql = sql; try { if (Utils.isNotEmpty(resultClass)) this.resultClass = Class.forName(resultClass); else this.resultClass = null; } catch (ClassNotFoundException e) { e.printStackTrace(); } }<pre name="code" class="java"> //get set....
}
SQLContext.java
public class SQLContext { <span style="white-space:pre"> </span>//仅仅一个属性,使用map存放每一个sql语句,使用的时候更加key来找到sql private Map<String, SQL> sqls = new HashMap<>(); public SQL getSQL(String sqlKey) { return sqls.get(sqlKey); } public Set<String> getKeys() { return sqls.keySet(); } public void put(String sqlKey, SQL sql) { this.sqls.put(sqlKey, sql); } public boolean checkKeyIsExist(String key) { return this.sqls.containsKey(key); } }
4. 解析sql的xml文件主要是在SQLContextFileBuilder中完成的,是一个的单例模式
1) 首先解析import标签,使用递归的方式把所有import的xml加载到一个document,实现的方法是public Document loadFullConfigFile(Resource resource, String encoding)
// 解析import包含的子配置文件 public Document loadFullConfigFile(Resource resource, String encoding) throws UnsupportedEncodingException, IOException, DocumentException { SAXReader reader = null; Document document = null; reader = new SAXReader(); InputStreamReader isr = null; try { isr = new InputStreamReader(resource.getInputStream(), encoding); document = reader.read(isr); } finally { CloseUtil.close(isr); } final Element root = document.getRootElement(); List list = document.selectNodes("//import"); for (int i = 0; i < list.size(); i++) { Element n = (Element) list.get(i); String file = n.attribute("resource").getValue(); Resource fr = SpringUtils.getResource(file); <span style="color:#ff0000;">Document includedDoc = loadFullConfigFile(fr, encoding);</span> List content = root.content(); int indexOfPos = content.indexOf(n); content.remove(indexOfPos); Element ie = includedDoc.getRootElement(); List ie_children = ie.content(); for (int k = ie_children.size() - 1; k >= 0; k--) { content.add(indexOfPos, ie_children.get(k)); } } this.rootDoc = document.getRootElement(); return document; }
2) 再从document中解析出所有的sql语句,创建SQL对象,存放到SQLContext中
public SQLContext loadSQLContext() { SQLContext sqlContext = new SQLContext(); List els = rootDoc.elements(); for (Object o : els) { Element element = (Element) o; String idKey = element.attribute("id").getValue(); String sql = element.getTextTrim(); Attribute attribute = element.attribute("resultClass"); String resultClass = Utils.isNotEmpty(attribute) ? attribute.getValue() : null; <span style="color:#ff0000;">//判断sql的id是否已经存在 ,若存在就抛出异常</span> if (<span style="color:#ff0000;">!sqlContext.checkKeyIsExist(idKey)</span>) { sqlContext.put(idKey, new SQL(idKey, sql, resultClass)); } else { throw new RuntimeException("请检查sql的配置文件,sql的key已经存在(key=" + idKey + ")!"); } } return sqlContext; }
5. 让spring容器启动就去加载sql的xml文件:SQLContextFactory.java 只有一个方法,
public static SQLContext createSQLContext(Resource springResource){......} 完成解析xml文件,返回sqlContext
在spring的xml配置文件中添加如下代码来完成SQLContext的创建:
<bean id="sqlContext" class="com.hqhop.framework.common.orm.sql.SQLContextFactory" factory-method="createSQLContext"> <constructor-arg> <!-- 指定sql文件的位置 --> <value><span style="color:#ff0000;">classpath:sqls/sql.xml</span></value> </constructor-arg> </bean>
6. 到此为止sqlContext已经存在了spring容器中了,接下来就在BaseRepoitoryImpl中来使用sqlContext,在BaseRepoitory中定义了几个使用sql的xml的接口,这里就只说明一个接口就行了:
public List<T> findAll(String sqlKey, Object... params) {....}
@Autowired private SQLContext sqlContext; public List<T> findAll(String sqlKey, Object... params) { SQL sql = this.sqlContext.getSQL(sqlKey); SQLQuery sqlQuery = this.getSession().createSQLQuery(sql.getSql()); RepositoryHelper.setValues(sqlQuery, params); RepositoryHelper.setResultTransformer(sqlQuery, sql.getResultClass()); return sqlQuery.list(); }
1) 传入一个sql的id,然后通过sqlContext来获取对应的SQL对象,通过RepoitoryHelper.setValues(...)来设置参数的值,这里传入的params可以使多个参数值,也可以是一个map对象,具体使用什么就要根据编写的sql来决定
select * from t_base_user where id =:id 这种方式只能传入map对象
select * from t_base_user where id = ? 这种方式只能传入对个参数值
RepositoryHelper.setValues(.....)代码如下:
public static void setValues(Query query, Object... params) { if (params[0] instanceof Map) { Map mapParams = (Map) params[0]; Set<String> keys = mapParams.keySet(); for (String key : keys) { query.setParameter(key, mapParams.get(key)); } } else { int paramIndex = 0; for (Object o : params) { query.setParameter(paramIndex++, o); } } }
2) 绑定查询出来的数据应该转化成什么对象,使用RepositoryHelper.setResultTransformer(...)来完成的,这里的resultClass是在sql的xml文件中指定的,只对select标签有效:
public static void setResultTransformer(SQLQuery query, Class resultClass) { if (Utils.isNotEmpty(resultClass)) { if (<span style="color:#ff0000;">resultClass.equals(List.class)</span>) { query.setResultTransformer(Transformers.TO_LIST); } else if (<span style="color:#ff0000;">resultClass.equals(Map.class)</span>) { query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); } else { query.addEntity(resultClass); } } }
其他使用sql的xml接口的实现方式都类似。
相关推荐
手写mybaits框架代码手写mybaits框架代码手写mybaits框架代码手写mybaits框架代码手写mybaits框架代码手写mybaits框架代码手写mybaits框架代码手写mybaits框架代码手写mybaits框架代码手写mybaits框架代码手写...
在IT行业中,Spring和Hibernate是两个非常重要的框架,它们分别专注于不同的领域。Spring是一个全面的后端开发框架,提供依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)等特性,使得Java应用的构建变得...
在Java企业级应用开发中,Spring、Hibernate、XFire(现已被Apache CXF替代)和MyBatis是四大常用的开源框架,它们各自负责不同的领域,共同构建了一个高效、灵活的开发环境。"SPRING_HIBERNATE_XFIRE_MYBAITS_JAR包...
在使用过程中,如有问题或建议,请及时私信沟通,帮助解答。 【2】项目主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。...
标题 "idea插件mybaits log 打印sql语句" 涉及的是一个针对IntelliJ IDEA的MyBatis日志插件,它的主要功能是帮助开发者在开发过程中实时查看并打印出MyBatis执行的SQL语句。这个功能对于调试和优化数据库查询非常...
这个主题,"mybaits-spring配置",主要涵盖了如何将MyBatis 3.1.1版本与Spring 3.0.5版本集成,并通过使用mybatis-spring-1.1.1.jar库来实现数据访问层(DAO)的无缝配合。下面将详细解释这一整合过程中的关键知识点...
动态SQL是MyBatis框架中的一项重要技术,它极大地提升了开发人员编写SQL语句的灵活性和效率。传统的JDBC编程中,开发者需要手动拼接SQL语句,稍有不慎就会引入错误。而MyBatis的动态SQL功能通过一系列的标签来构建可...
"Mybaits+sqlserver小例子"是一个很好的起点,它展示了如何在Java项目中使用MyBatis连接SQL Server数据库并执行基本的查询操作。对于初学者来说,理解这些概念和步骤是掌握MyBatis的关键。通过实践这个小例子,你...
在Web开发中,SSI(Struts、Spring、MyBatis)框架的整合是常见的技术栈,它结合了三个强大的开源组件来构建灵活、可维护的Java应用程序。Struts提供了MVC(Model-View-Controller)架构,Spring作为依赖注入容器和...
Spring MVC 和 MyBatis 是两个在 Java Web 开发中广泛使用的框架。Spring MVC 作为 Spring 框架的一部分,主要用于构建 MVC(Model-View-Controller)模式的 Web 应用程序,而 MyBatis 是一个优秀的持久层框架,它...
【标题】"SPRING_HIBERNATE_XFIRE_MYBAITS_JAR包"涉及的关键技术是Spring、Hibernate、XFire和MyBatis,这些都是Java开发中的核心框架和库。它们在企业级应用开发中扮演着重要的角色,尤其在构建分布式、数据库驱动...
标题"mybatis-3.2.jar"指的是MyBatis框架的3.2版本的Java档案文件(JAR),这是一个包含所有MyBatis库的可执行文件,开发者可以在自己的项目中引入这个JAR来使用MyBatis的功能。 描述中的"mybatis-3.2 ibatis"提到...
在IT行业中,开发Java应用程序时,常常需要依赖各种库来实现功能,如数据持久化、对象关系映射、JSON处理等。"spring mybaits hibernate jar包"这个压缩文件包含了一系列常用库的jar包,这些库对于构建基于Java的...
1、基于yml 配置方式 ,实现springBoot+sharding-jdbc+mybatis-plus 实现分库分表,读写分离,以及全局表,子表的配置。 2、实现mybatis-plus 整合到springboot 详细使用请看 测试用例
搭建Spring、SpringMVC和MyBatis这三大框架是Java Web开发中的常见任务,它们各自在应用程序的不同层次上提供服务,构建出一个完整的MVC(Model-View-Controller)架构。下面将详细介绍这三个框架以及如何将它们整合...
只需要在springboot的配置文件做简单的配置,mybatis拦截器将SQL中所有参数自动做了填充。拦截器监控慢SQL并将完整的可执行的SQL语句打印在日志文件中,复制该SQL语句即可在数据库工具中执行。 使用方法: 找到你...
该项目是基于SpringBoot + Vue +MyBatis的实验室助理信息管理系统-可用于大学生日常课设 功能点描述: (1)学生 ... (2)实验室技术员 筛选报名信息、实验室助理招聘计划的申请 (3)学工处 审核招聘计划(修改招聘人数...
标题中的"SpringBoot-mybaits-druid-swagger"是一个典型的微服务开发组合,涉及四个主要技术:Spring Boot、MyBatis、Druid和Swagger。这些技术在Java Web开发中广泛使用,尤其在构建高效、易维护的RESTful API时。 ...
在Web开发中,MyBatis是一个流行的持久层框架,它提供了灵活的SQL映射机制,使得开发者能够方便地处理数据库操作。本篇文档主要讲解如何使用MyBatis的逆向工程(Mybatis Generator)对已有的项目进行改写,以自动化...
在本项目中,我们主要关注的是“springboot集成mybaits、layui开发框架”的实现,这是一个结合了现代Java开发技术和前端界面设计的高效解决方案。以下是关于这些技术的详细说明: 1. **Spring Boot**: Spring Boot...