hibernate分表保存日志
@Service("accessLogService")
@Transactional
public class LogMessageServiceImpl extends BaseDaoServiceImpl<AccessLogMessage,Long> implements LogMessageService{
@Autowired
SplitHibernateInterceptor splitInter;
@Autowired
public BaseDaoImpl<AccessLogMessage> baseDao;
/**
* 根据当前月份
*/
@Override
public void addLog(AccessLogMessage message) {
//要拦截的目标数据库名称
splitInter.setTargetTableName("accesslog_message");
//月份从0计算
int month = Calendar.getInstance().get(Calendar.MONTH);
if(month==0){
//1月份
baseDao.save(message);
}else{
splitInter.setSubTableName("accesslog_message"+month);
SessionFactory sf= baseDao.getSessionFactory();
Session session = sf.openSession(splitInter);
try{
session.save(message);
}finally{
session.close();
}
}
}
}
@Service("splitInter")
public class SplitHibernateInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = 2293562313992510554L;
private String targetTableName;// 目标母表名
private String subTableName;// 操作子表名 ,与目标结构一样
public SplitHibernateInterceptor() {
}
public java.lang.String onPrepareStatement(java.lang.String sql) {
sql = sql.toLowerCase();
sql = sql.replaceAll(targetTableName, subTableName);
return sql;
}
public String getTargetTableName() {
return targetTableName;
}
public void setTargetTableName(String targetTableName) {
this.targetTableName = targetTableName;
}
public String getSubTableName() {
return subTableName;
}
public void setSubTableName(String subTableName) {
this.subTableName = subTableName;
}
}
@Component("baseDaoService")
@Transactional
public class BaseDaoServiceImpl<T, K extends Serializable> implements
BaseDaoService<T, K> {
@Autowired
public ExtendBaseDao<T, K> extendBaseDao;
@Override
public void add(T t) {
extendBaseDao.save(t);
}
@Override
public void delete(T t) {
extendBaseDao.delete(t);
}
@Override
public void update(T t) {
extendBaseDao.update(t);
}
@Override
public T get(Class<T> entityClass, K k) {
return extendBaseDao.get(entityClass, k);
}
@Override
public void deleteByHql(String hql ,Object... objects) {
extendBaseDao.delete(hql, objects);
}
@Override
public List<T> query(String hql, Object... objects) {
return extendBaseDao.list(hql, objects);
}
@Override
public void marge(T t) {
extendBaseDao.merge(t);
}
}
@Entity
@Table(name = "ACCESSLOG_MESSAGE")
public class AccessLogMessage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "requestURI", length = 250)
private String requestURI;
@Column(name = "requestTime", length = 30)
private String requestTime;
@Column(name = "requestParams", length = 1000)
private String requestParams;
@Column(name = "userName", length = 32)
private String userName;
@SuppressWarnings("serial")
public class ViewJsonInterceptor implements Interceptor {
@Autowired
private MemcachedClient memcachedClient;
private static final Logger logger = LoggerFactory
.getLogger(ViewJsonInterceptor.class);
@Override
public void init() {
logger.info("Json格式化拦截器启动!");
}
@Override
public void destroy() {
logger.info("Json格式化拦截器销毁!");
}
public HttpServletRequest getRequest(ActionInvocation invocation) {
ActionContext context = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context
.get(StrutsStatics.HTTP_REQUEST);
return request;
}
public HttpServletResponse getResponse(ActionInvocation invocation) {
ActionContext context = invocation.getInvocationContext();
HttpServletResponse response = (HttpServletResponse) context
.get(StrutsStatics.HTTP_RESPONSE);
return response;
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = getRequest(invocation);
HttpServletResponse response = getResponse(invocation);
response.setContentType("text/html;charset=UTF-8");
// end
Object action = invocation.getAction();
String methodName = invocation.getProxy().getMethod();
Method method = action.getClass().getDeclaredMethod(methodName, new Class[0]);
//防止 重复参数,如果重复取第一个
invocation.getInvocationContext().setParameters(InterceptorUtil.noRepeatParams(invocation));
if (!(action instanceof BaseViewJsonAction)
|| !method.isAnnotationPresent(ViewJson.class)) {
return invocation.invoke();
}
String voke = null;
BaseViewJsonAction baseViewJsonAction = (BaseViewJsonAction) action;// ============检验当前访问在缓存中是否存在========================
String memcachedSwitch = Switch.getInstance().getMemcachedSwitch();
String cacheKey = "";
if (Switch.OPEN.equals(memcachedSwitch) && method.isAnnotationPresent(MemCachedJson.class) ) {
// 获取当前访问URL对应的缓存key
cacheKey = InterceptorUtil.getCacheKey(invocation, request);
logger.debug("[key=]" + cacheKey);
String cacheValue = null;
try {
memcachedClient.setSanitizeKeys(true);
cacheValue = memcachedClient.get(cacheKey);
if (StringUtils.isNotBlank(cacheValue)) {
// 缓存中已存在cacheKey的cacheValue,则直接返回
//记录日志,并保存至数据库
InterceptorUtil.log(request, invocation);
response.getWriter().write(cacheValue);
return null;
}
} catch (Exception e) {
logger.error("memecached异常:", e.getMessage());
}
}
try {
invocation.invoke();
JsonViewMessage jsonMessage = baseViewJsonAction.getJsonViewMessage();
String code = "" + jsonMessage.getRet();
if (Switch.OPEN.equals(memcachedSwitch) && method.isAnnotationPresent(MemCachedJson.class)) {
// 将返回的正确结果注入缓冲
code = "" + jsonMessage.getRet();
if ("0".equals(code)) {
String returnValue = baseViewJsonAction.jsonViewAsString();
try {
memcachedClient.set(cacheKey, 0, returnValue);
} catch (Exception e) {
logger.error("memecached set 缓存异常:", e.getMessage());
}
}
// 注入缓存完成
}
if ("0".equals(code)) {
//记录日志,并保存至数据库
InterceptorUtil.log(request, invocation);
}else{
if(!"1".equals(code)&&logger.isErrorEnabled()){
logger.error("code:" + code + ";message:" + jsonMessage.getRetInfo());
logger.error("调用"+invocation.getAction().getClass().getSimpleName()+"."+methodName+"()");
String absUrl =ServletRequestUtil.getRequestURL(request);
logger.error(IPRequest.getIpAddress(request)+"=>"+request.getMethod()+"请求地址:"+absUrl);
}
}
} catch (BusinessException e) {
if(!"0".equals(e.getCode())){
if(logger.isErrorEnabled()){
logger.error("code:" + e.getCode() + ";message:" + e.getMessage());
logger.error("调用"+invocation.getAction().getClass().getSimpleName()+"."+methodName+"()");
String absUrl =ServletRequestUtil.getRequestURL(request);
logger.error(IPRequest.getIpAddress(request)+"=>"+request.getMethod()+"请求地址:"+absUrl);
}
}
baseViewJsonAction.getJsonViewMessage().setResult(null);
baseViewJsonAction.getJsonViewMessage().setRet(e.getCode());
baseViewJsonAction.getJsonViewMessage().setRetInfo(e.getMessage());
} finally {
baseViewJsonAction.writeJsonView();
}
return voke;
}
public void writeJsonView() {
if (userDefinedJsonObject != null) {
userDefinedJsonObject.put("ret", jsonViewMessage.getRet());
userDefinedJsonObject.put("retInfo", jsonViewMessage.getRetInfo());
JsonFormater.writeJsonValue(mapper, this.response,
userDefinedJsonObject);
return;
}
if (jsonViewMessage.getAlias() != null) {
Map<String, Object> map = new HashMap<String, Object>(3);
map.put("ret", jsonViewMessage.getRet());
map.put("retInfo", jsonViewMessage.getRetInfo());
map.put(jsonViewMessage.getAlias(), jsonViewMessage.getResult());
JsonFormater.writeJsonValue(mapper, this.response, map);
return;
}
JsonFormater.writeJsonValue(mapper, this.response, jsonViewMessage);
}
<package name="BasePackage" extends="struts-default">
<interceptors>
<interceptor name="LogInterceptor" class="com.core.action.interceptor.LogInterceptor"/>
<interceptor name="ViewJsonInterceptor" class="com.core.action.interceptor.ViewJsonInterceptor"/>
<!--<interceptor name="ParamValidateInterceptor" class="com.core.interceptor.ParamValidateInterceptor"/>-->
<interceptor-stack name="JsonInterceptorStack">
<interceptor-ref name="LogInterceptor"/>
<interceptor-ref name="ViewJsonInterceptor"/>
<!--<interceptor-ref name="ParamValidateInterceptor"/>-->
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="JsonInterceptorStack"/>
<default-action-ref name="notFound" />
<action name="notFound">
<result>/WEB-INF/404.jsp</result>
</action>
</package>
hibernate分表保存日志的更多相关文章
- 使用hibernate 分表做增删改查
公司项目有一张表的数据量特别大.而且时间越长累积的数据量就越大. 后来DBA决定分表来解决性能问题. 分表是指 一个母体表 一群子表(结构和字段与母体表完全一样) 我们程序对母表操作其实就是对子 ...
- Log4j分级别保存日志到单个文件中,并记录IP和用户信息
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration S ...
- 利用Sharding-Jdbc实现分表
你们团队使用SpringMVC+Spring+JPA框架,快速开发了一个NB的系统,上线后客户订单跟雪花一样纷沓而来. 慢慢地,你的心情开始变差,因为客户和产品的抱怨越来越频繁,抱怨的最多的一个问题就 ...
- 利用Sharding-Jdbc实现分表[z]
[z]https://www.cnblogs.com/codestory/p/5591651.html 你们团队使用SpringMVC+Spring+JPA框架,快速开发了一个NB的系统,上线后客户订 ...
- Mysql数据库常用分库和分表方式
http://blog.csdn.net/clevercode/article/details/50877580 1 分库 1.1 按照功能分库 按照功能进行分库.常见的分成6大库: 1 用户类 ...
- mysql分库分表(一)
mysql分库分表 参考: https://blog.csdn.net/xlgen157387/article/details/53976153 https://blog.csdn.net/cleve ...
- PostgreSQL 务实应用(三/5)分表复制
问题的提出 在项目中,有些表的记录增长非常快,记录数过大时会使得查询变得困难,导致整个数据库处理性能下降.此时,我们会考虑按一定的规则进行分表存储. 常用的分表方式是按时间周期,如每月一张,每天一张等 ...
- 【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
一.需求分析 日志数据在很多行业中都是非常敏感的数据,它们不能删除只能保存和查看,这样日志表就会越来越大,我们不可能永远让它无限制的增长下去,必须采取一种手段将数据分散开来.假设现在整个数据库需要保存 ...
- Hibernate与数据库分表
数据库分片(shard)是一种在数据库的某些表变得特别大的时候采用的一种技术. 通过按照一定的维度将表切分,可以使该表在常用的检索中保持较高的效率,而那些不常用的记录则保存在低访问表中.比如:销售记录 ...
随机推荐
- Akka源码分析-Event Bus
akka中的EventBus其实是不常用,也最容易被忽略的一个组件. 但如果你深入Cluster的实现就会发现,这个东西其实还挺有用的,而且它是ActorSystem系统中所有事件消息的一个横切面,通 ...
- easyui- comobo 详细讲解
具体代码实现 @{ ViewBag.Title = "人员查找"; ViewBag.LeftWidth = "200px"; ViewBag. ...
- 解决Logger在Android Studio 3.1版本无法正常加载tag格式
已经升级到Android Studio 3.1的同学可能会发现一个问题, Logcat中如果短时间出现多条日志tag相同, 只会显示第一条日志的tag, 后面的tag会自动隐藏, 这时com.orha ...
- 数据清洗——python定位csv中的特定字符位置
之前发过一篇关于定位csv中的特殊字符的,主要是用到了python的自带的函数,近期又遇到了一些新的问题,比如isdigit()的缺点在于不能判断浮点型,以及小数中有多个小数点的情况.发现还是正则表达 ...
- c# regex Match Matches MatchCollection 用法
string text = "1A 2B 3C 4D 5E 6F 7G 8H 9I 10J 11Q 12J 13K 14L 15M 16N ffee80 #800080"; Reg ...
- Hadoop Hive概念学习系列之hive与依赖环境的交互(二十一)
hive与环境的交互,算是一个小知识点,但掌握不菲! 如何在hive里,也达到这样呢? 不需要这样啦,因为,hive是建立在hadoop之上,启动hive,相当于,就是,hadoop jar ** h ...
- DetachedCriteria和Criteria的使用方法
DetachedCriteria和Criteria的使用方法 /* * 下载统计 * @return */ public String downloadStatistics(){ logger ...
- JS高级——封装注册事件
兼容性问题 1.ele.on事件类型 = function(){}一个元素ele注册一种事件多次,会被替换成最后一个,所以有局限性 2.addEventListener(事件类型,事件处理函数,use ...
- java攻城师之路--复习java web之Cookie_Session
Servlet技术 用来动态生成 网页数据资源Servlet生成HTML 页面数据时,所有内容都是通过 response.getWriter response.getOutputStream 向浏览器 ...
- MyBatis入门2_增删改查+数据库字段和实体字段不一致情况
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! 当数据库字段和实体bean中属性不一致时 之前数据库P ...