一、注意:
1.要么全部声明于属性上方,要么全部声明于对应的get函数上.
2.注意关键字的映射永远失败(注意hibernate的版本适配的字段,如user order longtext)
二、基本注解
三、入门案例【所有的注解重要的说明都在里面了】
/**
* @Entity:声明一个映射实体对象,位于class的上方
* 使用注解的方式,必须写该注解。声明为一个实体。需要被映射
* @Table:声明映射数据库的名字,唯一约束等。建议使用全小写表名解决Mysql不同平台表名大小写兼容问题
* 可配置:
* name :指定映射过去的表名 ,不写的话,默认跟类名一样。
* 其他属性:没怎么使用,有兴趣去看一下手册
*/
@Entity
@Table(name="t_user")
public class User extends BaseEntity<Long>{
private String loginName; // 登录名
private String password; // 密码
private Date registerTime;
private Integer version;
private String t_ignore;
private Level level;
private String everLongText;
private String testBasic;
private String nothing1;
public User() {
}
/**
* @Id:主键的属性或get方法上方 声明一个主键属性
*
*/
/**
* 主键生成策略
@GeneratedValue:可声明于@Id注解下方
可配值:
strategy=GenerationType.AUTO
strategy=GenerationType.SEQUENCE
strategy=GenerationType.IDENTITY
strategy=GenerationType.TABLE
*/
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
public Long getId() {
return id;
}
/**
* @Column:用来建立普通属性跟数据库之间的关系
* name : 对应表的列名,不写的话默认跟表字段名一样
length : 字段长度
nullable: 默认为true true表示可以为null,false表示不能为null
unique : 默认为false 能否唯一
*
*/
@Column(name="loginName",length=22,nullable=false)
public String getLoginName() {
return loginName;
}
//修改对应数据库的列名
@Column(name="myPassword")
public String getPassword() {
return password;
}
/**
* @Temporal:Date数据类型的时间精度。仅仅用在Date类型之上
* 可配值:
* @Temporal(TemporalType.DATE) //日期格式
* @Temporal(TemporalType.TIME) //时间格式
* @Temporal(TemporalType.TIMESTAMP) //时间戳格式 默认
*/
@Temporal(TemporalType.TIMESTAMP)
public Date getRegisterTime() {
return registerTime;
}
/**
* @Version:Integer字段属性或get方法上方 乐观锁,(什么是乐观锁!之类的后面讲)
* 更新的时候必须要版本号一致,否则更新失败.(先查询,再更新)
*/
@Version
public Integer getVersion() {
return version;
}
/**
* @Transient:易失变量,不会被持久化到数据库。自动忽略,不映射到数据库
*/
@Transient
public String getT_ignore() {
return t_ignore;
}
/**
* @Enumerated:枚举类型的存储精度
* 可配值:
* @Enumerated(EnumType.ORDINAL) //默认,存下标索引
@Enumerated(EnumType.STRING) //枚举值
*/
@Enumerated(EnumType.ORDINAL)
public Level getLevel() {
return level;
}
/**
* @Lob:映射到数据表的字段类型是longText类型,大文本类型
* 根据属性的类型配合使用
CLob :@Lob+String 大文本
BLob :@Lob+Byte[] 文件/图片字节
*/
@Lob
public String getEverLongText() {
return everLongText;
}
/**
* @Basic:一般不需要声明,默认所有属性都拥有该注解。
* 用于普通属性,获取策略.默认简单属性直接从数据库抓取。如果不需要直接抓取,才需要显示的声明LAZY.(延迟获取)
* @Basic(fetch=FetchType.EAGER) //默认
@Basic(fetch=FetchType.LAZY)
一般来说:对于普通属性字段是立即加载的
对于关联对象时延迟加载的
需要使用的时候才去加载
*
*/
@Basic(fetch=FetchType.LAZY)
public String getTestBasic() {
return testBasic;
}
//没有写默认还是会映射到数据库的。利用get方法
public String getNothing1() {
return nothing1;
}
public void setNothing1(String nothing1) {
this.nothing1 = nothing1;
}
public void setTestBasic(String testBasic) {
this.testBasic = testBasic;
}
public void setEverLongText(String everLongText) {
this.everLongText = everLongText;
}
public void setLevel(Level level) {
this.level = level;
}
public void setT_ignore(String t_ignore) {
this.t_ignore = t_ignore;
}
public void setVersion(Integer version) {
this.version = version;
}
public void setId(Long id) {
this.id = id;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public void setPassword(String password) {
this.password = password;
}
public void setRegisterTime(Date registerTime) {
this.registerTime = registerTime;
}
}
3.1 在核心配置文件中引入该实体类
<!-- 引入注解的实体类 -->
<mapping class="com.hibernate.entity.User"/>
四、测试案例如下:
@Test public void testAll() {
//1:加载配置文件,然后获得SessionFactory工厂
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
//解释:这里只要能够去加载我们的配置文件,那么它就会自动加载映射文件,会自动建表。测试是否建表成功 }
//在新版本里面使用下面的测试代码
@Test
public void testHbm() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure()
.build();
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
}
五、结果显示如下
5.1 在数据库里面看到生成的表
5.2 查看表结构如下
六、乐观锁和悲观锁的区别?
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。