hibernate

[TOC]

Hibernate

pom依赖

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>antlr</groupId>
      <artifactId>antlr</artifactId>
      <version>2.7.7</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml</groupId>
      <artifactId>classmate</artifactId>
      <version>1.3.4</version>
    </dependency>
    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.geronimo.specs</groupId>
      <artifactId>geronimo-annotation_1.0_spec</artifactId>
      <version>1.0</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate.common</groupId>
      <artifactId>hibernate-commons-annotations</artifactId>
      <version>5.0.1.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.0.12.Final</version>
    </dependency>
    <dependency>
      <groupId>org.hibernate.javax.persistence</groupId>
      <artifactId>hibernate-jpa-2.1-api</artifactId>
      <version>1.0.0.Final</version>
    </dependency>
    <dependency>
      <groupId>org.jboss</groupId>
      <artifactId>jandex</artifactId>
      <version>2.0.0.Final</version>
    </dependency>
    <dependency>
      <groupId>jboss</groupId>
      <artifactId>javassist</artifactId>
      <version>3.7.ga</version>
    </dependency>
    <dependency>
      <groupId>org.jboss.logging</groupId>
      <artifactId>jboss-logging</artifactId>
      <version>3.3.1.Final</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.30</version>
    </dependency>
  • 配置文件
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- 四大参数 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
        <!-- SQL 方言 ,注意使用MySQLInnoDBDialect,才可以使用Innodb引擎-->
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <!-- 打印出sql -->
        <property name="show_sql">true</property>       
        <!-- 格式化sql -->
        <property name="format_sql">true</property>
        <!-- 有表更新表,没有表自动创建表 -->
        <property name="hbm2ddl.auto">update</property>     
        <!-- 加载映射文件 -->
        <mapping resource="User.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

注意:主配置文件名,一般默认是hibernate.cfg.xml,并且在src根目录中
上面的配置文件,可以参考etc文件夹下的配置文件

  • 创建类
public class User {
    private int uid;
    private String username;
    private String password;
    //get/set方法 必须要有
}
  • 映射文件
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
<hibernate-mapping>
    <class name="com.hibernate.entity.User" table="user">
        <id name="uid" column="uid">
            <!-- 使用数据库默认的生成主键的方案 -->
            <generator class="native"/>
        </id>
        <property name="username" column="username"/>
        <property name="password" column="password"/>
    </class>
</hibernate-mapping>
    Configuration configure = new Configuration().configure("hibernate.cfg.xml");
    SessionFactory factory = configure.buildSessionFactory();
    Session session = factory.openSession();// 获取连接
    // 开启事务
    Transaction tx = session.beginTransaction();
    User user = new User("黄蓉", "123");
    session.save(user);
    tx.commit();// 提交事务
    session.close();// 关闭连接
对应关系

session查用api

save、delete、update、get

load

延迟查询:如果使用了对象中非id的属性时才会发送sql语句

saveOrUpdate

瞬时态执行save(),游离态执行update()

merge

两个相同id的对象合并

实体类的三种状态

瞬时态:无id,与session无关联,与数据库无关联

持久态:有id,与session有关联,与数据库关联
持久态对象修改数据,会自动修改数据库的数据

游离态(离线):有id,与session无关联,与数据库无关
游离态的对象如果id与表中的记录id一致,那么save时将发送update语句

三种状态

具体请看hibernate的三种状态

关联关系

多对一

多个Customer对应一个User

多对一

一对多

一个User对应多个Customer

一对多

注意:一对多,多对一其实是从不同角度看问题,本质是一样的,任意写一个就是单向的一对多(多对一),两个都写,就是双向的一对多(多对一)。单向意味着,只能从一方找到另一方,双方可以相互找到对方。

多对多

多对多

hibernate常用查询api

详情请点击这里

hibernate缓存

一级缓存:
第一次查找,去缓存中找,没有数据,从数据库获取,然后存入一级缓存,并且存入快照区;session没有关闭,并且执行第二次查找,先从一级缓存中获取。如果对象修改了数据,一级缓存中的数据也修改了,那么会将一级缓存和快照区的数据进行比对,如果不相同,就将数据存入数据库。

二级缓存

OpenSessionInView

1、创建一个工具类HIbernateUtils

    private static SessionFactory factory;
    static {
         factory = new Configuration().configure().buildSessionFactory();
    }

    public static Session getSession() {
        return factory.getCurrentSession();//将session与线程绑定
    }

2、创建一个过滤器OpenSessionInViewFilter

        Session session = HibernateUtils.getSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            chain.doFilter(request, response);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null) {
                tx.rollback();
            }
        } finally {
            if (session != null) {
                session.close();
            }
        }

3、在hibernate.cfg.xml中配置属性

<property name="hibernate.current_session_context_class">thread</property>  

request(请求)->open session并开始transaction->controller->View(Jsp)->结束transaction并 close session.

有可能在chain.doFilter()被阻塞,因为有可能输出jsp的页面内容大,response.write的时间长,另一方面可能是网速慢,服务器与用户间传输时间久。当大量这样的情况出现时,就有连接池连接不足,造成页面假死现象。

jpa

什么是jpa

java persistence api,java在持久层的一套接口,与jdbc接口类似,提供一套规范,有其他数据库厂商去实现

hibernate实现了jpa接口

基本用法

@Entity //表示该类为持久化类
@Table(name="user") //对应数据库的表名
public class User {
    @Id //主键
    @GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略 IDENTITY与native类似
    private Integer uid;
    @Column(name="user_name") //设置属性名与字段名的映射关系
    private String username;
    private String password; //如果属性名与字段名一致,可以不写注解
}

注意:如果下面的注解不理解,请看上面xml配置映射关系的图

多对一

在多方设置@ManyToOne和@JoinColumn

    @ManyToOne(cascade=CascadeType.ALL) //casacde为级联
    @JoinColumn(name="uid") //外键
    private User user;

一对多

在一方设置@OneToMany和@JoinColumn

    @OneToMany(cascade=CascadeType.ALL) //casacde为级联
    @JoinColumn(name="uid") //外键
    private Set<Customer> custSet = new HashSet<>();

多对多

在任意一方设置@ManyToMany和@JoinTable

    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
    @JoinTable(//生成第三张表
            name="role_user",
            joinColumns={@JoinColumn(name="uid")},//本表中的主键
            inverseJoinColumns={@JoinColumn(name="rid")}//另一张表的主键
    )
    private Set<Role> roleSet = new HashSet<>();

双向的只要在另一个类中写同样的注解即可

    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
    @JoinTable(
            name="role_user",
            joinColumns={@JoinColumn(name="rid")},//本表中的主键
            inverseJoinColumns={@JoinColumn(name="uid")}//另一张表的主键
    )
    private Set<User> userSet = new HashSet<>();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容