hibernate学习笔记

本文参考博主李阿昀的专栏完成。

项目的Github地址

直接简单的说了,详细内容去看专栏,写的非常棒!

关键内容

配置文件

两个关键配置文件:
1.xxx.hbm.xml:它主要是用于描述类与数据库中的表的映射关系。(如果在实体类中使用注解,则不需要该配置文件,推荐注解方式)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.yubotao.hibernate">
    <!--
        name:即实体类的全名
        table:映射到数据库里面的那个表的名称
        catalog:数据库的名称
     -->
    <class name="Customer" table="t_customer" catalog="hibernatetest">
        <!-- class下必须要有一个id的子元素 -->
        <!-- id是用于描述主键的 -->
        <id name="id" column="id">
            <!-- 主键生成策略 -->
            <generator class="native"></generator>
        </id>
        <!--
            使用property来描述属性与字段的对应关系
            如果length忽略不写,且你的表是自动创建这种方案,那么length的默认长度是255
        -->
        <property name="name" column="name" length="20"></property>
        <property name="address" column="address" length="50"></property>
        <property name="sex" column="sex" length="20"></property>
    </class>
</hibernate-mapping>

2.hibernate.cfg.xml:它是Hibernate框架的核心配置文件。(也可以用hibernate.properties

<?xml version="1.0" encoding="UTF-8"?>
<!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>
        <!-- 配置关于数据库连接的四个项:driverClass  url username password -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///hibernatetest</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">*****</property>

        <!-- 可以将向数据库发送的SQL语句显示出来 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL语句 -->
        <property name="hibernate.format_sql">true</property>

        <!-- hibernate的方言 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 如果数据库中有表,不创建,没有表则创建;如果映射不匹配,会自动更新表结构。 -->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 配置hibernate的映射文件所在的位置 -->
        <mapping resource="Customer.hbm.xml" />
        <mapping class="com.yubotao.hibernate.annotation.Book"/>
        <mapping class="com.yubotao.hibernate.annotation.Person"/>
        <mapping class="com.yubotao.hibernate.manyToOne.Customer"/>
        <mapping class="com.yubotao.hibernate.manyToOne.Order"/>

        <mapping class="com.yubotao.hibernate.manyToMany.Student"/>
        <mapping class="com.yubotao.hibernate.manyToMany.Teacher"/>
    </session-factory>
</hibernate-configuration>
核心类及接口

共6个:SessionSessionFactoryTransactionQueryCriteriaConfiguration。(其中Criteria并不常用)

Configuration:主要是用于加载Hibernate的核心配置文件。

// 创建Configuration来加载配置文件
        Configuration config = new Configuration().configure();

Configuration config=new Configuration().config(核心配置文件名称); // 加载指定名称的配置文件

SessionFactory:该接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。

SessionFactory sessionFactory = config.buildSessionFactory();

Session:该接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。但需要注意的是Session对象是非线程安全的。

Session session = sessionFactory.openSession();

常用方法
save():保存对象
update ():修改操作
delete():删除
get()/load():根据id进行查询
saveOrUpdate():执行save或update操作
createQuery():获取一个Query对象
createSQLQUery():获取一个可以操作SQL的SQLQuery对象
createCriteria():取一个Criteria对象,它可以完成条件查询

Transaction:该接口主要用于管理事务,它是Hibernate的事务接口,对底层的事务进行了封装。使用它可以进行事务操作。

Transaction transaction = session.beginTransaction();

Query:该接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。

Query query = session.createQuery("hql语句");

SQLQuery sqlQuery = session.createSQLQuery("本地sql语句");

注意:SQLQuery是Query的子类。

执行过程总结
  1. 通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件。
  2. hibernate.cfg.xml中的<mapping resource="com/xx/Xxx.hbm.xml"/>读取解析映射信息。
  3. 通过config.buildSessionFactory();得到sessionFactory。
  4. sessionFactory.openSession();得到session。
  5. session.beginTransaction();开启事务。
  6. persistent operate; 执行你自己的操作。(用到了Query)
  7. session.getTransaction().commit();提交事务。
  8. 关闭session。
  9. 关闭sessionFactory。

注解

@Entity // 定义了一个实体
// name是表名,catalog是数据库名
@Table(name = "t_book",catalog = "hibernatetest") 
public class Book {

    @Id // 这表示一个主键
    // @GeneratedValue 相当于native主键生成策略
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 相当于identity主键生成策略
    private Integer id; // 主键

    //定义列,name为列名
    @Column(name = "b_name",length = 30, nullable = true)
    private String name;

    @Temporal(TemporalType.TIMESTAMP) // 是用来定义日期类型
    private Date publicationDate; // 出版日期

    @Type(type = "double") // 允许你去指定Hibernate里面的一些类型
    private Double price; // 价格,如果没有添加注解,也会自动的生成在表中

    @Transient // 现在这个属性不想生成在表中
    private String msg;
}

使用uuid进行主键生成

    @Id
    @GenericGenerator(name = "myuuid", strategy = "uuid") // 声明一种主键生成策略(uuid)
    @GeneratedValue(generator = "myuuid") // 引用uuid主键生成策略
    private String id;

另外还有一对多注解@OneToMany@ManyToOne
及多对多注解@ManyToMany@JoinTable
它们都用到了@Cascade
这块还是要仔细看这里。内容较多,不展开了。

操作

带参数条件查询

// 条件查询
    @Test
    public void test4() {
        Session session = HibernateUtils.openSession();
        session.beginTransaction();

        // 2.根据名称来绑定
        // 1.1创建hql语句
        String hql = "from Order where money > :mymoney";

        // 1.2执行hql语句
        List<Order> list = session.createQuery(hql).setParameter("mymoney", 2000d).list();

        System.out.println(list);

        session.getTransaction().commit();
        session.close();
    }

from 类名;where后面的子句中使用的是实体类的实例变量,不是表中的列名,这是与mysql不同的地方。并且这里可以使用某示例.实例变量的形式。
如:

public class Student {
    ...
    private Set<Teacher> teachers = new HashSet<Teacher>();
    ...
}
public class Teacher {
    private Integer id;
    private String name;
    ...
}

则可以这么写hql

from Student where teachers.id = :id

注意

有外键插入的时候需要注意!需要进行相应的级联操作。

这里刚好遇到一个错误

object references an unsaved transient instance - save the transient instance before flushing

就是因为主表数据还未插入,从表就插入,导致的报错。这里的处理方法如here
思路就是先将主表数据持久化。

        // 操作
        Customer c = new Customer();
        c.setName("武松");
        // 需要先将主表数据插入表中,否则从表无法插入,会报错save the transient instance before flushing
        session.persist(c);

        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setMoney(1000d + i * 10);
            order.setReceiverInfo("北京");
            order.setC(c);
            session.save(order);
        }

这里的session.persist(c);先于session.save(order);,就是针对主从表的插入顺序。

本地sql

也可以使用本地sql,不用写hql。

如本地为mysql时,测试代码如下:

    // 测试执行本地sql
    @Test
    public void test1() {

        Session session = HibernateUtils.openSession();
        session.beginTransaction();

        // 执行本地sql
        SQLQuery sqlQuery = session.createSQLQuery("select * from t_customer");
        // List list = sqlQuery.list();
        // System.out.println(list);

        // List<Object[]> list = sqlQuery.list();

        sqlQuery.addEntity(Customer.class); // 如何能得到一个对象呢?
        // 将查询结果绑定到指定对象
        List list = sqlQuery.list();
        System.out.println(list);

        session.getTransaction().commit();
        session.close();

    }

暂时总结这些基础内容,由于目前还处于学习hibernate的阶段,所以也没啥有质量的输出,先这样吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值