1、模式
BS , CS
2、结构
(1)、程序代码结构:View 表示层 View
Action/sevlet/xx 数据
Jsp 模板
-----------------------------------
Service 业务层
Dao 数据访问层
-----------------------------------
MySQL, Oracle, SqlServer, Db2, ...
MySQLDaoImpl
OracleDaoImpl
MVC:从表示层看全局
JDBC:各种实现接口;从对象到表记录,从表记录到对象转换麻烦。
SQL
ORM:(只是一种设计方案,有好多实现框架)
对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。
3、学习线路
全限定名:cn.itcast.domain.User
简单名称:User
数据库信息:方言,URL,Driver,用户名,密码
4、hibernate的配置
maven配置包:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>seu.xinci</groupId>
<artifactId>test1</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.10.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
</dependencies>
</project>
<!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 name="foo">
<!-- 配置数据库信息-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!--<property name="connection.url">jdbc:mysql://localhost:3306/test2</property>-->
<property name="connection.url">jdbc:mysql:///test2</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">1234</property>
<!-- 显示SQL语句-->
<property name="show_sql">true</property>
<mapping resource="User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="seu.xinci.pojo">
<class name="User" table="table_user">
<!-- 主键-->
<id name="id" type="int" column="id">
<!--自动增长-->
<generator class="native" />
</id>
<!-- 一般 -->
<property name="name" type="java.lang.String" column="name" />
</class>
</hibernate-mapping>
session的获取与简单查询与保存:(hibernate版本为5)
通常作为静态工具类,获取工厂
private static SessionFactory sessionFactory;
//初始化工厂
static {
Configuration configuration = new Configuration();
//读取指定的配置文件
configuration.configure("hibernate.cfg.xml");
//configuration.buildSessionFactory();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}
User user = new User();
user.setName("张三");
//获取session
Session session = sessionFactory.openSession();
//开启事务
Transaction tx =session.beginTransaction();
session.save(user);
//提交事务
tx.commit();
//关闭session,释放资源
session.close();
自动递增ID,因此只有插入name
查询:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = (User) session.get(User.class,1);
tx.commit();
session.close();
System.out.println(user.toString());
open别忘了close
使用模式:
A、通过配置,创建工厂
B、获得session
C、创建事务
D、具体操作
E、提交事务,不成功回滚
D、关闭session
5、分页查询
1、全部查询出来,部分显示(附近的店)
2、查一部分,显示一部分(常用)
假设共有
25条记录,每页显示10条,则共3页。
firstResult maxResults
----------------------------------------
第1页 0 10
第2页 10 10
第3页 20 10
firstResult maxResults
----------------------------------------
第1页 0 10
第2页 10 10
第3页 20 10
total / pageSize
total % pageSize
total % pageSize
/**
* 分页查询数据列表
*
* @param firstResult 从结果列表中的哪个索引开始取数据
* @param maxResults 最多去多少条数据
* @return 一页的数据列表 + 总记录数
*/
public QueryResult findAll(int firstResult, int maxResults) {
Session session = HibernateUtils.getSession();
try {
Transaction tx = session.beginTransaction();//开始事务
//操作
//查询一页的数据量列表
//方法一:
// Query query = session.createQuery(
// "FROM seu.xinci.pojo.User");//使用HQL查询
// query.setFirstResult(firstResult);
// query.setMaxResults(maxResults);
// List<User> list =query.list();
//方法二:方法链
List<User> list = session.createQuery(
"FROM seu.xinci.pojo.User")
.setFirstResult(firstResult)
.setMaxResults(maxResults)
.list();
//查询总记录数
Long count = (Long) session.createQuery(
"SELECT COUNT(*) FROM seu.xinci.pojo.User")
.uniqueResult();
tx.commit();//提交事务
//返回结果
return new QueryResult(count.intValue(),list);
} catch (Exception e) {
session.getTransaction().rollback();//回滚事务
throw new RuntimeException(e);
} finally {
session.close();//关闭session
}
}
6、HQL简介
SQL
查询的是表和表中的字段。
不区分大小写
HQL
Hibernate Query Language
与SQL相似
查询的是对象和对象中的属性。
关键字不区分大小写,但类名与属性名区分大小写。
查询的是表和表中的字段。
不区分大小写
HQL
Hibernate Query Language
与SQL相似
查询的是对象和对象中的属性。
关键字不区分大小写,但类名与属性名区分大小写。
7、API与配置
API(1)、API简介。
(2)、Session中的方法。
(3)、查询:HQL与Criteria
配置:
(1)、主配置文件
(2)、映射文件
映射基础
普通属性
主键
集合属性
关联关系
一对多/多对一
多对多
一对一
关联关系
一对多/多对一
多对多
一对一
继承结构
------------------------------------------------------------------
-- API简介
Configuration 配置
configure()
configure(String resource)
addResource(String resource) 导入一个指定位置的映射文件
addClass(Class clazz) 导入与指定类同一个包中的以类名为前缀,后缀为.hbm.xml的映射文件
buildSessionFactory()
SessionFactory Session工厂
-- API简介
Configuration 配置
configure()
configure(String resource)
addResource(String resource) 导入一个指定位置的映射文件
addClass(Class clazz) 导入与指定类同一个包中的以类名为前缀,后缀为.hbm.xml的映射文件
buildSessionFactory()
SessionFactory Session工厂
openSession()
getCurrentSession()
close()
Session 很重要的一个对象
操作对象的方法
save(Object)
update(Object)
delete(Object)
查询的方法
createQuery(String) --> Query
createCriteria(Class)
createQuery(String) --> Query
createCriteria(Class)
管理事务的方法
beginTransaction() --> Transaction
getTransaction() --> Transaction 获取当前Session中关联的事务对象
其他的方法
...
Transaction 事务
commit()
rollback()
是否提交,是否回滚
Query 查询
list() 查询一个结果集合。
uniqueResult() 查询一个唯一的结果,如果没有结果,则返回null,如果结果有多个,就抛异常。
...
beginTransaction() --> Transaction
getTransaction() --> Transaction 获取当前Session中关联的事务对象
其他的方法
...
Transaction 事务
commit()
rollback()
是否提交,是否回滚
Query 查询
list() 查询一个结果集合。
uniqueResult() 查询一个唯一的结果,如果没有结果,则返回null,如果结果有多个,就抛异常。
...
-------------------------------------------------------------------
Hibernate主配置文件
(1)、配置的key前面的hibernate.前缀 可以有,也可以没有。如hibernate.dialect或dialect都可以。
(2)、按作用可分为三类:
(a)、数据库信息
<property ...>
Hibernate主配置文件
(1)、配置的key前面的hibernate.前缀 可以有,也可以没有。如hibernate.dialect或dialect都可以。
(2)、按作用可分为三类:
(a)、数据库信息
<property ...>
方言、JdbcUrl、驱动、用户名、密码
(b)、导入映射文件:将对象与表连接起来
<mapping ...>
(c)、其他配置
<property ...>
show_sql 显示生成的SQL语句
format_sql 格式化生成的SQL语句
(b)、导入映射文件:将对象与表连接起来
<mapping ...>
(c)、其他配置
<property ...>
show_sql 显示生成的SQL语句
format_sql 格式化生成的SQL语句
hbm2ddl.auto 自动生成表结构
hibernate.hbm2ddl.auto:
hibernate.hbm2ddl.auto:
validate 加载hibernate时,验证创建数据库表结构
create 每次加载hibernate,重新创建( 先删除后创建)数据库表结构
create-drop 加载hibernate时创建,退出是删除表结构
update 加载hibernate自动更新数据库结构( 如果表不存在就创建,不一样就更新,一样就什么都不做)
create 每次加载hibernate,重新创建( 先删除后创建)数据库表结构
create-drop 加载hibernate时创建,退出是删除表结构
update 加载hibernate自动更新数据库结构( 如果表不存在就创建,不一样就更新,一样就什么都不做)
生成表结构的两种方式:
1,hbm2ddl.auto
2,使用SchemaExport工具类
Configuration cfg = new Configuration().configure();
SchemaExport schemaExport = new SchemaExport(cfg);
// 第一个参数script的作用: print the DDL to the console打印到控制台
// 第二个参数export的作用: export the script to the database导入到数据库
schemaExport.create(true, true);
注意:只能建表,不能建库
DDL:数据库模式定义语言,关键字:create
DML:数据操纵语言,关键字:Insert、delete、update
DCL:数据库控制语言 ,关键字:grant、remove
DQL:数据库查询语言,关键字:select
DML:数据操纵语言,关键字:Insert、delete、update
DCL:数据库控制语言 ,关键字:grant、remove
DQL:数据库查询语言,关键字:select
8、映射基础
反射利用无参构造器,无需new
final类不能被继承(影响懒加载),final变量不能改变,final方法不能被重写
持久化对象的要求
(1).提供一个无参的构造器。使Hibernate可以使用Constructor.newInstance() 来实例化持久化类。
(2).提供一个标识属性(identifier property)。通常映射为数据库表的主键字段。如果没有该属性,一些功能将不起作用,如:Session.saveOrUpdate()。
(3).为持久化类的字段声明访问方法(get/set)。Hibernate对JavaBeans风格的属性实行持久化。
(4).使用非final类(影响懒加载)。在运行时生成代理是Hibernate的一个重要的功能。如果持久化类没有实现任何接口,Hibnernate 使用 CGLIB 生成代理。如果使用的是 final 类,则无法生成CGLIB代理。
(5).重写eqauls()和hashCode()方法。如果需要把持久化类的实例放到Set中(当需要进行关联映射时),则应该重写这两个方法。
(2).提供一个标识属性(identifier property)。通常映射为数据库表的主键字段。如果没有该属性,一些功能将不起作用,如:Session.saveOrUpdate()。
(3).为持久化类的字段声明访问方法(get/set)。Hibernate对JavaBeans风格的属性实行持久化。
(4).使用非final类(影响懒加载)。在运行时生成代理是Hibernate的一个重要的功能。如果持久化类没有实现任何接口,Hibnernate 使用 CGLIB 生成代理。如果使用的是 final 类,则无法生成CGLIB代理。
(5).重写eqauls()和hashCode()方法。如果需要把持久化类的实例放到Set中(当需要进行关联映射时),则应该重写这两个方法。
OID
为了在系统中能够找到所需对象,需要为每一个对象分配一个唯一的标识号。在关系数据库中称之为主键,而在对象术语中,则叫做对象标识(Object identifier-OID)。映射文件
映射文件的后缀为“.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 package="cn.itcast.c_hbm_property">
<!-- name属性:哪个类,不写包名就要写全名
table属性:对应哪个表,如果不写,默认的表名就是类的简单名称
-->
<class name="User" table="t_user">
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<!-- 普通的属性(数据库中的基本类型,如字符串、日期、数字等)
name属性:对象中的属性名,必须要有。
type属性:类型,如果不写,Hibernate会自动检测。
可以写Java中类的全名。
或是写hibernate类型。
column属性:对应表中的列名,如果没有,默认为属性名。
length属性:长度,不是所有的类型都有长度属性,比如varchar有,如果不写默认255,但int没有
not-null属性:非空约束,默认为false
-->
<!--
<property name="name"/>
-->
<property name="name" type="string" column="name" length="20" not-null="true"/>
<property name="age" type="int" column="age_"/>
<property name="birthday" type="date" column="birthday_"/>
<!-- 当列表与关键字冲突时,可以通过column属性指定一个其他的列名。
或是使用反引号包围起来。
指定使用text类型时,最好再指定length,以确定生成的SQL类型是能够存放指定数量的字符的。
<property name="desc">
<column name="desc_" length="5000" sql-type="text"/>
</property>
-->
<property name="desc" type="text" length="5000" column="`desc`" ></property>
<!-- 头像,二进制类型,最好指定长度 -->
<property name="photo" type="binary" length="102400"></property>
</class>
</hibernate-mapping>
测试APP:
public class App {
private static SessionFactory sessionFactory;
static {
sessionFactory = new Configuration()//
.configure()// 读取配置文件
.addClass(User.class)//
.buildSessionFactory();
}
@Test
public void testSave() throws Exception {
// 读取图片文件
InputStream in = new FileInputStream( "c:/test.png");
byte[] photo = new byte[in.available()];
in.read(photo);
in.close();
// 创建对象实例
User user = new User();
user.setName("张三");
user.setAge(20);
user.setBirthday(new Date());
user.setDesc("一大段的说明,此处省略5000字……");
user.setPhoto(photo);
// 保存
Session session = sessionFactory.openSession(); // 打开一个新的Session
Transaction tx = session.beginTransaction(); // 开始事务
session.save(user);
tx.commit(); // 提交事务
session.close(); // 关闭Session,释放资源
}
@Test
public void testGet() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = (User) session.get(User.class, 4); // 获取
System.out.println(user.getId());
System.out.println(user.getName());
System.out.println(user.getDesc());
System.out.println(user.getPhoto());
OutputStream out = new FileOutputStream("c:/copy.png");
out.write(user.getPhoto());
out.close();
tx.commit();
session.close();
}
}
Date date = new Date();当前时间
映射类型:
主键:
主键:<id>
如果是数字,建议使用 包装类型。Integer null的属性比较好
如果是数字,建议使用 包装类型。Integer null的属性比较好
普通类型:<property>
identity
sequence
hilo
native
assigned
uuid
foreign
...
<?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 package="cn.itcast.d_hbm_id">
<class name="User" table="t_user">
<!-- id元素用于映射主键。
子元素generator是用于指定主键生成策略的。
-->
<id name="id">
<!-- identity:使用数据库的自动增长策略,不是所有数据库都支持,比如oracle就不支持
<generator class="identity"/>
-->
<!-- sequence:在 DB2,PostgreSQL,Oracle,SAP DB,McKoi 中使用序列(sequence)
在使用Oracle数据库时可以使用这一个
<generator class="sequence"/>
-->
<!-- hilo,使用高低位算法生成主键值。
只需要一张额外表,所有的数据都支持。
<generator class="hilo">
<param name="table">hi_value</param>
<param name="column">next_value</param>
<param name="max_lo">100</param>
</generator>
-->
<!-- 根据底层数据库的能力选择 identity、sequence 或者 hilo中的一个。
<generator class="native"></generator>
-->
<!-- increment:由Hibernate维护的自动增长。
先查询当前最大的id值,再加1使用
不推荐使用,因为在多线程下会问题。
<generator class="increment"></generator>
-->
<!-- assigned:手工指定主键值
<generator class="assigned"></generator>
-->
<!-- uuid:由Hibernate自动生成UUID并指定为主键值。 -->
<generator class="uuid"></generator>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
identity
sequence
hilo
native
assigned
uuid
foreign
...
9、回顾总结
Hibernate3.6
持久层的框架
添加环境:
1,jar包
2,配置文件
hibernate.cfg.xml
xxx.hbm.xml
使用Hibernate实现CRUD操作
// --- 准备
Configuration cfg = new Configuration().configure(); // hibernate.cfg.xml
SessionFactory sessionFactory = cfg.buildSessionFactory(); // 只需要一个
// --- 模板代码
Session session = sessionFactory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
// 操作
tx.commit();
}catch(Exception e){
tx.rollback();
throw e;
}finally{
session.close();
}
// --- 操作
Session中的方法:
save(Object) --> insert into ..
update(Object) --> update ..
saveOrUpdate(Object)
delete(Object) --> delete ..
get(Class, id) --> select ...
createQuery(hql) --> select ..
主配置文件
1,数据库信息
方言、URL、驱动、用户名、密码
2,导入映射文件
3,其他配置
show_sql = true
hbm2ddl.auto = update
映射配置:
映射基础
类 -- 表
属性 -- 列
映射普通属性
name, type, column, length, not-null, ...
映射主键
主键生成略:native, uuid
持久层的框架
添加环境:
1,jar包
2,配置文件
hibernate.cfg.xml
xxx.hbm.xml
使用Hibernate实现CRUD操作
// --- 准备
Configuration cfg = new Configuration().configure(); // hibernate.cfg.xml
SessionFactory sessionFactory = cfg.buildSessionFactory(); // 只需要一个
// --- 模板代码
Session session = sessionFactory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
// 操作
tx.commit();
}catch(Exception e){
tx.rollback();
throw e;
}finally{
session.close();
}
// --- 操作
Session中的方法:
save(Object) --> insert into ..
update(Object) --> update ..
saveOrUpdate(Object)
delete(Object) --> delete ..
get(Class, id) --> select ...
createQuery(hql) --> select ..
主配置文件
1,数据库信息
方言、URL、驱动、用户名、密码
2,导入映射文件
3,其他配置
show_sql = true
hbm2ddl.auto = update
映射配置:
映射基础
类 -- 表
属性 -- 列
映射普通属性
name, type, column, length, not-null, ...
映射主键
主键生成略:native, uuid