[关闭]
@huynh 2016-06-06T09:20:09.000000Z 字数 12702 阅读 1710

数据库服务请求与响应


概述

服务调用方法

  1. package hust.webservice.service;
  2. import hust.webservice.domain.SqlRequest;
  3. import hust.webservice.domain.SqlResponse;
  4. import javax.jws.WebService;
  5. /**
  6. * Sql操作服务接口,参数必须有数据库名。<br>
  7. * <p>
  8. * 1.如果是单表操作,则还需传入表名和参数<br>
  9. * 2.如果是多表复杂操作,则提供sql语句,该sql语句可以是完全的sql,也可以是mybatis带参数形式的sql<br>
  10. * 3.详细参数见SqlRequest说明<br>
  11. * </p>
  12. * 所有操作参数都封装在SqlRequest中,本接口所有方法只有该参数。<br>
  13. * 所有操作的返回值均封装在了SqlResponse中。
  14. * @date 2016年4月8日
  15. * @author huynh
  16. */
  17. @WebService
  18. public interface SqlService {
  19. /**
  20. * Select
  21. * @param sqlRequest
  22. * @return
  23. */
  24. SqlResponse select(SqlRequest sqlRequest);
  25. /**
  26. * 查询总数
  27. * @param sqlRequest
  28. * @return
  29. */
  30. SqlResponse selectCount(SqlRequest sqlRequest);
  31. /**
  32. * Insert<br>
  33. * 注意插入日期,需要将日期序列化为"yyyy-MM-dd HH:mm:ss"字符串,下面是使用fastjson注解实体类属性<br>
  34. * <pre class="code">
  35. * {@code
  36. \@JSONField (format="yyyy-MM-dd HH:mm:ss",name="register_time")
  37. private Date registerTime;<br>
  38. }
  39. </pre>
  40. 实体类必须先使用JSON.toJSONString(javaBean)序列化<br>
  41. * @param sqlRequest
  42. * @return
  43. */
  44. SqlResponse insert(SqlRequest sqlRequest);
  45. /**
  46. * Update <br>
  47. * 只能根据主键或者唯一字段更新
  48. * @param sqlRequest
  49. * @return
  50. */
  51. SqlResponse update(SqlRequest sqlRequest);
  52. /**
  53. * Delete <br>
  54. * paramter和condition只能用其一
  55. * @param sqlRequest
  56. * @return
  57. */
  58. SqlResponse delete(SqlRequest sqlRequest);
  59. /**
  60. * 多组更新操作需要在一个事务中完成
  61. * @param sqls 多组操作的sql语句,使用英文分号;隔开。注意sql的执行顺序
  62. * @return 只有返回1表示执行成功,其他情况均为失败
  63. */
  64. int updateTransaction(String databaseName,String sqls);
  65. }
  1. package hust.webservice.service;
  2. import hust.webservice.domain.SqlCondition;
  3. import hust.webservice.domain.SqlConditionRule;
  4. import hust.webservice.domain.SqlRequest;
  5. import hust.webservice.domain.SqlResponse;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. import java.util.concurrent.CountDownLatch;
  9. import org.apache.commons.lang.StringUtils;
  10. import org.apache.cxf.endpoint.Client;
  11. import org.apache.cxf.frontend.ClientProxy;
  12. import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
  13. import org.apache.cxf.transport.http.HTTPConduit;
  14. import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. /**
  18. * 本类为SqlService的代理实现类,供客户端使用,所有业务类都应该使用本类进行WebService的服务调用<br>
  19. * 在spring中将本类配置为非单例,配置如下:<br>
  20. *
  21. * <pre class="code">
  22. * {@code
  23. * <bean id="sqlService" class="hust.dbservice.webservice.SqlServiceProxy" scope="prototype">
  24. * <constructor-arg index="0">
  25. * <value type="java.lang.String"> WebService服务地址 </value>
  26. * </constructor-arg>
  27. * </bean>
  28. * }
  29. * </pre>
  30. *
  31. * @date 2016年4月12日
  32. * @author huynh
  33. */
  34. public class SqlServiceProxy implements SqlService {
  35. private static final Logger logger = LoggerFactory.getLogger(SqlServiceProxy.class);
  36. private final SqlService sqlService;
  37. private final JaxWsProxyFactoryBean jaxWsProxyFactoryBean;
  38. public SqlServiceProxy(String wsdlAddress) {
  39. if (StringUtils.isBlank(wsdlAddress)) {
  40. throw new RuntimeException("服务地址不能为空!");
  41. }
  42. jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
  43. try {
  44. sqlService = generateProxyClient(SqlService.class, wsdlAddress);
  45. } catch (Exception e) {
  46. logger.error("Fail to create webservice of SqlService! wsdlAddress={}",new Object[]{wsdlAddress,e});
  47. throw new RuntimeException("Fail to create SqlServiceProxy! Could not connect to CXF WebService,WSDL address is " + wsdlAddress);
  48. }
  49. if (sqlService != null) {
  50. logger.info("The webservice of sqlService is created successfully!");
  51. }
  52. }
  53. /**
  54. * 生成CXF服务接口代理类
  55. *
  56. * @param classType
  57. * 服务接口
  58. * @return 服务接口代理类
  59. * @throws Exception 可能抛出网络连接异常
  60. *
  61. */
  62. private <T> T generateProxyClient(Class<T> classType, String wsdlAddress) throws Exception {
  63. jaxWsProxyFactoryBean.setServiceClass(classType);
  64. jaxWsProxyFactoryBean.setAddress(wsdlAddress);
  65. T service = (T) jaxWsProxyFactoryBean.create();
  66. Client proxy = ClientProxy.getClient(service);
  67. HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
  68. HTTPClientPolicy policy = new HTTPClientPolicy();
  69. policy.setConnectionTimeout(40000); // 连接超时时间,默认30000
  70. policy.setReceiveTimeout(40000);// 请求超时时间,默认60000
  71. policy.setAllowChunking(false);// 取消块编码
  72. conduit.setClient(policy);
  73. return service;
  74. }
  75. @Override
  76. public SqlResponse select(SqlRequest sqlRequest) {
  77. return sqlService.select(sqlRequest);
  78. }
  79. @Override
  80. public SqlResponse selectCount(SqlRequest sqlRequest) {
  81. return sqlService.selectCount(sqlRequest);
  82. }
  83. @Override
  84. public SqlResponse insert(SqlRequest sqlRequest) {
  85. return sqlService.insert(sqlRequest);
  86. }
  87. @Override
  88. public SqlResponse update(SqlRequest sqlRequest) {
  89. return sqlService.update(sqlRequest);
  90. }
  91. @Override
  92. public SqlResponse delete(SqlRequest sqlRequest) {
  93. return sqlService.delete(sqlRequest);
  94. }
  95. @Override
  96. public int updateTransaction(String databaseName, String sqls) {
  97. return sqlService.updateTransaction(databaseName, sqls);
  98. }
  99. }

注:SqlServuceProxy使用方式: 本类为SqlService的代理实现类,供客户端使用,所有业务类都应该使用本类进行WebService的服务调用
在spring中将本类配置为非单例,配置如下:

  1. <bean id="sqlService" class="hust.webservice.service.SqlServiceProxy" scope="prototype">
  2. <constructor-arg>
  3. <value type="java.lang.String">wsdl地址</value>
  4. </constructor-arg>
  5. </bean>

请求参数

数据库服务请求参数的实体类是hust.webservice.domain.ServiceRequest,这个类是固定的。建议所有服务请求参数的包名均为hust.webservice.domain

参数名称 参数类型 是否为空 参数说明
databaseName string 不能为空 数据库名,选择数据源使用
tableName string 仅当sqlId不为空时,该参数可以为空 数据库表名
sql string 单表操作可以为空,其他多表必须指定 自定义数据库操作的sql语句,可以是MyBatis的带参数的sql
paramter String 可以为空 数据库操作条件部分字段对应参数,使用equal和and连接,JSONObject类型。
isPage bool 默认为false 是否进行分页查询
pageNo int 可以为空 分页查询页码
pageSize int 可以为空 分页查询页大小
orderBy String 可以为空 排序字段,单表使用,如 根据id排序: orderBy = "id asc"
sqlCondition SqlCondition 可以为空,如果不为空,优先使用此参数,而忽略tableField参数 单表操作条件

请求Sql服务的示例(详细可参见服务中单例测试)

  1. //创建数据库服务请求参数实例
  2. SqlRequest sqlRequest = new SqlRequest();
  3. //指定数据库
  4. sqlRequest.setDatabaseName("smartshop");
  5. //设置数据库表名
  6. sqlRequest.setTableName("user");
  7. //设置分页查询
  8. sqlRequest.setPage(true);
  9. sqlRequest.setPageNo(1);
  10. sqlRequest.setPageSize(2);
  11. sqlRequest.setOrderBy("buildingnumber desc");//分页查询支持排序
  12. //设置查询参数
  13. User user = new User();
  14. user.setUsername("huynh")
  15. //将SqlRequest序列化到ServiceRequest中
  16. sqlRequest.setParamter(JSON.toJSONString(user));
  17. //调用Web服务
  18. SqlResponse sqlResponse = sqlService.select(sqlRequest);
  19. //执行的sql = select * from user where username='huynh'
  1. //创建数据库服务请求参数实例
  2. SqlRequest sqlRequest = new SqlRequest();
  3. //指定数据库
  4. sqlRequest.setDatabaseName("smartshop");
  5. //设置数据库表名
  6. sqlRequest.setTableName("user");
  7. //指定要查询的字段
  8. sqlRequest.setQueryField("distinct username,password");
  9. //设置查询参数
  10. User user = new User();
  11. user.setUsername("huynh")
  12. //将SqlRequest序列化到ServiceRequest中
  13. sqlRequest.setParamter(JSON.toJSONString(user));
  14. //调用Web服务
  15. SqlResponse sqlResponse = sqlService.select(sqlRequest);
  16. //执行的sql = select distinct username,password from user where username='huynh'
  1. SqlRequest sqlRequest = new SqlRequest();
  2. sqlRequest.setDatabaseName("smartshop");
  3. sqlRequest.setTableName("cart");
  4. //设置复杂条件
  5. List<SqlConditionRule> conditions = new ArrayList<SqlConditionRule>();
  6. SqlConditionRule condition = new SqlConditionRule();
  7. condition.setField("total_price");
  8. condition.setOperation("<");
  9. condition.setValue(5);
  10. conditions.add(condition);
  11. condition = new SqlConditionRule();
  12. condition.setField("id");
  13. condition.setOperation("<");
  14. condition.setValue(37);
  15. conditions.add(condition);
  16. SqlCondition sqlCondition = new SqlCondition("and", conditions, null);
  17. sqlRequest.setSqlCondition(sqlCondition);
  18. SqlResponse sqlResponse = sqlService.select(sqlRequest);
  19. //执行的sql = select * from cart where total_price<5 and id < 37
  1. SqlRequest sqlRequest = new SqlRequest();
  2. sqlRequest.setDatabaseName("smartshop");
  3. sqlRequest.setTableName("user");
  4. //创建sql语句,这里的语句包含了#{}参数形式
  5. sqlRequest.setSql("select a.username,b.name from user as a,shop as b where a.id = b.user_id and a.id = #{id}");
  6. //设置参数值
  7. sqlRequest.setParamter("{\"id\":1}");
  8. SqlResponse sqlResponse = sqlService.select(sqlRequest);

响应参数

数据库服务响应参数的实体类是hust.webservice.domain.SqlResponse,这个类是固定的。

参数名称 参数类型 参数说明
success boolean 服务是否调用成功
errorMsg String 服务调用失败错误信息
queryResult JSON 数据库查询结果
updateResult int 对数据库做更新操作后被影响的行数,如果是插入单条记录,且数据库字段是自增的,则返回插入成功后的id
insertId int 仅仅针对MySql表主键为id且自增,当插入成功会返回被插入的id
totalCount long 查询满足条件的总数,对应selectCout方法返回值
totalPage int 分页查询后总页数

服务配置方法

1.先增加数据源配置

位置在dbservice-dal/resource/datasource

  1. <?xml version="1.0" encoding="GBK"?>
  2. <!-- 商城数据源 -->
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  10. http://www.springframework.org/schema/tx
  11. http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  12. http://www.springframework.org/schema/mvc
  13. http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
  14. <!-- 配置数据源,使用alibaba的DruidDataSource -->
  15. <bean id="smartshopDataSource" class="com.alibaba.druid.pool.DruidDataSource"
  16. init-method="init" destroy-method="close">
  17. <!-- 基本连接配置 -->
  18. <property name="driverClassName" value="${jdbc.driver}" />
  19. <property name="url"
  20. value="jdbc:mysql://222.20.95.248:3306/smartshop?characterEncoding=utf8" />
  21. <property name="username" value="root" />
  22. <property name="password" value="Idc+123456" />
  23. <!-- 配置初始化大小、最小、最大 -->
  24. <property name="initialSize" value="${initialSize}" />
  25. <property name="minIdle" value="${minIdle}" />
  26. <property name="maxActive" value="${maxActive}" />
  27. <!-- 配置获取连接等待超时的时间 -->
  28. <property name="maxWait" value="${maxWait}" />
  29. <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
  30. <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />
  31. <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
  32. <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />
  33. </bean>
  34. <!-- 线程安全类,可以是单例。用于对数据库的基本操作 -->
  35. <bean id="smartshopSqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  36. <!-- 构造函数中需要传入会话工厂 -->
  37. <constructor-arg index="0" ref="smartshopSqlSessionFactory" />
  38. </bean>
  39. <!-- MyBatis的会话工厂 -->
  40. <bean id="smartshopSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  41. <property name="dataSource" ref="smartshopDataSource" />
  42. <!-- 指定 MyBatis XML 映射器文件的位置 <property name="mapperLocations" value="classpath:mapper_smartshop/*.xml"
  43. /> -->
  44. <!-- 配置别名包 使用的时候可以省略包名 <property name="typeAliasesPackage" value="cscec3.dbservice.smartshop.model"
  45. /> -->
  46. <!-- 配置插件 -->
  47. <property name="plugins">
  48. <array>
  49. <!-- 配置分页插件 -->
  50. <bean class="com.github.pagehelper.PageHelper">
  51. <!-- 这里的几个配置主要演示如何使用,如果不理解,一定要去掉下面的配置 -->
  52. <property name="properties">
  53. <value>
  54. dialect=mysql
  55. reasonable=true
  56. supportMethodsArguments=true
  57. params=count=countSql
  58. autoRuntimeDialect=true
  59. </value>
  60. </property>
  61. </bean>
  62. </array>
  63. </property>
  64. </bean>
  65. <!-- 配置 spring 事务管理 -->
  66. <bean id="smartshopTransactionManager"
  67. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  68. <property name="dataSource" ref="smartshopDataSource" />
  69. </bean>
  70. <!-- 由于声明式事务不支持多数据源切换,因此使用的是编程式事务,所以不需要此注解 -->
  71. <!--<tx:annotation-driven transaction-manager="transactionManager"/> -->
  72. </beans>

2.将1增加的配置写入总配置

位置在dbservice-dal/resource/hust-dbservice-dal.xml

  1. <?xml version="1.0" encoding="GBK"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context-3.0.xsd
  9. http://www.springframework.org/schema/tx
  10. http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  11. http://www.springframework.org/schema/mvc
  12. http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
  13. >
  14. <!-- 测试用的 <import resource="classpath:datasource/spring-mybatis_test.xml"
  15. /> -->
  16. <!-- 指定jdbc属性配制文件位置 -->
  17. <context:property-placeholder location="classpath:jdbc.properties"/>
  18. <!-- 正式用的 -->
  19. <!-- 配置物业数据源 -->
  20. <import resource="classpath:datasource/datasource_smartproperty.xml" />
  21. <!-- 配置权限管理数据源 -->
  22. <import resource="classpath:datasource/datasource_authorization.xml" />
  23. <!-- 配置商城数据源 -->
  24. <import resource="classpath:datasource/datasource_smartshop.xml" />
  25. </beans>

3.将数据源和事务管理器配置当作SqlServiceImpl的属性注入

位置在dbservice-biz/resource/bean/hust-dbservice-bean.xml

  1. <?xml version="1.0" encoding="GBK"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
  3. <beans default-autowire="byName">
  4. <!-- 配置数据库服务实例 -->
  5. <bean id="sqlService" class="hust.dbservice.webservice.impl.SqlServiceImpl" >
  6. <!-- 这里配置不同数据源的SqlSessionTemplate实例 -->
  7. <constructor-arg index="0">
  8. <map>
  9. <entry key="smartshop" value-ref="smartshopSqlSession" />
  10. <entry key="smartproperty" value-ref="smartpropertySqlSession" />
  11. <entry key="authorization" value-ref="authorizationSqlSession" />
  12. </map>
  13. </constructor-arg>
  14. <!-- 这里配置不同数据源的TransactionManager实例 -->
  15. <constructor-arg index="1">
  16. <map>
  17. <entry key="smartshop" value-ref="smartshopTransactionManager" />
  18. <entry key="smartproperty" value-ref="smartpropertyTransactionManager" />
  19. <entry key="authorization" value-ref="authorizationTransactionManager" />
  20. </map>
  21. </constructor-arg>
  22. </bean>
  23. </beans>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注