Hibernate入门到开发四之基于Annotations的映射(简单属性)

一、注意:
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,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值