
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。
import java.sql.Connectionimport java.sql.DriverManager
import java.sql.SQLException
import java.sql.Statement
public class DoInsert {
private Connection conn=null
private Statement stmt=null
private String driver="com.mysql.jdbc.Driver"
private String username="root"
private String password="123456"
private String sql=
"INSER INTO student(name myclass score) VALUES('卞志成','0801','80')"
public boolean addStudent(){
boolean flag=false
try{
//第一步 : 加载数据库厂商提供的驱动程序
Class.forName(driver)
}catch(ClassNotFoundException e){
e.printStackTrace()
}
//第二步 : 提供数据库的连接url;
String url="jdbc.mysql://localhost:3306/test"
try{
//第三步 :通过DriverManager获得数据库的一个连接对象
conn=DriverManager.getConnection(url, username, password)
}catch(SQLException e){
e.printStackTrace()
}
try{
//第四步 :创建Statement(SQL的执行环境)
stmt=conn.createStatement()
//第五步 :执行SQL语句
int row=stmt.executeUpdate(sql)
//第六步 : 处理结果
if(row==1)
flag=true
}catch(SQLException e)
{
e.printStackTrace()
}finally{
//第七步 : 关闭JDBC的资源
if(null!=stmt)
{
try{stmt.close()}
catch(SQLException e){e.printStackTrace()}
}
if(null!=conn){
try{conn.close()}
catch(SQLException e){
e.printStackTrace()
}
}
}
return flag
}
public static void main(String[] args)
{
DoInsert doinser=new DoInsert()
boolean flag =doinser.addStudent()
if(flag)
{
System.out.println("添加信息成功")
}
else{
System.out.println("添加信息失败")
}
}
}
这个看你怎么创建的。1,如果你用的成熟的CMS系统,那就容易,按他说的安装好CMS系统和数据库,配置好数据库名,用户名和密码。网页上直接 *** 作录入数据什么的就行了。
2,如果你自己制作网页程序,你得在源代码里写好数据的提交模块。包括从网页获取数据、连接数据库、验证数据库连接信息、提交、存储等很多方面。要有一定的html编程基础。
希望能帮到你!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)