hibernate的学习笔记

1.hibernate所需jar包

i.hibernate core

ii./required

iii.slf-nop jar

2.hibernate的配置文件hibernate.cfg.xml

 

hibernate.cfg.xml

 

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

         <hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->//数据库基本信息

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <property name="connection.url">jdbc:mysql://localhost/hibernate</property>

        <property name="connection.username">root</property>

        <property name="connection.password">bjsxt</property>

        <!-- JDBC connection pool (use the built-in) -->

        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>//数据库方言

        <!-- Enable Hibernate's automatic session context management -->

        <property name="current_session_context_class">thread</property> //规定session上线文的                                 范围,这里规定是在一个线程里,参见15

        <!-- Disable the second-level cache  -->

        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>//禁止二级缓存

        <!-- Echo all executed SQL to stdout -->

        <property name="show_sql">true</property>//显示生成的sql语句

                           <property name="format_sql">true</property>//显示生成的sql语句,并进行格式化

        <!-- Drop and re-create the database schema on startup -->

        <property name="hbm2ddl.auto">update</property>//让hibernate自动生成建表语句,create,数据库中没有这张表会自动进行创建,update,原来数据库中有这张表,如果表结构修改了,运行程序,数据库表会自动改变,create-drop,当关闭sessionFactory时,数据库中的表会自动被删掉,validte,数据库中的表已经建好,没事往数据库插入数据是,就会和hbm文件进行对照是否一致

        <mapping resource="com/bjsxt/hibernate/Student.hbm.xml"/>//告诉hibernate取哪里找对应的表的配置文件

        <mapping class="com.bjsxt.hibernate.Teacher"/>

    </session-factory>

</hibernate-configuration>

 

2.hibernate的表的映射文件Strudent.hbm.xml

 

Student.hbm.xml

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

      <hibernate-mapping>

<class name="com.bjsxt.hibernate.Student" table ="student">  //这里的table="student"可以不用写,因为默认表名和类                                                                                                                      //名是一样的,数据库表名是不区分大小写的

<id name="id" column="id"/> //数据库字段名和表的字段名是一样的就不用写column=""

<property name="name" />

<property name="age" />

    </class>

     </hibernate-mapping>

3.第一个hibernate的小程序

 

Test.java

 

package com.bjsxt.hibernate;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.AnnotationConfiguration;

public class Test {

public static void main(String[] args) {

Student s = new Student();

s.setId(1);

s.setName("zhangsan");

s.setAge(8);

                        //如果不传参数,hibernate会到src根目录下找hibernate.cfg.xml的配置文件进行读入,如果放在其它目录下或则叫其他                           名字的话,就传入路径和文件名,sessionFactory相当于残生connection的工厂

    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

Session session = sessionFactory.openSession();

session.beginTransaction();

session.save(s);

session.getTransaction().commit();

}

}


4.用单例模式得到sessionFactory

package com.bjsxt.hibernate;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class Singleton {

    private final static SessionFactory sessionFactory = buildSessionFactory();

    

    private static SessionFactory buildSessionFactory(){

        return new Configuration().buildSessionFactory();

    }

    public SessionFactory getSessionFactory(){

        return sessionFactory;

    }

}

 

5.用annotation

 

在基础类中的属性不加注解,也可以自动就进行映射如下的,name和title,相当于hibernate自动给加上@Basic注解

 

hibernate.cfg.xml

 

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

 

<hibernate-configuration>

 

    <session-factory>

 

        <!-- Database connection settings -->

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <property name="connection.url">jdbc:mysql://localhost/hibernate</property>

        <property name="connection.username">root</property>

        <property name="connection.password">bjsxt</property>

 

        <!-- JDBC connection pool (use the built-in) -->

        <property name="connection.pool_size">1</property>

 

        <!-- SQL dialect -->

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

 

        <!-- Enable Hibernate's automatic session context management -->

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

 

        <!-- Disable the second-level cache  -->

        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

 

        <!-- Echo all executed SQL to stdout -->

        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->

        <property name="hbm2ddl.auto">update</property>

        <mapping resource="com/bjsxt/hibernate/Student.hbm.xml"/>

<mapping class="com.bjsxt.hibernate.Teacher"/>  //使用annotation要在xml中这么配

    </session-factory>

</hibernate-configuration>

 

基础类Teacher,使用annotation

package com.bjsxt.hibernate;

import javax.persistence.Entity;

import javax.persistence.Id;//引入的是javax,是标准里面的接口,jpa

 

@Entity

@Table(name="_teacher") //当类名和表名不一致的情况

public class Teacher {

private int id;

private String name;

private String title;

        private String yourWifeName;

private Date birthDate;

private boolean good;

private Gender gender;

@Id

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

            @column(name="_name")  //字段名和表里的名字不一样

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

        @Enumerated(EnumType.STRING)  //对于Enum类型的,通过这个把enum类型转成要存入数据库中字段的类型

public Gender getGender() {

return gender;

}

public void setGender(Gender gender) {

this.gender = gender;

}

public boolean isGood() {

return good;

}

public void setGood(boolean good) {

this.good = good;

}

@Transient  //透明的,在数据库中没有对应的字段

public String getYourWifeName() {

return yourWifeName;

}

public void setYourWifeName(String yourWifeName) {

this.yourWifeName = yourWifeName;

}            

 

        @Temporal(TemporalType.TIME)  //精度,可以规定Date类型的存储,是@Temporal(value =TemporalType.TIME)时,value可以省略,DATE,TIME,TIMESTAMP这几种类型

public Date getBirthDate() {

return birthDate;

}

public void setBirthDate(Date birthDate) {

this.birthDate = birthDate;

}

}

 

6. 在hibernate lib 中加入annotation的jar包

a)    hibernate annotaion jar

b)    ejb3 persistence jar

c)    hibernate common-annotations.jar

d)    注意文裆中没有提到hibernate-common-annotations.jar 文件

7.显示建表语句的配置

org.hibernate.tool.hbm2ddl,在记录日志中记录,在log4j的日志系统中记录建表语句

 需要加入的jar包:

slf4-api-1.5.8.jar(标准接口包) 

log4j-1.2.15.jar(具体实现包)

slf4j-log4j12-1.5.8.jar(slf4j和log4j之间的转换包)

 

8.hibernate中的java类中的类型,数据库中的类型,映射类型的之间的对应关系

 

           映射类型               java类型                         标准sql类型

 

9.id的生成策略,使用xml配置

 

Student.hbm.xml

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

<class name="com.bjsxt.hibernate.Student">

               <generator  class = "uuid"></generator>  //native ,identity,sequence,uuid等比较多,用native是让hibernate帮你选

       </class>

</hibernate-mapping>


10.使用annotation生成主键

@GeneratorValue  //默认使用auto

@GeneratorValue(strategy=GenerationType.IDENTITY)  //mysql用的是identiy,oracle用的是sequence

 

11.为oracle的sequence生成策略指定名字

package com.bjsxt.hibernate;

 

import java.util.Date;

 

import javax.persistence.EmbeddedId;

import javax.persistence.Entity;

import javax.persistence.EnumType;

import javax.persistence.Enumerated;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.IdClass;

import javax.persistence.SequenceGenerator;

 

import javax.persistence.Id;

import javax.persistence.Temporal;

import javax.persistence.TemporalType;

import javax.persistence.Transient;

 

@Entity

@SequenceGenerator(name="teacherSEQ", sequenceName="teacherSEQ_DB")

public class Teacher {

//private TeacherPK pk;

private int id;

private String name;

private String title; 

private String yourWifeName;

private Date birthDate;

private boolean good;

public boolean isGood() {

return good;

}

public void setGood(boolean good) {

this.good = good;

}

@Transient

public String getYourWifeName() {

return yourWifeName;

}

public void setYourWifeName(String yourWifeName) {

this.yourWifeName = yourWifeName;

}

@Id

@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="Teacher_GEN")

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

@Id

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

@Temporal(TemporalType.TIME)

public Date getBirthDate() {

return birthDate;

}

public void setBirthDate(Date birthDate) {

this.birthDate = birthDate;

}

 

}


 11.用table生成主键

 package com.bjsxt.hibernate;

 

import java.util.Date;

 

import javax.persistence.EmbeddedId;

import javax.persistence.Entity;

import javax.persistence.EnumType;

import javax.persistence.Enumerated;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.IdClass;

import javax.persistence.SequenceGenerator;

 

import javax.persistence.Id;

import javax.persistence.Temporal;

import javax.persistence.TemporalType;

import javax.persistence.Transient;

 

@Entity

@javax.persistence.TableGenerator(

    name="Teacher_GEN", //生成主键的名字

    table="GENERATOR_TABLE", //table名字

    pkColumnName = "pk_key", //字段名

    valueColumnName = "pk_value", //字段名

    pkColumnValue="Teacher", //记录的pkColumnName的名字

    allocationSize=1 //增加区间

)

 

@SequenceGenerator(name="teacherSEQ", sequenceName="teacherSEQ_DB")

@IdClass(TeacherPK.class)

public class Teacher {

//private TeacherPK pk;

private int id;

private String name;

private String title; 

private String yourWifeName;

private Date birthDate;

private boolean good;

private Gender gender;

@Enumerated(EnumType.STRING)

public Gender getGender() {

return gender;

}

public void setGender(Gender gender) {

this.gender = gender;

}

public boolean isGood() {

return good;

}

public void setGood(boolean good) {

this.good = good;

}

@Transient

public String getYourWifeName() {

return yourWifeName;

}

public void setYourWifeName(String yourWifeName) {

this.yourWifeName = yourWifeName;

}

@Id

@GeneratedValue(strategy=GenerationType.TABLE, generator="Teacher_GEN")

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

@Id

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

@Temporal(TemporalType.TIME)

public Date getBirthDate() {

return birthDate;

}

public void setBirthDate(Date birthDate) {

this.birthDate = birthDate;

}

/*@EmbeddedId

public TeacherPK getPk() {

return pk;

}

public void setPk(TeacherPK pk) {

this.pk = pk;

}*/

}

 

12.使用xml生成联合主键

StudentPK .java

 

package com.bjsxt.hibernate;

import javax.persistence.Embeddable;

public class StudentPK implements java.io.Serializable{

private int id;

private String name; //联合主键类

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public boolean equals(Object o) {

if(o instanceof TeacherPK) {

TeacherPK pk = (TeacherPK)o;

if(this.id == pk.getId() && this.name.equals(pk.getName())) {

return true;

}

}

return false;

}

@Override

public int hashCode() {

return this.name.hashCode();

}

}

 

Student.java

 

package com.bjsxt.hibernate;

 

public class Student {

private StudentPK pk;

private int age;

private String sex;

private boolean good;

public boolean isGood() {

return good;

}

public void setGood(boolean good) {

this.good = good;

}

/*public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}*/

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public StudentPK getPk() {

return pk;

}

public void setPk(StudentPK pk) {

this.pk = pk;

}

}

 

Student.hbm.xml

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

<class name="com.bjsxt.hibernate.Student">

<composite-id name="pk" class="com.bjsxt.hibernate.StudentPK">

<key-property name="id"></key-property>

<key-property name="name"></key-property>

</composite-id>

<property name="age" />

<property name="sex" />

<property name="good" type="yes_no"></property>

    </class>

</hibernate-mapping>

 

 

13.为什么一个对象要写它的equals和hashcode

在内存中,每个对象都被装在hascode表中,当要访问一个对象时会去通过hascode去找这个对象,通过一个hashcode找到的对象可能有几个,这个时候要通过equal来确定唯一的对象

 

14.使用annotation来实现联合主键,有三种方式

 

①通过在主键类上注解

package com.bjsxt.hibernate;

import javax.persistence.Embeddable;

 

@Embeddable

public class TeacherPK implements java.io.Serializable{

private int id;

private String name;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public boolean equals(Object o) {

if(o instanceof TeacherPK) {

TeacherPK pk = (TeacherPK)o;

if(this.id == pk.getId() && this.name.equals(pk.getName())) {

return true;

}

}

return false;

}

@Override

public int hashCode() {

return this.name.hashCode();

}

}

 

Student.java

 package com.bjsxt.hibernate;

 

public class Student {

private StudentPK pk;

private int age;

private String sex;

private boolean good;

public boolean isGood() {

return good;

}

public void setGood(boolean good) {

this.good = good;

}

/*public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}*/

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

 

       @ Id

public StudentPK getPk() {

return pk;

}

public void setPk(StudentPK pk) {

this.pk = pk;

}

}

②把主键类上的注解去掉,在id上加

package com.bjsxt.hibernate;

import javax.persistence.Embeddable;

 

public class TeacherPK implements java.io.Serializable{

private int id;

private String name;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public boolean equals(Object o) {

if(o instanceof TeacherPK) {

TeacherPK pk = (TeacherPK)o;

if(this.id == pk.getId() && this.name.equals(pk.getName())) {

return true;

}

}

return false;

}

@Override

public int hashCode() {

return this.name.hashCode();

}

}

 

Student.java

 package com.bjsxt.hibernate;

 

public class Student {

private StudentPK pk;

private int age;

private String sex;

private boolean good;

public boolean isGood() {

return good;

}

public void setGood(boolean good) {

this.good = good;

}

/*public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}*/

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

 

       @EmbedId

public StudentPK getPk() {

return pk;

}

public void setPk(StudentPK pk) {

this.pk = pk;

}

}

 

③在联合主键上加,主键类上 不加

package com.bjsxt.hibernate;

import javax.persistence.Embeddable;

 

public class TeacherPK implements java.io.Serializable{

private int id;

private String name;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public boolean equals(Object o) {

if(o instanceof TeacherPK) {

TeacherPK pk = (TeacherPK)o;

if(this.id == pk.getId() && this.name.equals(pk.getName())) {

return true;

}

}

return false;

}

@Override

public int hashCode() {

return this.name.hashCode();

}

}

 

Student.java

 package com.bjsxt.hibernate;

    @IdClass(StudentPK.class)

public class Student {

private StudentPK pk;

private int age;

private String sex;

private boolean good;

public boolean isGood() {

return good;

}

public void setGood(boolean good) {

this.good = good;

}

        @Id

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

        @Id

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

 

public StudentPK getPk() {

return pk;

}

public void setPk(StudentPK pk) {

this.pk = pk;

}

}

 

15.hibernate的核心开发接口

Session session = sessionFactory.openSession();   //每次都创建一个session,需要close()

Session session = sessionFactory.getCurrentSession();   //从上下文找(呼应以上2),如果当前有session就用当前的,如果没有就会重新创建一个session,事物提交会自动close()

 

16.JTA

java transaction api:针对两个以上的数据库建立事物

17.对象的三种状态

 

18.几种数据库操作方法

save();

delete();

get();

load();

get()与load()的区别:

①load返回的是代理对象,等到要真正用到对象的内容时才发出sql语句(懒加载)

②直接从数据库加载,不会延迟

 

19.用xml配置只更新要更新的字段

 

Student.hbm.xml

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

<class name="com.bjsxt.hibernate.Student" dynamic-update="true">

<id name="id">

<generator class="native"></generator>

</id>

<property name="name"></property>

<property name="age" />

<property name="sex" />

<property name="good" type="yes_no"></property>

    </class>

</hibernate-mapping>

 

20.关于flush()和clear()

clear方法:无论是load还是get,都会首先查找缓存(一级缓存),如果没有才会到数据库找查,调用clear()可以强制清除session缓存

flush()方法:可以强制进行内存到数据库的同步,具体什么时候同步,可以进行设置《

设置方法时,通过session.setFlushMode(FlushMode.……),这个会在性能调优上用到

21.schemaexport,手动生成建表语句

new SchemaExport(new AnnotationConfiguration().configure.create(……,……));//第一个参数时在控制台打印sql语句,第二个是使建表语句到数据库去执行

 

22.主键关联

两个表的主键互相参照

 

23.外键关联

一张表里除了主键,还有另外一个主键,然后关联另外一张表里的主键

 

24.annotation配置单项一对一外键关联

 

Husband.java

 

package com.bjsxt.hibernate;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.OneToOne;

 

@Entity

public class Husband {

private int id;

private String name;

private Wife wife;

@Id

@GeneratedValue

public int getId() {

return id;

}

public String getName() {

return name;

}

 

@OneToOne

@JoinColumn(name="wifeId")

public Wife getWife() {

return wife;

}

 

public void setId(int id) {

this.id = id;

}

public void setName(String name) {

this.name = name;

}

public void setWife(Wife wife) {

this.wife = wife;

}

}

 

25.用xml配置单项一对一外键关联

 

StuIdCard.hbm.xml

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

<class name="com.bjsxt.hibernate.StuIdCard">

<id name="id">

<generator class="native"></generator>

</id>

<property name="num"/>

<many-to-one name="student" column="studentId" unique="true"></many-to-one>

    </class>

</hibernate-mapping>

 

26.一对一双向外键关联

 

Husband.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.OneToOne;

 

@Entity

public class Husband {

private int id;

private String name;

private Wife wife;

@Id

@GeneratedValue

public int getId() {

return id;

}

public String getName() {

return name;

}

@OneToOne

@JoinColumn(name="wifeId")

public Wife getWife() {

return wife;

}

public void setId(int id) {

this.id = id;

}

public void setName(String name) {

this.name = name;

}

public void setWife(Wife wife) {

this.wife = wife;

}

}

 

Wife.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.OneToOne;

 

@Entity

public class Wife {

private int id;

private String name;

private Husband husband;

 

@OneToOne(mappedBy="wife")  //双向一对一外键关联,必须有一方主导,否则会产生冗余数据,例如会有两个wifeid字段

public Husband getHusband() {

return husband;

}

public void setHusband(Husband husband) {

this.husband = husband;

}

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

public void setName(String name) {

this.name = name;

}

}

 

27.联合主键

 

WifePK.java

 

package com.bjsxt.hibernate;

import java.io.Serializable;

public class WifePK implements Serializable {

private int id;

private String name;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

Husband.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.JoinColumns;

import javax.persistence.OneToOne;

 

@Entity

public class Husband {

private int id;

private String name;

private Wife wife;

@Id

@GeneratedValue

public int getId() {

return id;

}

public String getName() {

return name;

}

@OneToOne

@JoinColumns(

{

@JoinColumn(name="wifeId", referencedColumnName="id"),

@JoinColumn(name="wifeName", referencedColumnName="name")

}

)   //重命名联合主键

public Wife getWife() {

return wife;

}

public void setId(int id) {

this.id = id;

}

public void setName(String name) {

this.name = name;

}

public void setWife(Wife wife) {

this.wife = wife;

}

}

 

 

Wife.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.IdClass;

 

@Entity

@IdClass(WifePK.class)

public class Wife {

private int id;

private String name;

private int age;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

@Id

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

@Id

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

28.数据库三范式

①要有主键,列不可分

②联合主键,不能存在部分依赖

③不能存在传递依赖

 

29.多对一单向关联

 

User.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

 

@Entity

@Table(name="t_user")

public class User {

private int id;

private String name;

private Group group;

@ManyToOne

public Group getGroup() {

return group;

}

public void setGroup(Group group) {

this.group = group;

}

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

 

Group.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.Table;

 

@Entity

@Table(name="t_group")

public class Group {

private int id;

private String name;

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

30.一对多的单向关联

 

group.java

 

package com.bjsxt.hibernate;

 

import java.util.HashSet;

import java.util.Set;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.OneToMany;

import javax.persistence.Table;

 

@Entity

@Table(name="t_group")

public class Group {

private int id;

private String name;

private Set<User> users = new HashSet<User>();

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@OneToMany

@JoinColumn(name="groupId")

public Set<User> getUsers() {

return users;

}

public void setUsers(Set<User> users) {

this.users = users;

}

}

 

User.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

 

@Entity

@Table(name="t_user")

public class User {

private int id;

private String name;

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

31.双向一对多和多对一关联

 

User.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

 

@Entity

@Table(name="t_user")

public class User {

private int id;

private String name;

private Group group;

@ManyToOne

public Group getGroup() {

return group;

}

public void setGroup(Group group) {

this.group = group;

}

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

Group.java

 

package com.bjsxt.hibernate;

 

import java.util.HashSet;

import java.util.Set;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.OneToMany;

import javax.persistence.Table;

 

@Entity

@Table(name="t_group")

public class Group {

private int id;

private String name;

private Set<User> users = new HashSet<User>();

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@OneToMany(mappedBy="group")

public Set<User> getUsers() {

return users;

}

public void setUsers(Set<User> users) {

this.users = users;

}

}

 

32.多对多单向关联

 

Teacher.java

 

package com.bjsxt.hibernate;

 

import java.util.HashSet;

import java.util.Set;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.JoinTable;

import javax.persistence.ManyToMany;

import javax.persistence.OneToMany;

import javax.persistence.Table;

 

@Entity

public class Teacher {

private int id;

private String name;

private Set<Student> students = new HashSet<Student>();

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@ManyToMany

@JoinTable(name="t_s",

joinColumns={@JoinColumn(name="teacher_id")},

inverseJoinColumns={@JoinColumn(name="student_id")}

)

public Set<Student> getStudents() {

return students;

}

public void setStudents(Set<Student> students) {

this.students = students;

}

}

 

Student.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

 

@Entity

public class Student {

private int id;

private String name;

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

 

33.双向多对多

 

Teacher.java

 

package com.bjsxt.hibernate;

 

import java.util.HashSet;

import java.util.Set;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.JoinTable;

import javax.persistence.ManyToMany;

import javax.persistence.OneToMany;

import javax.persistence.Table;

 

@Entity

public class Teacher {

private int id;

private String name;

private Set<Student> students = new HashSet<Student>();

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@ManyToMany

@JoinTable(name="t_s",

joinColumns={@JoinColumn(name="teacher_id")},

inverseJoinColumns={@JoinColumn(name="student_id")}

)

public Set<Student> getStudents() {

return students;

}

public void setStudents(Set<Student> students) {

this.students = students;

}

}

 

Student.java

 

package com.bjsxt.hibernate;

 

import java.util.HashSet;

import java.util.Set;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToMany;

 

@Entity

public class Student {

private int id;

private String name;

private Set<Teacher> teachers = new HashSet<Teacher>();

@ManyToMany(mappedBy="students")

public Set<Teacher> getTeachers() {

return teachers;

}

public void setTeachers(Set<Teacher> teachers) {

this.teachers = teachers;

}

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

34.CRUD之C(有关联关系的新增)  双向一对多,多对一

 

 

CascadeType对CUD,有用

fetch 对R有用,在多对一的情况下默认设置是EAGER,不仅查询多的一方也会把一的一方发出来,

在一对多的情况下是LAZY,只查出一的一方,不查询多的一方

 

铁律:①双向关系在程序中要设定双向关系

         ②双向要设mappedBy

 

Group.java

 

package com.bjsxt.hibernate;

 

import java.util.HashSet;

import java.util.Set;

 

import javax.persistence.CascadeType;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.OneToMany;

import javax.persistence.Table;

 

@Entity

@Table(name="t_group")

public class Group {

private int id;

private String name;

private Set<User> users = new HashSet<User>();

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@OneToMany(mappedBy="group",

cascade={CascadeType.ALL},   //在任何情况下都进行关联,MERGE,在合并的情况下进行关联,PERSIST,REMOVE

                fetch=FetchType.EAGER)   //对于一的一方,如果进行get查询,会取出一的一方,多的一方不会取,设置Fetch就会进行取了

public Set<User> getUsers() {

return users;

}

public void setUsers(Set<User> users) {

this.users = users;

}

}

 

User.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.CascadeType;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

 

@Entity

@Table(name="t_user")

public class User {

private int id;

private String name;

private Group group;

@ManyToOne(cascade={CascadeType.ALL})

public Group getGroup() {

return group;

}

public void setGroup(Group group) {

this.group = group;

}

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

 

35.要删除带关联关系的数据

 

如果想消除关联关系,先设定关系为null.再删除对应记录,如果不删记录,该记录变成垃圾数据或则使用hql

 

 

36.继承映射(不太重要)

三种方式

a)一张总表SINGLE_TABLE

i. hibernate_1900_lnheritence_Mapping_Single_Table

b)每个类分别一张表TABLE_PER_CLASS

i. hibernate_2000_lnheritence_Mapping_Table_Per_Class

c)每个子类一张表jOINED

i. hibernate_2100_lnheritence_Mapping_JOINED

父类上加注解@Inheritance(strategy=InheritanceType.JOINED)

@Inheritance(strategy=InheritanceType.JOINED)

 

public class Person {... ...}

 

37.hibernate关于实体类的设计

 

设计:

a)实体类(表)

b)导航(编程方便)

c)确定了编程方式

38.hql

①查询所有

   Session session = sf.openSession();

   session.beginTransaction();

   Query q = session.createQuery("from Category c where c.name > 'c5'");

   List<Category> categories = (List<Category>)q.list();

 

②带查询条件

   Session session = sf.openSession();

   session.beginTransaction();

   Query q = session.createQuery("from Category c where c.name > 'c5'");

 

   List<Category> categories = (List<Category>)q.list();

③排序查询

   Session session = sf.openSession();

   session.beginTransaction();   

   Query q = session.createQuery("from Category c order by c.name desc");

 

   List<Category> categories = (List<Category>)q.list();

④过滤重复

   Session session = sf.openSession();

   session.beginTransaction();

   Query q = session.createQuery("select distinct c from Category c order by c.name desc");

 

   List<Category> categories = (List<Category>)q.list();

⑤带占位符的查询

   Session session = sf.openSession();

   session.beginTransaction();

   Query q = session.createQuery("from Category c where c.id > :min and c.id < :max");

   q.setInteger("min", 2);

   q.setInteger("max", 8);

 

   List<Category> categories = (List<Category>)q.list();

⑥用?占位符

   Session session = sf.openSession();

   session.beginTransaction();

   Query q = session.createQuery("from Category c where c.id > ? and c.id < ?");

   q.setParameter(0, 2)

   q.setParameter(1, 8);

 

   List<Category> categories = (List<Category>)q.list();   

⑦分页查询

   Session session = sf.openSession();

   session.beginTransaction();

   Query q = session.createQuery("from Category c order by c.name desc");

   q.setMaxResults(4); //每页的最大页数

   q.setFirstResult(2); //起始行数

 

   List<Category> categories = (List<Category>)q.list();

⑧用对象数组取

    Session session = sf.openSession();

    session.beginTransaction();

    Query q = session.createQuery("select c.id,  c.name from Category c order by c.name desc");

     List<Object[]> categories = (List<Object[]>)q.list();

     for(Object[] o : categories) {

       System.out.println(o[0] + "-" + o[1]);

}

⑨查询多对一( //设定fetch type 为lazy后将不会有第二条sql语句)

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Topic t where t.category.id = 1");

List<Topic> topics = (List<Topic>)q.list();

for(Topic t : topics) {

System.out.println(t.getTitle());

//System.out.println(t.getCategory().getName());

}

⑩ 关联查询

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Msg m where m.topic.category.id = 1");

 

for(Object o : q.list()) {

Msg m = (Msg)o;

System.out.println(m.getCont());

}

⑪查询结果封装成封装类

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select new com.bjsxt.hibernate.MsgInfo(m.id, m.cont, m.topic.title, m.topic.category.name) from Msg m");

 

for(Object o : q.list()) {

MsgInfo m = (MsgInfo)o;

System.out.println(m.getCont());

}

⑫联合查询

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select t.title, c.name from Topic t join t.category c "); //join Category c

for(Object o : q.list()) {

Object[] m = (Object[])o;

System.out.println(m[0] + "-" + m[1]);

}

 

⑬只去单个对象

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Msg m where m = :MsgToSearch "); //不重要

Msg m = new Msg();

m.setId(1);

q.setParameter("MsgToSearch", m);

 

Msg mResult = (Msg)q.uniqueResult();

⑭使用聚合函数

 

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select count(*) from Msg m");

 

long count = (Long)q.uniqueResult();

⑮使用函数

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select max(m.id), min(m.id), avg(m.id), sum(m.id) from Msg m");

 

Object[] o = (Object[])q.uniqueResult();

System.out.println(o[0] + "-" + o[1] + "-" + o[2] + "-" + o[3]);

⑯其他

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Msg m where m.id between 3 and 5");

 

for(Object o : q.list()) {

Msg m = (Msg)o;

System.out.println(m.getId() + "-" + m.getCont());

}

⑰其他

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Msg m where m.id in (3,4, 5)");

 

for(Object o : q.list()) {

Msg m = (Msg)o;

System.out.println(m.getId() + "-" + m.getCont());

}

 

⑱是不是Null

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Msg m where m.cont is not null");

 

for(Object o : q.list()) {

Msg m = (Msg)o;

System.out.println(m.getId() + "-" + m.getCont());

}

⑳集合是不是空

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Topic t where t.msgs is empty");

 

for(Object o : q.list()) {

Topic t = (Topic)o;

System.out.println(t.getId() + "-" + t.getTitle());

}

(21)模糊查询

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Topic t where t.title like '%5'");

 

for(Object o : q.list()) {

Topic t = (Topic)o;

System.out.println(t.getId() + "-" + t.getTitle());

}

 

 

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("from Topic t where t.title like '_5'");

 

for(Object o : q.list()) {

Topic t = (Topic)o;

System.out.println(t.getId() + "-" + t.getTitle());

}

 

 

(22)函数

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select lower(t.title)," +

"upper(t.title)," +

"trim(t.title)," +

"concat(t.title, '***')," +

"length(t.title)" +

" from Topic t ");

 

for(Object o : q.list()) {

Object[] arr = (Object[])o;

System.out.println(arr[0] + "-" + arr[1] + "-" + arr[2] + "-" + arr[3] + "-" + arr[4] + "-");

}

 

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select abs(t.id)," +

"sqrt(t.id)," +

"mod(t.id, 2)" +

" from Topic t ");

 

for(Object o : q.list()) {

Object[] arr = (Object[])o;

System.out.println(arr[0] + "-" + arr[1] + "-" + arr[2] );

}

 

(23)时间

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select current_date, current_time, current_timestamp, t.id from Topic t");

 

for(Object o : q.list()) {

Object[] arr = (Object[])o;

System.out.println(arr[0] + " | " + arr[1] + " | " + arr[2] + " | " + arr[3]);

}

(24)group by

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select t.title, count(*) from Topic t group by t.title") ;

for(Object o : q.list()) {

Object[] arr = (Object[])o;

System.out.println(arr[0] + "|" + arr[1]);

} //group by 的字段必须在select中

 

(25)having

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("select t.title, count(*) from Topic t group by t.title having count(*) >= 1") ;

for(Object o : q.list()) {

Object[] arr = (Object[])o;

System.out.println(arr[0] + "|" + arr[1]);

 

}    //having 后面必须是聚合函数

(26) exists

 //用in 可以实现exists的功能

//但是exists执行效率高

@Test

public void testHQL_31() {

Session session = sf.openSession();

session.beginTransaction();// t.id not in (1)

Query q = session.createQuery("from Topic t where not exists (select m.id from Msg m where m.topic.id=t.id)") ;

// Query q = session.createQuery("from Topic t where exists (select m.id from Msg m where m.topic.id=t.id)") ;

for(Object o : q.list()) {

Topic t = (Topic)o;

System.out.println(t.getTitle());

}

session.getTransaction().commit();

session.close();

 

}

 

(27)//update and delete

//规范并没有说明是不是要更新persistent object,所以如果要使用,建议在单独的trasaction中执行

 

@Test

public void testHQL_32() {

Session session = sf.openSession();

session.beginTransaction();

Query q = session.createQuery("update Topic t set t.title = upper(t.title)") ;

 

q.executeUpdate();

q = session.createQuery("from Topic");

for(Object o : q.list()) {

Topic t = (Topic)o;

System.out.println(t.getTitle());

}

session.createQuery("update Topic t set t.title = lower(t.title)")

.executeUpdate();

session.getTransaction().commit();

session.close();

 

 

}

(28)//Native(了解)

Session session = sf.openSession();

session.beginTransaction();

SQLQuery q = session.createSQLQuery("select * from category limit 2,4").addEntity(Category.class); //返回的泛型

List<Category> categories = (List<Category>)q.list();

for(Category c : categories) {

System.out.println(c.getName());

}

39.面试题之java有内存泄漏吗?

语法级别没有 但是可由java引起,例如:连接池不关闭,或io读取后不关闭,java调用c,c调用windows的文件打开

40.面试题之1+N问题

问题描述:当两个实体类有关联关系时,我只想取出其中一个实体类的对象,因为设成了EAGER,所有在取得

时候会连带着另外一个实体类的对象一起从数据库中取出来

解决办法:

a)@ManyToOne(fetch=FetchType.LAZY)

        //fetch=FetchType.LAZY 解决N+1问题 说明如下:

        //当多对一(@ManyToOne)已经设定属性" fetch=FetchType.LAZY "时

        //只有当需要时(如:t.getCategory().getName()时)才会去获取关联表中数据 可以解决N+1问题

b)join fetch

        //join fetch 解决N+1问题 说明如下:

        //修改hql语句为--"  from Topic t left join fetch t.category c  "

41.面试题之用list和iteration取得区别

a)list取所有

b)iterate先取 ID,等用到的时候再根据ID来取对象

c)session中list第二次发出,仍会到数据库査询

  d)iterate 第二次,首先找session 级缓存    

42.一级和二级缓存

session是一级缓存

SessionFactory二级缓存

a)load默认使用二级缓存,iterate默认使用二级缓存

 

b)list默认往二级缓存加数据,但是查询的时候不使用,查询缓存除外(相同的sql查询)

二级缓存的设置

注:使用EhCache二级缓存 需要导入ehcache-1.2.3.jar及commons-logging-1.0.4.jar包    

 

hibernate.cfg.xml

 

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

 

<hibernate-configuration>

    <session-factory>

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <property name="connection.url">jdbc:mysql://localhost/hibernate</property>

        <property name="connection.username">root</property>

        <property name="connection.password">bjsxt</property>

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- JDBC connection pool (use the built-in) -->

        <property name="connection.pool_size">1</property>

        <!-- Enable Hibernate's automatic session context management -->

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

<property name="cache.use_second_level_cache">true</property>

<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

<property name="cache.use_query_cache">true</property> //查询缓存设置

 

        <!-- Echo all executed SQL to stdout -->

        <property name="show_sql">true</property>

        <property name="format_sql">true</property>

 

        <!-- Drop and re-create the database schema on startup

        <property name="hbm2ddl.auto">update</property>

-->

        <!--  

        

<mapping resource="com/bjsxt/hibernate/Group.hbm.xml"/>

<mapping resource="com/bjsxt/hibernate/User.hbm.xml"/>

-->

<mapping class="com.bjsxt.hibernate.Category"/>

 <mapping class="com.bjsxt.hibernate.Msg"/>

 <mapping class="com.bjsxt.hibernate.Topic"/>

    </session-factory>

 

</hibernate-configuration>

 

ehcache.xml

 

<ehcache>

    <diskStore path="java.io.tmpdir"/>

    <defaultCache

        maxElementsInMemory="10000"  //可以装载的最大对象数

        eternal="false" //永远存在

        timeToIdleSeconds="120"  //对象可以不被使用停留的时间

        timeToLiveSeconds="1200"  //对象的生命周期

        overflowToDisk="true"  //当内存满了以后写到硬盘

       memoryStoreEvictionPolicy = "LRU"   //使用哪种缓存算法

        />

 

    <cache name="sampleCache1"

        maxElementsInMemory="10000"

        eternal="false"

        timeToIdleSeconds="300"

        timeToLiveSeconds="600"

        overflowToDisk="true"

        memoryStoreEvictionPolicy = "LRU"

 

        />

 

    <cache name="sampleCache2"

        maxElementsInMemory="1000"

        eternal="true"

        timeToIdleSeconds="0"

        timeToLiveSeconds="0"

        overflowToDisk="false"

        /> -->

 

    <!-- Place configuration for your caches following -->

 

</ehcache>

 

Category.java

 

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

 

import org.hibernate.annotations.Cache;

import org.hibernate.annotations.CacheConcurrencyStrategy;

 

@Entity

//@BatchSize(size=5)

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,region ="sampleCache1")//第一个参数设置缓存可以读写,第二个参数设置使用哪个配置的缓存

public class Category {

private int id;

private String name;

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

 

43.使用查询缓存的设置(相同的查询)

 

hibernate.cfg.xml

 

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

 

<hibernate-configuration>

    <session-factory>

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <property name="connection.url">jdbc:mysql://localhost/hibernate</property>

        <property name="connection.username">root</property>

        <property name="connection.password">bjsxt</property>

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- JDBC connection pool (use the built-in) -->

        <property name="connection.pool_size">1</property>

        <!-- Enable Hibernate's automatic session context management -->

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

 <property name="cache.use_second_level_cache">true</property>

<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

<property name="cache.use_query_cache">true</property> //查询缓存设置

 

        <!-- Echo all executed SQL to stdout -->

        <property name="show_sql">true</property>

        <property name="format_sql">true</property>

 

        <!-- Drop and re-create the database schema on startup

        <property name="hbm2ddl.auto">update</property>

 -->

        <!--  

        

<mapping resource="com/bjsxt/hibernate/Group.hbm.xml"/>

 <mapping resource="com/bjsxt/hibernate/User.hbm.xml"/>

 -->

 <mapping class="com.bjsxt.hibernate.Category"/>

  <mapping class="com.bjsxt.hibernate.Msg"/>

  <mapping class="com.bjsxt.hibernate.Topic"/>

    </session-factory>

 

</hibernate-configuration>

 

 

//join fetch

@Test

public void testQueryCache() {

Session session = sf.openSession();

session.beginTransaction();

List<Category> categories = (List<Category>)session.createQuery("from Category")

.setCacheable(true).list();

session.getTransaction().commit();

session.close();

Session session2 = sf.openSession();

session2.beginTransaction();

List<Category> categories2 = (List<Category>)session2.createQuery("from Category")

.setCacheable(true).list();

session2.getTransaction().commit();

session2.close();

}

 

44.缓存算法

 

a)缓存算法:(纯为了面试)

i.    LRU  LFU  FIFO

1.Least Recently Used –最近很少被使用

2.Least Frequently Used(命中率高低)

3.First In First Out 按顺序替换

ii.     memoryStoreEvictionPolicy = "LRU"

(ehcache.xml中配置) 

 

45.集中有关事务的问题

 

①脏读(dirty read)

读取别人还没提交的事物

②不可重复读(non-repeatable read)

别人已经提交了事物,我这边更新,发现和前面的数据不一样了(针对更新)

③幻读(phantom  read)

别人插入了数据,我读的结果和上次不一样(针对插入)

 

 

1       事务并发处理(面试的意义更大)

a)事务:ACID

i.Atomic Consistency Itegrity Durability

b)事务并发时可能出现的问题:

第一类丢失更新(Lost Update)

时间

取款事务A

存款事务B

T1

开始事务

 

T2

 

开始事务

T3

查询账户余额为1000元

 

T4

 

查询账户余额为1000元

T5

 

汇入100元把余额改为1100元

T6

 

提交事务

T7

取出100元把余额改为900 元

 

T8

撤销事务

 

T9

余额恢复为1000元(丢失更新)

 

   

    dirty read脏读(读到了另一个事务在处理中还未提交的数据)

时间

取款事务A

存款事务B

T1

开始事务

 

T2

 

开始事务

T3

 

查询账户余额为1000元

T4

 

汇入100元把余额改为1100元

T5

查询账户余额为1100元(读取脏数据)

 

T6

 

回滚

T7

取款1100

 

T8

提交事务失败

 

 

    non-repeatable read 不可重复读

时间

取款事务A

存款事务B

T1

开始事务

 

T2

 

开始事务

T3

查询账户余额为1000元

 

T5

 

汇入100元把余额改为1100元

T5

 

提交事务

T6

查询帐户余额为1100元

 

T8

提交事务

 

 

    second lost update problem 第二类丢失更新(不可重复读的特殊情况)

时间

取款事务A

存款事务B

T1

 

开始事务

T2

开始事务

 

T3

 

查询账户余额为1000元

T4

查询账户余额为1000元

 

T5

 

取出100元把余额改为900元

T6

 

提交事务

T7

汇入100元

 

T8

提交事务

 

T9

把余额改为1100元(丢失更新)

 

 

    phantom read 幻读

时间

查询学生事务A

插入新学生事务B

T1

开始事务

 

T2

 

开始事务

T3

查询学生为10人

 

T4

 

插入1个学生

T5

查询学生为11人

 

T6

 

提交事务

T7

提交事务

 

c)数据库的事务隔离机制

i.    查看 java.sql.Connection 文档

 

ii.    1:read-uncommitted  2:read-committed  4:repeatable read  8:serializable(数字代表对应值)

为什么取值要使用 1 2 4 8 而不是 1 2 3 4

1=0000  2=0010 4=0100 8=1000(位移计算效率高)

1.只要数据库支持事务,就不可能出现第一类丢失更新

2.read-uncommitted(允许读取未提交的数据) 会出现dirty read, phantom-read,

non-repeatable read 问题

3.read-commited(读取已提交的数据 项目中一般都使用这个)不会出现dirty read,因为只有另

一个事务提交才会读出来结果,但仍然会出现 non-repeatable read 和 phantom-read

   使用read-commited机制可用悲观锁 乐观锁来解决non-repeatable read 和 phantom-read问题

4.repeatable read(事务执行中其他事务无法执行修改或插入操作     较安全)

5.serializable解决一切问题(顺序执行事务 不并发,实际中很少用)

 

46.悲观锁和乐观锁

悲观锁:当前被更新的数据被我锁定,谁都不能更改,直到我更改完以后,解锁了,别人才可以更改

乐观锁:我和别人都可以更改,在我更改的时候,重新到数据库查询这条数据还是不是原来的那条,如果不是,重新再查一次,进行更新,一般会用

update_time或则version字段来实现

在hibernate中的设置

 

a)设定hibernate的事务隔离级别(使用hibernate.connection.isolation配置 取值1、2、4、8)

i.    hibernate.connection.isolation = 2(如果不设 默认依赖数据库本身的级别)

 

        ii.    用悲观锁解决repeatable read的问题(依赖于数据库的锁)

 

①使用悲观锁

                  @Test

public void testPessimisticLock() {

Session session = sf.openSession();

session.beginTransaction();

 

Account a = (Account)session.load(Account.class, 1, LockMode.UPGRADE);

int balance = a.getBalance();

//do some caculation

balance = balance - 10;

a.setBalance(balance);

session.getTransaction().commit();

session.close();

 

}

②使用乐观锁

 

Account.java

 

package com.bjsxt.hibernate;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.Version;

 

@Entity

public class Account {

private int id;

private int balance;

private int version;

@Version

public int getVersion() {

return version;

}

public void setVersion(int version) {

this.version = version;

}

@Id

@GeneratedValue

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public int getBalance() {

return balance;

}

public void setBalance(int balance) {

this.balance = balance;

}

 

}

 

47.知识点重要程程度总结

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿的十万个为什么

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值