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

来源:互联网 发布:mcake 知乎 编辑:程序博客网 时间:2024/06/06 02:35

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