持久层的事务回滚
public static void main(String[] args) {
Connection con = null;
PreparedStatement ps = null;
try {
// 设置自动提交,默认为真,一旦更新数据库,数据就写入数据库
// 如果设置为false,表示手动提交
con.setAutoCommit(false);
ps.executeUpdate();
// 设置为手动提交后必须调用con.commit();方法才能更新数据库
// 提交事物
con.commit();
} catch (SQLException e) {
try {
// 表示回滚食物,必须要设置为手动提交才能
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
企业级应用需要解决并发,交互,事务,集群,安全,分布式,WEB的一系列问题。
什么是EJB
由EJB(企业级Javabean)服务器主要提供生命周期管理、代码产生、持续性管理、安全、事务管理、锁和并发行管理等服务器。
EJB提供会话bean。消息驱动bean,和实体bean,进行企业级应用的服务器,这些服务器由EJB容器支持,由EJB容器管理EJB组件。
JavaEE是一套设计、开发、汇编和部署企业应用程序的规范。
JavaEE提供了企业级应用程序的开发平台,提供了多层结构、分布式、基于组件、松耦合、安全可靠、独立于平台且反应迅速的应用程序。
J2EE包含的组件技术:
JSP: J2EE的web层核心技术
servlet:J2EE的web层核心技术
JDBC:数据库访问技术
XML:跨平台可扩展标记语言
EJB:j2EE业务层核心技术
JNDI:java命名和目录接口
JMS:java消息服务器
JTA和JTS:JAVA事务管理
JavaMail:邮件收发
RMI:远程方法调用
IDL:接口定义语言,将java和CORBA集成的一种技术
重量级框架:启动、测试、运行、都不能离开容器单独进行。依赖性比较强。
轻量级框架:SUN提出容器提供服务器,轻量级框架提供同样的服务器,用来支持POJP。通过代理方式实现服务的附加。用轻量级框架,持久层和业务层可以单独测试。
SSH:
struts:撑杆
hibernate:冬眠
spring:春天
spring:
表现层-----------------------》业务层-----------------------》持久层------------------------》DB
struts1 hibernate
struts2 mybatis(ibatis)
webwork jdo
springMVC EJB实体Bean
Hibernate
什么是O/R Mapping
对象-关系映射是一门非常实用的工程技术,他实现了java应用中的对象到关系数据库中的表的自动的(和透明的)持久化,使用元数据(meta data)描述对象与数据库间的映射
O/R Mapping的优点:提高生产率、可维护性、更好性能。
Hibernate特点
hibernate 是一种开放源代码的对象/关系映射持久层框架
事务处理,生命周期不依赖于J2EE容器
解决数据库的方言问题
hibernate只需要操作对象就可以完成数据库的CRUD操作,使用hibernate更面向对象。
轻量级、无侵入性、移植性很好。
hibernate应用范围:
不适用范围:
批量对对象进行操作时
使用数据特定映射
表间关系很复杂时,会造成性能问题
<hibernate-configuration>
<session-factory>
<!-- 设置驱动 -->
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<!-- 设置URL -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/classtrain2?characterEncoding=utf-8</property>
<!-- 设置数据登录用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 设置数据登录密码 -->
<property name="hibernate.connection.password">111111</property>
<!-- 配置方言,hibernate利用方言产生该数据库的SQL语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 执行操作时,是否显示SQL语句 -->
<property name="show_sql">true</property>
<!-- 关联O/R Mapping (ORM)映射文件 -->
<mapping resource="orm/MessageBean.hbm.xml"/>
</session-factory>
</hibernate-configuration>
<hibernate-mapping>
<!-- name为类的全路径,table为表名 -->
<class name="com.lovo.bean.MessageBean"table="t_message">
<!-- 定义主键,name表示那个属性对应主键列
如果属性名和列名一致,column也可以不写,不一致必须写
-->
<id name="id"column="m_id">
<!-- 定义主键生产策略,native表示利用数据库的主键自动增长列来生成主键 -->
<generator class="native"></generator>
</id>
<!-- 定义普通属性,如果属性名和列名一致column可以不写 -->
<property name="name"column="m_name"></property>
<property name="tel"column="m_tel"></property>
</class>
</hibernate-mapping>
主键生产策略;
increment:自动增长,其主键由hibernate控制,数据库中相应的字段没有设置自动增长,不能用于集群
identity: 自动增长,对DB2 MYSQL SQLSERVER 数据库中相应的字段设置自动增长
sequence: 对oracle数据库中相应的字段设置自动增长
UUID:采用UUID算法生成字符串唯一标识符,UUID生成策略相对来说速度较快,不需要使用数据库相关的维护表的操作,但查找相对较慢
Native:根据数据库底层的描述,决定采用identity,sequence中的一个
assigned: 手动非陪主键,当generator 没有设置时,采用这种方式
select:使用触发器分配主键
foreign:使用另外一个相关联的对象的标识符,通常和<ont-to-one>联合起来使用
oracle序列添加主键生成策略
<id name=”custld”>
<generatorclass=”sequence”>
S_CUST_ID为序列名称
<param name=”sequence”>S_CUST_ID</param>
</generator>
</id>
Transient(瞬时状态)
当生成PO对象时,产生,数据库中没有相应的记录,没有session对其进行管理
persistent(持久状态)
当session对象调用save 或update 方法时,数据库中有与之相对应的记录,有session对象对之进行管理,当PO对象的值发生改变时,session对象让数据库记录与之同步
Detacher(游离状态)
当session事务提交时,数据库中有与之相对应的记录,从session一级缓存中清除,session对其不再进行管理
hibernate中get和load区别
1、 session.get()方法为立即加载,调用get方法时,会马上执行sql 将结果查询出来。
session.load()方法为延迟加载(懒加载),调用load方法时,不会马上查询结果,而是当查询出来的对象在使用时,才发出SQL语句查询结果
2、 当查询的主键不存在时,gei方法返回null,load方法会抛出“对象未找到异常”。
对延迟加载而言,一旦查询的对象不使用,不会真正的查询数据库。这时,如果session关闭,在使用查询的对象,那么会抛出懒加载异常:org.hibernate.LazyInitializationException
Hibernate 映射关系:
一对一有两种方式:
主键关联:从表的主键,同时又是主表的外键。从表没有单独的外键。
外键关联:从表中存在外键列,关联主表的主键列,但是外键列是不重复。
配置文件:主表:
<hibernate-mapping>
<class name="com.lovo.bean.ManBean"table="t_man">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"column="m_name"></property>
<!-- name为属性名,class为该属性的类型,cascade表示当对主表对象操作时,从表对象是否做级联操作:级联操作指当当前对象执行某些操作的情况下,其关联的对象也执行cascade设置的同样操作 -->
<one-to-one name="code"class="com.lovo.bean.CodeBean" cascade="all"></one-to-one>
</class>
</hibernate-mapping>
从表配置文件:
<hibernate-mapping>
<class name="com.lovo.bean.CodeBean"table="t_code">
<id name="id">
<!-- foreign表示该主键同时也是外键 -->
<generator class="foreign">
<!-- man为属性名,表示该主键由ManBean对象的主键生成 -->
<param name="property">man</param>
</generator>
</id>
<property name="codeName"column="c_code"></property>
<!-- constrained表示该主键存在外键约束。lazy="false",不做懒加载,查询该对象时,关联对象立即查询 -->
<one-to-one name="man"class="com.lovo.bean.ManBean" constrained="true" lazy="false"></one-to-one>
</class>
</hibernate-mapping>
以上为主键关联的配置文档
下面是1对1的外键配置:
<!-- 外键关联 -->
<hibernate-mapping>
<class name="com.lovo.bean.CodeBean2"table="t_code1">
<id name="id">
<generator class="native"></generator>
</id>
<property name="codeName"column="c_code"></property>
<!-- 唯一外键关联,是多对一的特列。unique=true表示外键列是唯一的,column为外键列列名 -->
<many-to-one name="man"class="com.lovo.bean.ManBean" unique="true" column="manId"></many-to-one>
</class>
</hibernate-mapping>
Hibernate一对多 配置:
主表配置文件(主表的实体bean中需要放置一个集合 set list,一般用set防止重复):
<hibernate-mapping>
<class name="com.lovo.bean.UserBean"table="t_user">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"column="u_name"></property>
<property name="birth"column="u_birth"></property>
<!-- 加上inverse=true 执行效率更高 -->
<set name="roomSet"inverse="true">
<!-- 配置从表的外键 -->
<key column="r_userId"></key>
<!-- 集合中存放元素的类型 -->
<one-to-many class="com.lovo.bean.RoomBean"/>
</set>
</class>
</hibernate-mapping>
从表配置文件:
<hibernate-mapping>
<class name="com.lovo.bean.CodeBean2"table="t_room">
<id name="id">
<generator class="native"></generator>
</id>
<property name="address"column="r_address"></property>
<property name="price"column="r_price"></property>
<many-to-one name="user"class="com.lovo.bean.ManBean" column="r_userId"></many-to-one>
</class>
</hibernate-mapping>
cascade和inverse的区别:
cascade表示级联操作,当主表记录做操作时,从表记录做相应的操作,维护的是记录。
inverse表示控制反转。当该属性设置为真时,表示由关联对象维护外键关系,当前对象不做外键维护,所以维护的是外键。一般来说,inverse设置在一方,外键由从表维护。
//一般不要在配置文件中加上lazy=false,而是在需要的地方使用一次
hibernate 多对多映射:
其他的表相同配置,在多对多中,实体bean中可以单向有集合
toSring()方法中要去掉关于集合的属性
<hibernate-mapping>
<class name="com.lovo.bean.RoleBean"table="t_role">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"column="r_name"></property>
<!-- 多对多必须写table,table是中间表 -->
<set name="gradeSet"table="t_role_grade">
<!-- 当前对象对应中间表的外键列 -->
<key column="roleId"></key>
<!-- class为集合中存放元素的类型,而column为集合中存放元素对应的中间表的外键列 -->
<many-to-many class="com.lovo.bean.GradeBean"column="gradeId"></many-to-many>
</set>
</class>
</hibernate-mapping>
多对多的联表查询:
@Override
publicList<RoleBean> findByGradeName(String gradeName) {
Session session = this.getSession();
List<RoleBean> list = null;
Query q = session.createQuery("select r from RoleBean r joinr.gradeSet s where s.name = ?");
q.setParameter(0, gradeName);
list = q.getResultList();
session.close();
return list;
}