用户信息(住院部工作人员)
某个病区的用户不能看其他病区的数据。
病人信息管理
功能方法:
0、住院号+住院次数:唯一确定一条病人信息
1、分页
:用PageHelper
进行分页(第几页,页大小,按字段排序
(name
,住院日期
),升序或者降序
)
2、多条件查询病人信息+分页:病区+住院号+住院日期
3、修改病人探视信息+探访日志log(先查库中的探视状态
,防止重复点击按钮
)
4、支持首字母检索
,实现方式:前段缓存所有病人信息,前段处理首字母问题,传给后台的是姓名的集合,然后后台到数据库取出所有符合信息的数据。
出院信息
手术信息
1、探视、离开:id+探视状态(记录探视日志)
2、查看探视日志:根据sid
同步数据日志
Swagger2
https://blog.csdn.net/csdnlijingran/article/details/88888275
1、手写Api文档的几个痛点:
- 文档需要更新的时候,需要再次发送一份给前端,也就是
文档更新交流不及时
- 接口
返回结果不明确
不能直接在线测试接口
,通常需要使用工具,比如postman
接口文档太多,不好管理
2、Swagger也就是为了解决这些问题
,直接生成接口文档的方式。当然也不能说Swagger就一定是完美的,当然也有缺点,最明显的就是代码移入性比较强。
swagger通过注解表明该接口会生成文档,包括接口名、请求方法、参数、返回信息的等等。
还可以在8080/swagger页面上进行接口的测试。
generator
利用generator自动
生成数据库对应
的表的映射类,dao接口和dao的xml文件。
需要配置
:
- 数据源的jdbc的driver引擎,url,username,password
- 生成表的映射类,dao接口和dao的xml文件的目录等信息
用到的切面
1、InputFilterAspect该切面检测入参合法性
2、该切面用于切换数据源
@DataSwitch(dataSource = “dataSource1”)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
public @interface DataSwitch {
String dataSource() default "";
}
DataSwitchAop
@Aspect
@Component
public class DataSwitchAop {
//@Pointcut()
//@Pointcut("execution(public * com.system.service.impl..*(..))")
public void execute(){
}
@Before("@annotation(com.system.util.database.DataSwitch)")
public void dataSwitch(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature =(MethodSignature) signature;
Method method = methodSignature.getMethod();
DataSwitch data = null;
if(method!=null){
data = method.getAnnotation(DataSwitch.class);
}
String dataSource = data.dataSource();
if(dataSource!=null){
MultipleDataSource.setDataSourceKey(dataSource);
}
}
}
MultipleDataSource
继承了 AbstractRoutingDataSource
,该类中有个ThreadLocal
类型的变量,用于记录本线程 用的数据源名称
。
public class MultipleDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();
public static void setDataSourceKey(String dataSource){
dataSourceKey.set(dataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
mybatis配置
<bean class="com.system.util.database.MultipleDataSource" id="dynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource1" key="dataSource1"></entry>
<entry value-ref="dataSource3" key="dataSource3"></entry>
<!--<entry value-ref="dataSource5" key="dataSource5"></entry>-->
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource1"></property>
</bean>
spring-mvc中的配置
跨域处理:拦截器
spring-mvc中的配置:声明 拦截器的bean
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.system.util.tools.CommonInterceptor">
<property name="excludedUrls">
<list>
<value>/</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
CommonInterceptor:
response.setHeader(“Access-Control-Allow-Origin”, “*”);
public class CommonInterceptor implements HandlerInterceptor {
private List<String> excludedUrls;
public List<String> getExcludedUrls() {
return excludedUrls;
}
public void setExcludedUrls(List<String> excludedUrls) {
this.excludedUrls = excludedUrls;
}
/**
* @param request
* @param response
* @Description: 在业务处理器处理请求之前被调用 如果返回false
* 从当前的拦截器往回执行所有拦截器的afterCompletion(),
* 再退出拦截器链, 如果返回true 执行下一个拦截器,
* 直到所有的拦截器都执行完毕 再执行被拦截的Controller
* 然后进入拦截器链,
* 从最后一个拦截器往回执行所有的postHandle()
* 接着再从最后一个拦截器往回执行所有的afterCompletion()
*/
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PATCH, PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return true;
}
// 在业务处理器处理请求执行完成后,生成视图之前执行的动作
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
/**
* @param request
* @param response
* @param handler
* @param ex
* @Description: 在DispatcherServlet完全处理完请求后被调用
* 当有拦截器抛出异常时,
* 会从当前拦截器往回执行所有的拦截器的afterCompletion()
*/
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
spring-mybatis配置
1、引用jdbc
文件
2、连接池
配置:连接哪个数据库;慢sql语句
的记录;异常日志
;sql注入
。
- 记录慢sql日志
<!--配置druid监控拦截器-->
<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
<property name="slowSqlMillis" value="10000"/>
<property name="logSlowSql" value="true"/>
</bean>
- 记录异常日志:连接异常;
<!--<!–配置druid日志输出拦截器–>-->
<bean id="log-filter" class="com.alibaba.druid.filter.logging.Log4jFilter">
<property name="resultSetLogEnabled" value="false"/>
<property name="statementLogErrorEnabled" value="true"/>
<property name="connectionLogErrorEnabled" value="true"/>
</bean>
- 配置sql注入拦截器
<!--配置SQL注入拦截器-->
<bean id="wall-filter" class="com.alibaba.druid.wall.WallFilter">
<property name="dbType" value="mysql"/>
</bean>
3、MultipleDataSource 继承了 AbstractRoutingDataSource 抽象路由数据库源
<bean class="com.system.util.database.MultipleDataSource" id="dynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource1" key="dataSource1"></entry>
<entry value-ref="dataSource3" key="dataSource3"></entry>
<!--<entry value-ref="dataSource5" key="dataSource5"></entry>-->
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource1"></property>
</bean>
spring中的配置
spring配置中引入了spring-mvc,springBean,spring-mybatis等配置文件。
1、事务管理器
:
-
DataSourceTransactionManager
数据源事务管理器
; -
dataSource
数据源
;<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dynamicDataSource"/> </bean>
基于注解
的事务配置
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
删除事务实例:
@Transactional(rollbackFor = NoneRemoveException.class)
@Transactional(rollbackFor = NoneRemoveException.class)
public boolean delete(List<Integer> idList) {
for (Integer anIdList : idList) {
if (sysAreaDao.deleteByPrimaryKey(anIdList) == 0) {
throw new NoneRemoveException();
}
}
return true;
}