hibernate的envers模块提供了一整套机制可以用来记录数据的变更。这里简单介绍一下。
1.自动配置
@SpringBootApplication
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
@EnableJpaAuditing(auditorAwareRef = "auditorAwareImpl")
public class EnversDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EnversDemoApplication.class, args)
}
}
这里配置@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)表示开启envers模块。
2.Audited注解
@Entity
@Audited
public class Book extends AuditableEntity{
@javax.persistence.Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id
private String title
private String author
private String description
private long price
private boolean valid
// getter and setter
}
使用@Audited标注一下这个实体类需要审计。
继承RevisionRepository
public interface BookDao extends RevisionRepository,JpaRepository {
}
通过继承RevisionRepository获取查找revisions的查询方法,主要如下:
@NoRepositoryBean
public interface RevisionRepository>{
Revision findLastChangeRevision(ID var1)
Revisions findRevisions(ID var1)
Page>findRevisions(ID var1, Pageable var2)
Revision findRevision(ID var1, N var2)
}
这里的N是指变更版本号的类型,一般Integer够用,如果觉得不够用可以改为Long类型。这里的T就是实体类。ID就是实体类的主键类型。
查询变更
经过以上配置之后,就可以正常记录变更的每个版本了,可以通过如下方法来查询,比如:
Revisions revision = bookDao.findRevisions(id)
List>data = revision.getContent()
这里的id为实体的id
revision的表结构
hibernate默认以实体类后缀_AUD来记录每个变更的版本,比如
-- ----------------------------
-- Table structure for book_aud
-- ----------------------------
DROP TABLE IF EXISTS "public"."book_aud"
CREATE TABLE "public"."book_aud" (
"id" int8 NOT NULL,
"rev" int4 NOT NULL,
"revtype" int2,
"author" varchar(255) COLLATE "default",
"description" varchar(255) COLLATE "default",
"price" int8,
"title" varchar(255) COLLATE "default",
"valid" bool
)
WITH (OIDS=FALSE)
ALTER TABLE "public"."book_aud" OWNER TO "postgres"
-- ----------------------------
-- Primary key structure for table book_aud
-- ----------------------------
ALTER TABLE "public"."book_aud" ADD PRIMARY KEY ("id", "rev") NOT DEFERRABLE INITIALLY IMMEDIATE
-- ----------------------------
-- Foreign keys structure for table book_aud
-- ----------------------------
ALTER TABLE "public"."book_aud" ADD CONSTRAINT "fk2u9iq76nh69r6f989ae7xft9" FOREIGN KEY ("rev") REFERENCES "public"."revinfo" ("rev") ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE
如果想改表后缀的话,可以通过org.hibernate.envers.audit_table_suffix的属性进行配置。里头的rev字段表示revision的版本号,一般全局递增。revtype字段表示 *** 作类型,0表示新增,1表示更新,2表示删除。
另外还有一个表是revinfo,记录每个变更的版本号和时间:
-- ----------------------------
-- Table structure for revinfo
-- ----------------------------
DROP TABLE IF EXISTS "public"."revinfo"
CREATE TABLE "public"."revinfo" (
"rev" int4 NOT NULL,
"revtstmp" int8
)
WITH (OIDS=FALSE)
ALTER TABLE "public"."revinfo" OWNER TO "postgres"
-- ----------------------------
-- Primary key structure for table revinfo
-- ----------------------------
ALTER TABLE "public"."revinfo" ADD PRIMARY KEY ("rev") NOT DEFERRABLE INITIALLY IMMEDIATE
自定义revision entity
如果默认的envers的实现不满足你的要求的话,使用@RevisionEntity注解,替换@Audited,然后自定义listener,比如
@Entity
@RevisionEntity( ExampleListener.class )
public class ExampleRevEntity extends DefaultRevisionEntity {
private String username
public String getUsername() { return username}
public void setUsername( String username ) { this.username = username}
}
public class ExampleListener implements RevisionListener {
public void newRevision( Object revisionEntity ) {
ExampleRevEntity exampleRevEntity = ( ExampleRevEntity ) revisionEntity
Identity identity =
(Identity) Component.getInstance( "org.jboss.seam.security.identity" )
exampleRevEntity.setUsername( identity.getUsername() )
}
}
具体的这里就不细讲了,具体可以参考hibernate。
1.建立一个web项目2.把数据库驱动复制到lib目录下。数据库驱动有:mysql,sqlserver,oracle等 是什么样类型的数据导入相应驱动。
3.编写一个连接数据库的工具类,获取一个连接。下面以mysql数据库为例。
核心代码:
public class DataUtils {
/**
* 从数据中获取一个连接
* @return
*/
public static Connection getConn(){
Connection conn = null
try {
Class.forName("com.mysql.jdbc.Driver").newInstance()
//表为test,用户名root,密码admin。
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "admin")
} catch (Exception e) {
e.printStackTrace()
}
return conn
}
}
4.获取到与相应数据库的连接后,就可以做增删改查 *** 作了。记得做完 *** 作后,关闭连接,释放资源。
这几天写论文做实验,Web日志挖掘部分第一步就是对Web日志进行预处理。所谓预处理就是将Web日志中没有用的记录和字段去掉。根据我的实验需要需要保留的是有效用户对于有效页面的访问时间,就这三个字段就可以。做数据预处理的第一步是将以文本形式保存的Web日志导入数据库,然后利用SQL语句对其所导入的数据库表进行 *** 作就可以完成数据与处理。Web日志的形式如下图所示:
这个部分之前一直不是很明白,询问去年做过这个工作的两个哥们,其中一个说用C++中STL部分可以实现,另一个说是将日志按行读取,分割内容存入数据库,然后读取下一行,却没有做具体工作。总之这两个人所说的都是利用编码来实现文本的读取和内容的分割最后再导入数据库。这样在理论上是可行的,但是实际 *** 作起来还是有很大的麻烦的,以现在的时间来看是来不及的。
还好在相关文献上看到有人提到用SQL
Server2000种的DTS工具可以实现这个导入功能。在网上进行搜索居然没有任何有用的类似于教程的文章,手头还没有SQL
Server的书籍,只能自己研究了,经过了一个小时的研究终于将这个问题解决。
Web日志文件虽然是文本文件,但是它的后缀是.log,如果想将其导入数据库必须首先将其后缀改称.txt。然后打运行SQL
Server2000的服务管理器,打开企业管理器。建立新的数据库Weblog,然后利用工具DTS进行 *** 作,DTS即数据转换服务。 *** 作为“工具—〉数据转换服务—〉导入数据”,出现如下对话框如图2所示。
在图3对话框中的数据源选择文本文件,对话框变成图4所示界面。点击文件名处右边的浏览按钮可以选择所要读取的文本文件形式的日志。这里只能读取.txt文件,所以前面一定要将Web日志的后缀.log改成后缀.txt。
根据图1我们看到Web日志头四行都是日志的信息,比如时间和文件格式,所以在跳过行里面要写跳过4行。下一步进入图6所示界面。
在图6种需要选择如何对文本文件中每一行的各个字段进行区分。选择方式如图中所示。由于Web日志每行为一个记录,每条记录中每一个字段中间都是用空格来进行分隔,所以选择“其它”然后在其对话框中填入一个空格键“
”,系统就将对数据进行处理进行划分,得到分割好的记录。当然相应字段的名称是错误的,这个可以在以后生成数据库表文件后对表进行设计修改。点击下一步进入图7所示界面。
单击下一步之后就可以完成数据导入。
然后刷新数据库Weblog,就可以看到与Web日志同名的新的数据库表文件。修改相应字段的名称,就可以完成数据的导入和数据库表的建立。
接下来可以利用查询分析器对Web日志的数据库表进行 *** 作,完成数据预处理,进而进行日志挖掘或者流量分析。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)