ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Hibernate基础知识

2021-12-07 20:32:05  阅读:150  来源: 互联网

标签:Hibernate tab private 基础知识 session hibernate import class


1 概念

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库

概念解释

orm:object relational mapper 对象关系映射
    持久层实现java类的属性与rdbms表的列一一对应关系
    实现java对象和结果集行的对应关系
域模型:java中模型对象的思想
       java类之间的关系
       关联关系:订单和客户:订单要指定其所属客户  (部分依赖)
       聚集关系:轮胎和车:轮胎是车的一部分 (整体和部分)
       依赖关系:action和service:action中所有方法都要通过service来实现  (类似于寄生)
       一般关系:儿子和父亲:继承关系
      
关系模型:rdbms中的二维表
    :1对1  :把从表的主键定义为外键  来引用主表的主键
    :n对n  :定义一个关系表:定义两列作为联合主键  这两列作为外键 类分别引用另外两张表的主键
    :1对n  :把1定义为主表  把n定义为从表  在从表中定义一个外键来引用主表的主键

2 hibernate案例

2.1 创建项目:web/java

2.2 导入jar包

image

2.3 创建核心配置文件

  • 位置src
  • 名字:hibernate.properties
hibernate.dialect=org.hibernate.dialect.MySQLDialect  #指定方言
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost:3306/db_37
hibernate.connection.username=root
hibernate.connection.password=root
hibernate.show_sql=true                              #是否显示sql语句

2.4 创建数据库

DROP TABLE student;
CREATE TABLE `student` (
  `sid` INT(11) NOT NULL AUTO_INCREMENT,
  `sname` VARCHAR(11) DEFAULT NULL,
  `sex` CHAR(1) DEFAULT NULL,
  `score` FLOAT(4,1) DEFAULT NULL,
  `sdy` TINYINT(1) DEFAULT NULL,
  `sbirthday` DATE DEFAULT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=INNODB AUTO_INCREMENT=221 DEFAULT CHARSET=utf8
INSERT INTO student VALUES(
   NULL,
   SUBSTRING(UUID(),1,8),
   IF(RAND()>0.5,"男","女"),
   CEIL(RAND()*100),
   RAND()>0.5,
   CONCAT(CEIL(RAND()*10+1990),"-",CEIL(RAND()*12),"-",CEIL(RAND()*31))
 );
 SELECT * FROM student;

2.5 mapper映射文件:

  • 创建实体类
public class Student implements Serializable {
    private Integer sid;
    private String sname;
    private String sex;
    private Float score;
    private Boolean sdy;
    private Date sbirthday;
    ...
}
  • 指定表的列与类的属性的对应关系:位置必须和实体类同一个包 名字必须是:实体类.hbm.xml
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="sss.entity.Student" table="student">
        <!-- 指定主键列对应的属性 -->
        <id name="sid" column="sid" type="int">
            <!-- 主键自增方式:数据库自增-->
            <generator class="identity"/>
        </id>
        <property name="sname" column="sname" type="string"/>
        <property name="sex" column="sex" type="string"/>
        <property name="sbirthday" column="sbirthday" type="date"/>
        <property name="sdy" column="sdy" type="boolean"/>
        <property name="score" column="score" type="float"/>
    </class>
</hibernate-mapping>

2.6 测试类

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import sss.entity.Student;

import java.util.Date;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        //1 创建Configration对象 自动读取heibernate的核心配置文件
        Configuration conf = new Configuration();
        //2 读取指定实体类的mapper映射文件
        conf.addClass(Student.class);
        //3 通过Configuration创建sessionfactory对象
        SessionFactory factory = conf.buildSessionFactory();
        //4 获取连接
        Session session = factory.openSession();
        //5 创建事务
        Transaction transaction = session.beginTransaction();
        //6 开启事务
        transaction.begin();

        /*通过session实现crud*/
        //获取一个
        Student s1 = (Student) session.get(Student.class, 221);
        System.out.println(s1);
        //获取所有
        //hql语句:面向对象的
        Query query = session.createQuery("from sss.entity.Student");
        List<Student> list = query.list();
        System.out.println(list);
        //添加一个
        session.save(new Student(1, "叶晨", "男", 66f, false, new Date()));
        //修改一个:要求修改和删除之前必须先获取对象
        Student s2 = (Student) session.get(Student.class, 222);
        s2.setSbirthday(new Date());
        s2.setScore(33f);
        s2.setSname("楚灵");
        s2.setSex("女");
        session.update(s2);
        //删除一个
        Student s3 = (Student) session.get(Student.class, 223);
        session.delete(s3);
        //事务提交
        transaction.commit();
        //关闭连接
        session.close();
    }
}

3 hibernate改进(配置文件是xml)

3.1 创建xml核心配置文件:

  • 名字随意
  • 位置随意:hibernatepro.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="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- 指定连接的四大参数 -->
        <property name="connection.url">jdbc:mysql://localhost:3306/ssr</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <!-- 是否显示sql语句 -->
        <property name="show_sql">true</property>

        <!-- 导入类与表的映射文件 -->
        <mapping resource="sss/entity/Student.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

3.2创建测试类

  • TestPro
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import sss.entity.Student;

public class TestPro {
    public static void main(String[] args) {
        //1 创建Configration对象 自动读取heibernate的核心配置文件
        Configuration conf = new Configuration();
        //2 读取核心配置文件
        conf.configure("sss/test/hibernatepro.xml");
        //3 通过Configuration创建sessionfactory对象
        SessionFactory factory = conf.buildSessionFactory();
        //4 获取连接
        Session session = factory.openSession();
        //5 创建事务
        Transaction transaction = session.beginTransaction();
        //6 开启事务
        transaction.begin();

		//增 删 改 ......
        
        //7 事务提交
        transaction.commit();
        //8 关闭连接
        session.close();
    }
}

4 主键自增方式(策略)

  • 在save插入行数据时 指定主键值的方式
  • 在xml中修改
<id name="sid" column="sid" type="int">
    <generator class="identity"/><!-- 主键自增方式:数据库自增-->
</id>

4.1 可选类型

* increment:适用于int/long/short类型的字段: hibernate自增
* identity:适用于int/long/short类型的字段:数据库自增:支持auto_increment的数据库:mysql
* sequence:通过sequence实现自增的数据库:oracle
* assinged:主键列由程序员手动赋值
* uuid:适用于string类型的字段:随机一个32位16进制的字符串
* hilo:适用于int/long/short类型的字段 根据高/低位算法自动生成
* native:由程序根据数据库自动选择:identity、sequence、hilo

4.2 increment自增

<id name="sid" column="sid" type="int">
    <--主键自增方式:auto_increment [数据库需要使用auto_increment 否则无效]-->
    <generator class="identity"/> 
        
    <!-- 主键自增方式:hibernate自增-->
    <generator class="increment"/>
</id>
  • 添加
//添加一个
session.save(new Student("韩梅3","女",11f,true,new Date()));//不指定sid 通过hibernate自增 自动赋值
  • sql语句::执行了两次sql语句
Hibernate: select max(sid) from student
Hibernate: insert into student (sname, sex, sbirthday, sdy, score, sid) values (?, ?, ?, ?, ?, ?)
  • 注意:
increment自增是hibernate自增:会先查询当前表的主键的最大值  然后最大值+1给添加的对象的主键列赋值
不适应于:多线程或者分布式项目

4.3 sequence序列自增

  • 创建oracle表,mysql不能用
CREATE TABLE stu(
  sid INT PRIMARY KEY,
  sname VARCHAR(20),
  sex CHAR(3),
  score FLOAT,
  sbirthday DATE
)

CREATE sequence seq_stu_11 START WITH 1000

INSERT INTO stu VALUES(
   seq_stu_11.nextval,
   dbms_random.string('x',6),
   '男',
   trunc(dbms_random.value*100,1),
   to_date(trunc(dbms_random.value*10+1990)||'-'||trunc(dbms_random.value*12+1)||'-'||trunc(dbms_random.value*30+1),'yyyy-MM-dd')
);
  • 创建实体类
public class Stu implements Serializable {
    private Integer sid;
    private String sname;
    private String sex;
    private Float score;
    private Date sbirthday;
    ...
}
  • 创建mqpper映射文件-->Stu.hbm.xml
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="sss.entity.Stu" table="stu">
        <!-- 指定主键列对应的属性 -->
        <id name="sid" column="sid" type="int">
            <!--<generator class="identity"/> 主键自增方式:数据库自增 auto_increment-->
            <!-- <generator class="increment"/>主键自增方式:hibernate自增-->
            <!-- sequence自增 -->
            <generator class="sequence">
                <param name="sequence">seq_stu_11</param>
            </generator>
        </id>
        <property name="sname" column="sname" type="string"/>
        <property name="sex" column="sex" type="string"/>
        <property name="score" column="score" type="float"/>
        <property name="sbirthday" column="sbirthday" type="date"/>

    </class>
</hibernate-mapping>
  • 创建hibernate.xml连接oracle
<?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="dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.username">wen</property>
        <property name="connection.password">123</property>
        <!-- 是否显示sql语句 -->
        <property name="show_sql">true</property>

        <!-- 导入类与表的映射文件-->
        <mapping resource="sss/entity/Stu.hbm.xml"/>
    </session-factory>
</hibernate-configuration>
  • 测试
//添加一个
session.save(new Stu("楚灵", "女", 11f, new Date()));

4.4 uuid自增:只适用于字符串类型的主键列

  • 创建表
CREATE TABLE tea(
    tid varchar(50) primary key,
    tname VARCHAR(20)
)
  • mapper映射文件
  • 注意:使用uuid定义id必须是String类型
<id name="sid" column="sid" type="int">
    <!-- uuid自增-->
    <generator class="uuid"/>
</id>
  • 测试
//插入一条数据
session.save(new Stu("楚宣", "女", 11f, new Date()));

5 表与表之间的关系

5.1 1对n

  • 在多的一方定义外键 来引用主表的主键

创建数据库

CREATE TABLE tea(
   tid INT PRIMARY KEY AUTO_INCREMENT,
   tname VARCHAR(11)
);
INSERT INTO tea VALUES(1,"李老师");
INSERT INTO tea VALUES(2,"郭老师");

CREATE TABLE stu(
   sid INT PRIMARY KEY AUTO_INCREMENT,
   sname VARCHAR(11),
   stid INT,
   CONSTRAINT fk_099 FOREIGN KEY(stid) REFERENCES tea(tid)
);
INSERT INTO stu VALUES(1001,"李老师学生1",1);
INSERT INTO stu VALUES(1002,"李老师学生2",1);
INSERT INTO stu VALUES(2001,"郭老师学生1",2);
INSERT INTO stu VALUES(2002,"郭老师学生2",2);

创建实体类

public class Stu implements Serializable {
    private Integer sid;
    private String sname;
    //定义引用记录老师
    private Tea tea;
    ...
}
public class Tea implements Serializable {
    private Integer tid;
    private String tname;
    //定义集合记录学生
    private Set<Stu> stuSet;
    ...
}

mapper映射文件

  • Stu.hbm.xml
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="sss.entity.Stu" table="stu">
        <!-- 指定主键列对应的属性 -->
        <id name="sid" column="sid" type="int">
            <!-- 自增-->
            <generator class="identity"/>
        </id>
        <property name="sname" column="sname" type="string"/>
        <!--n对1-->
        <!--
            many-to-one:
                name:n中定义的引用
                column:外键列名
        -->
        <many-to-one name="tea" column="stid" class="sss.entity.Tea"/>

    </class>
</hibernate-mapping>
  • Tea.hbm.xml
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="sss.entity.Tea" table="tea">
        <!-- 指定主键列对应的属性 -->
        <id name="tid" column="tid" type="int">
            <!-- 自增-->
            <generator class="identity"/>
        </id>
        <property name="tname" column="tname" type="string"/>
        <!--1对n-->
        <!--
            one-to-money:
                set的属性:name 对应的n集合的引用名
                key的column:从表的外键列名
                one-to-money的class:集合元素的类型
        -->
        <set name="stuSet" lazy="true">
            <key column="stid"/>
            <one-to-many class="sss.entity.Stu"/>
        </set>

    </class>
</hibernate-mapping>

测试

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import sss.entity.Stu;

public class TestPro {
    public static void main(String[] args) {
        //1 创建Configration对象 自动读取heibernate的核心配置文件
        Configuration conf = new Configuration();
        //2 读取核心配置文件
        conf.configure("sss/test/hibernatepro.xml");
        //3 通过Configuration创建sessionfactory对象
        SessionFactory factory = conf.buildSessionFactory();
        //4 获取连接
        Session session = factory.openSession();
        //5 创建事务
        Transaction transaction = session.beginTransaction();
        //6 开启事务
        transaction.begin();
        
        Stu s1 = (Stu) session.get(Stu.class, 1001);
        System.out.println(s1);

        //7 事务提交
        transaction.commit();
        //8 关闭连接
        session.close();
    }
}

5.2 1对1

创建数据库

CREATE TABLE husband(
   hid INT PRIMARY KEY AUTO_INCREMENT,
   hname VARCHAR(11)
);
INSERT INTO husband VALUES(1,"李先生");
INSERT INTO husband VALUES(2,"高先生");
CREATE TABLE wife(
   wid INT PRIMARY KEY AUTO_INCREMENT,
   wname VARCHAR(11),
   CONSTRAINT fk_091 FOREIGN KEY(wid) REFERENCES husband(hid)
);
INSERT INTO wife VALUES(1,"李太太");
INSERT INTO wife VALUES(2,"高太太");

实体类

public class Husband implements Serializable {
    private Integer hid;
    private String hname;
    //定义引用记录妻子
    private Wife wife;
    ...
}
public class Wife implements Serializable {
    private Integer wid;
    private String wname;
    private  Husband husband;
    ...
}

mapper映射文件

  • Husband.hbm.xml
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="sss.entity.Husband" table="husband">
        <!-- 指定主键列对应的属性 -->
        <id name="hid" column="hid" type="int">
            <!-- 自增-->
            <generator class="identity"/>
        </id>
        <property name="hname" column="hname" type="string"/>
        <!--1对1-->
        <one-to-one name="wife" class="sss.entity.Wife"/>

    </class>
</hibernate-mapping>
  • Wife.hbm.xml
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="sss.entity.Wife" table="wife">
        <!-- 指定主键列对应的属性 -->
        <id name="wid" column="wid" type="int">
            <!-- 自增-->
            <generator class="identity"/>
        </id>
        <property name="wname" column="wname" type="string"/>
        <!--1对1-->
        <one-to-one name="husband" class="sss.entity.Husband"/>

    </class>
</hibernate-mapping>
  • hibernatepro.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="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/ssr</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <!-- 是否显示sql语句 -->
        <property name="show_sql">true</property>

        <!-- 导入类与表的映射文件-->
        <mapping resource="sss/entity/Stu.hbm.xml"/>
        <mapping resource="sss/entity/Tea.hbm.xml"/>
        <mapping resource="sss/entity/Husband.hbm.xml"/>
        <mapping resource="sss/entity/Wife.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

测试

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import sss.entity.Husband;
import sss.entity.Wife;

public class TestPro {
    public static void main(String[] args) {
        //1 创建Configration对象 自动读取heibernate的核心配置文件
        Configuration conf = new Configuration();
        //2 读取核心配置文件
        conf.configure("sss/test/hibernatepro.xml");
        //3 通过Configuration创建sessionfactory对象
        SessionFactory factory = conf.buildSessionFactory();
        //4 获取连接
        Session session = factory.openSession();
        //5 创建事务
        Transaction transaction = session.beginTransaction();
        //6 开启事务
        transaction.begin();

        Husband h1 = (Husband) session.get(Husband.class, 1);
        System.out.println(h1+":::"+h1.getWife());

        Wife w1 = (Wife) session.get(Wife.class, 2);
        System.out.println(w1+":::"+w1.getHusband());

        //7 事务提交
        transaction.commit();
        //8 关闭连接
        session.close();
    }
}

5.3 n对n

创建表

CREATE TABLE tab_goods(
   gid INT PRIMARY KEY AUTO_INCREMENT,
   gname VARCHAR(11),
   gprice FLOAT(6,1)
);
INSERT INTO tab_goods VALUE (1,"铅笔",2.1);
INSERT INTO tab_goods VALUE (2,"橡皮",0.5);
INSERT INTO tab_goods VALUE (3,"本子",1.0);

CREATE TABLE tab_order(
   oid INT PRIMARY KEY AUTO_INCREMENT,
   omoney FLOAT(9,1),
   otime DATE
);
INSERT INTO tab_order VALUES(1,10000,'2021-01-01');
INSERT INTO tab_order VALUES(2,2000,'2021-02-01');
INSERT INTO tab_order VALUES(3,300,'2021-03-01');

CREATE TABLE tab_goods_order(
   ooid INT,
   ggid INT,
   PRIMARY KEY(ooid,ggid),
   CONSTRAINT fk_092 FOREIGN KEY(ooid) REFERENCES tab_order(oid),
   CONSTRAINT fk_093 FOREIGN KEY(ggid) REFERENCES tab_goods(gid)   
);
INSERT INTO tab_goods_order VALUES(1,1),(1,2),(1,3);
INSERT INTO tab_goods_order VALUES(2,1),(2,2);
INSERT INTO tab_goods_order VALUES(3,1),(3,3);

实体类

public class Goods implements Serializable {
    private Integer gid;
    private String gname;
    private Float gprice;
    private Set<Order> orderSet;
	......
}
public class Order implements Serializable {
    private Integer oid;
    private Float omoney;
    private Date otime;
    private Set<Goods> goodsSet;
	......
}

映射文件

  • Goods.hbm.xml
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="sss.entity.Goods" table="tab_goods">
        <!-- 指定主键列对应的属性 -->
        <id name="gid" column="gid" type="int">
            <!-- 自增-->
            <generator class="identity"/>
        </id>
        <property name="gname" column="gname" type="string"/>
        <property name="gprice" column="gprice" type="float"/>
        <!--n对n-->
        <set name="orderSet" table="tab_goods_order">
            <!--key的column当前表tab_goods在关系表中的外键列-->
            <key column="ggid"/>
            <!--many-to-many的column对方表tab_order在关系表中的外键列-->
            <many-to-many column="ooid" class="sss.entity.Order"/>
        </set>

    </class>
</hibernate-mapping>
  • Order.hbm.xml
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="sss.entity.Order" table="tab_order">
        <!-- 指定主键列对应的属性 -->
        <id name="oid" column="oid" type="int">
            <!-- 自增-->
            <generator class="identity"/>
        </id>
        <property name="omoney" column="omoney" type="float"/>
        <property name="otime" column="otime" type="date"/>
        <!--n对n-->
        <set name="goodsSet" table="tab_goods_order">
            <!--key的column当前表tab_order在关系表中的外键列-->
            <key column="ooid"/>
            <!--many-to-many的column对方表tab_goods在关系表中的外键列-->
            <many-to-many column="ggid" class="sss.entity.Goods"/>
        </set>

    </class>
</hibernate-mapping>
  • hibernatepro.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="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/ssr</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <!-- 是否显示sql语句 -->
        <property name="show_sql">true</property>

        <!-- 导入类与表的映射文件-->
        <mapping resource="sss/entity/Stu.hbm.xml"/>
        <mapping resource="sss/entity/Tea.hbm.xml"/>
        <mapping resource="sss/entity/Husband.hbm.xml"/>
        <mapping resource="sss/entity/Wife.hbm.xml"/>
        <mapping resource="sss/entity/Goods.hbm.xml"/>
        <mapping resource="sss/entity/Order.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

测试

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import sss.entity.Goods;
import sss.entity.Order;

public class TestPro {
    public static void main(String[] args) {
        //1 创建Configration对象 自动读取heibernate的核心配置文件
        Configuration conf = new Configuration();
        //2 读取核心配置文件
        conf.configure("sss/test/hibernatepro.xml");
        //3 通过Configuration创建sessionfactory对象
        SessionFactory factory = conf.buildSessionFactory();
        //4 获取连接
        Session session = factory.openSession();
        //5 创建事务
        Transaction transaction = session.beginTransaction();
        //6 开启事务
        transaction.begin();

        Goods g1 = (Goods) session.get(Goods.class, 2);
        System.out.println(g1 + ":::" + g1.getOrderSet());
        Order o1 = (Order) session.get(Order.class, 3);
        System.out.println(o1 + ":::" + o1.getGoodsSet());

        //7 事务提交
        transaction.commit();
        //8 关闭连接
        session.close();
    }
}

6 hibernate中get和load的区别

  • 相同之处
1 都是通过主键获取一个对象
2 都需要指定对象的类型
  • 不同之处
get和load的区别
1:当对应的主键值不存在时:
	get返回的是null
    load抛出异常:ObjectNotFoundException
2:正常运行时:
	get会立刻发送并执行sql语句 获取对应的结果对象
    load不会立刻发送sql语句 load方法获取的是proxy代理对象
    (此对象类型和id确定但其他属性无值)
    只有当调用代理对象时才发送和执行sql语句
    如果session关闭才第一次调用代理对象会抛出异常:LazyInitializationException

7 属性lazy和cascade

  • lazy:在xml中修改
懒加载:lazy="true" 默认:
	学生关联老师:获取学生时 如果不调用老师 
	学生的老师属性tea赋值的是代理对象:只有id属性
    只有在调用此老师属性时 才执行sql语句
    如果session关闭 才第一次调用此老师属性会报错:LazyInitializationException
立刻加载:lazy="false" 默认:
    学生关联老师:会执行两个sql语句:sql1获取学生 sql2获取学生关联的老师
  • cascade:在xml中修改
cascade="save-update":级联操作:添加或者修改学生时 学生关联的老师也会级联添加/修改
cascade="delete":级联操作:删除学生时 学生关联的老师也会删除
cascade="all":=cascade="save-update"+cascade="delete"
  • 代码测试
Order o1 = new Order(10, 11111f, new Date());
Set<Goods> set = new HashSet<>();
//注意:级联添加时:关联对象不能设置id
set.add(new Goods(null, "袜子1", 11f));
set.add(new Goods(null, "袜子2", 12f));
set.add(new Goods(null, "袜子3", 13f));
o1.setGoodsSet(set);
session.save(o1);
/*
    Hibernate: insert into tab_order (omoney, otime) values (?, ?)
    Hibernate: insert into tab_goods (gname, gprice) values (?, ?)
    Hibernate: insert into tab_goods (gname, gprice) values (?, ?)
    Hibernate: insert into tab_goods (gname, gprice) values (?, ?)
    Hibernate: insert into tab_goods_order (ooid, ggid) values (?, ?)
    Hibernate: insert into tab_goods_order (ooid, ggid) values (?, ?)
    Hibernate: insert into tab_goods_order (ooid, ggid) values (?, ?)
*/

session.delete(session.get(Goods.class,4));
/*
    先查询出所有有关联的表,然后删除
    Hibernate: delete from tab_goods_order where ggid=?
    Hibernate: delete from tab_goods_order where ooid=?
    Hibernate: delete from tab_goods_order where ggid=?
    Hibernate: delete from tab_goods_order where ggid=?
    Hibernate: delete from tab_goods where gid=?
    Hibernate: delete from tab_goods where gid=?
    Hibernate: delete from tab_order where oid=?
    Hibernate: delete from tab_goods where gid=?
*/
  • 注意:级联操作时,关联的对象不能设置id

8 hibernate的检索方式

  • 检索:查询方式

8.1 ognl对象导航:通过对象a来获取关联的对象b

/*
    检索方式:OGNL:通过Stu关联的tea属性来获取对象
    Stu s1 = (Stu) session.get(Stu.class, 1001);
    System.out.println(s1.getTea());
*/

8.2 OID检索方式:通过get/load方法由主键值获取对象

/*
	检索方式:OID:通过get/load方法获取对象
	Stu s2 = (Stu) session.get(Stu.class, 1001);
    System.out.println(s2);
*/

8.3 HQL检索方式:通过Query接口获取对象

/*	
	检索方式:HQL :通过Query接口方式hql(类sql语句:面向对象的sql语句)语句
	idea中 hql中涉及到属性名会编译报错 但不影响执行
	
	*** 执行查找 ***
	Query q1 = session.createQuery("from sss.entity.Stu where sname=?");
	(q1=session.createQuery("from sss.entity.Stu");)
    q1.setParameter(0,"李老师学生1");
    System.out.println(q1.list());
    
    *** 执行修改 ***
    Query q2 = session.createQuery("update sss.entity.Stu set sname=? 
    where sid=?");
    q2.setString(0,"依依").setInteger(1,1001);
    System.out.println(q2.executeUpdate());
    
    *** 执行删除 ***
    Query q3 = session.createQuery("delete from sss.entity.Stu where sid=?");
    q3.setInteger(0,1001);
    System.out.println(q3.executeUpdate());
*/

8.4 QBC检索方式:通过Criteria接口获取对象

/*
    检索方式:QBC:通过Criteria接口 实现完全面向对象方式访问数据库
    参考:https://www.cnblogs.com/lukelook/p/9692429.html
    
    *** 查询所有 ***
    Criteria c1 = session.createCriteria(Stu.class);
    System.out.println(c1.list());
    
    *** 模糊查询 ***
    Criterion s1 = Restrictions.eq("sname", "李老师的学生2");
    Criterion s2 = Restrictions.like("sname", "%1%");
    Criterion s3 = Restrictions.or(s1, s2);
    c1.add(s3);
    System.out.println(c1.list());
    
    *** 分页 ***
	c1.setFirstResult(0);//设置起始行的索引:索引从0开始
    c1.setMaxResults(2);//设置每页记录数
    System.out.println(c1.list());
    (System.out.println(c1.setFirstResult(0).setMaxResults(2).list());)
*/

8.5本地SQL检索方式:通过手写sql查询数据库

/*
	检索方式:本地SQL:通过SQLQuery接口 写sql对数据库进行增删改查
    SQLQuery sql1 = session.createSQLQuery("select * from stu where sid>? and sname=?");
    List<Object[]> list1 = sql1.setInteger(0, 2).setString(1, "郭老师学生1").list();
    for (int i = 0; i <list1.size(); i++) {
        for (int j = 0; j <list1.get(i).length ; j++) {
            System.out.println(list1.get(i)[j]);
        };
    }

    SQLQuery sql2 = session.createSQLQuery("select * from stu where sid>? 
    and sname=?").addEntity(Stu.class);
    List<Stu> list2 = sql2.setInteger(0, 1).setString(1, "郭老师学生1").list();
    for (int i = 0; i <list2.size() ; i++) {
        System.out.println(list2.get(i));
    }	
*/

image

9 hibernate自动创建表

<property name="hibernate.hbm2ddl.auto">create-drop</property>

hibernate.hbm2ddl.auto:通过mapper映射文件自动创建或者修改表
hibernate.hbm2ddl.auto=create:如果表存在先删除表再创建,如果表不存在直接创建
hibernate.hbm2ddl.auto=create-drop:如果表存在先删除表再创建,如果表不存在直接创建 
					   SessionFactory:关闭前会删除创建的表
hibernate.hbm2ddl.auto=udpate:如果表不存在直接创建,表存在使用已有的,列同理
常用:hibernate.hbm2ddl.auto=udpate   

10 hibernate中对象的状态

image

/*
	***对象状态***
	1:瞬时态=游离态:Transient
	通过new创建的对象:此对象和session的数据库中的行无关,
	对对象进行操作不会影响数据库中的行记录
	Student s1=new Student(1,"韩雪","女",66f,true,new Date());
	
	2:持久态:Persistent
	通过load/get/list/iterator/save/saveorupdate等方法获取的对象,
	此对象和sesson数据库中的某行是对应关系
	s1=(Student)session.get(Student.class.1);
	在session关闭前/事务提交前:hibernate会自动判断持久态对象和对应的行数据是否一致
	如果不一致:会自动执行update语句,根据持久态对象的属性值来更改对应的行数据
    List<Student> list1 = session.createQuery("from sss.entity.Student").list();
    for (Student s:list1) {
        if(s.getSex().equals("女")){
            s.setScore(s.getScore()+200);
            System.out.println(1);
        }
    }
    Iterator<Student> it = session.createQuery("from sss.entity.Student").iterate();
    while(it.hasNext()){
        Student next = it.next();
        System.out.println(next);
    }
    System.out.println(it);
    
    3:脱管态:Detached
    当session关闭/清空/事务提交后  
    持久态的对象转换为脱管态:此对象和session数据库行脱离关联关系
    Student s1=new Student("5","韩雪","女",66.6,true,new Date());
    session.evict(s1);//s1转换为脱管态
    session.clear();
    s1.setSex("圣");
    s1.setScore(100.0);
    Iterator<Student> it = session.createQuery("from sss.entity.Student").iterate();
    while(it.hasNext()){
        Student s = it.next();
        if(s.getSex().equals("女")){
            s.setScore(s.getScore()+200);
        }
    }
    System.out.println(it);
	
*/

标签:Hibernate,tab,private,基础知识,session,hibernate,import,class
来源: https://www.cnblogs.com/RenVei/p/15658671.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有