SSH框架之Hibernate第四篇

时间:2021-01-13 00:28:48
Hibernate中有两套实现数据库数据操作的方式 :
hibernate前3天讲解的都是 : hibernate自己的操作方式(纯XML配置文件的方式)
另一种方式是基于JPA的操作方式(通过注解的方式替代之前的部分XML) JPA相关概念:
1.1JPA概述 : (java的持久化规范(规范即接口))
全称是 : Java Persistence API. 是SUN公司推出的一套基于ORM的规范.hibernate框架中提供了JPA的实现.
JAP通过JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.
1.2JPA要明确的
a. JPA是一套ORM规范(算是一个接口),hibernate实现了JPA规范(算是一个实现类).
b. hibernate中有自己的独立ORM操作数据库方式,也有JPA规范实现的操作数据库方式.
c. 在数据库增删改查操作中,我们hibernate和JPA的操作都要会.
JPA和hibernate的关系?
JPA是接口,hibernate是实现.
所有的ORM框架都可以去实现JPA接口,通过JPA提供的一些接口来操作数据库的数据. JPA的使用 :
JPA是通过注解的方式来描述,对象和表的映射关系.
之前的对象和表的映射关系配置是通过XML,今天要替换成注解的方式. 注释 : 给程序员看的.
注解 : 给程序来使用的.
为什么要出现注解?
一开始就是为了替代所有的XML配置文件. 工作中两种方式结合使用 :
配置文件 + 注解
如果是需要常常改动的程序 : 用配置文件.
如果是定义好了不需要更改的程序 : 注解. 2.1 2 JPA的环境搭建
1 hibernate的环境(16个包)
2 JPA的环境(1个包) 2.2.2 创建配置文件
要求:在src下面的META-INF文件夹下面创建一个名称为persistence.xml的文件。
配置文件的内容:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<!--Name属性用于定义持久化单元的名字 (name必选,空值也合法);
transaction-type 指定事务类型(可选)
取值:
JTA:默认值
RESOURCE_LOCAL
-->
<persistence-unit name="myPersistUnit" transaction-type="RESOURCE_LOCAL"> <properties>
<!-- 生成DDL的策略 -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<!-- 数据库的连接信息 -->
<property name="hibernate.connection.driver_class"
value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url"
value="jdbc:mysql://localhost:3306/hibernate_jpa"/>
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="1234" />
<!-- 指定方言 -->
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQL5Dialect" />
<!-- 是否显示SQL语句 -->
<property name="hibernate.show_sql" value="false" />
<!-- 是否格式化SQL语句 -->
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
</persistence> 2.2.3 编写工具类,用于获取JPA的操作数据库对象
public class HibernateUtils {
//JPA的实体管理器工厂 : 相当于Hibernate的SessionFactory
private static EntityManagerFactory em;
//使用静态代码块赋值
static {
//加载一次配置文件
//注意 : 该方法参数必须和persistence.xml中persistence-unit标签name属性取值一致
em = Persistence.createEntityManagerFactory("aaa");
}
/*
* 使用管理器工厂生产一个管理器对象
*/
//相当于获取连接
public static EntityManager getEntityManager() {
return em.createEntityManager();
}
} jpa 的批量查询方式 :
类似咋们之前学习的query方式查询 :
1 : qr.getResultList() ; 类似之前的qr.list();
2 : hibernate对于占位符? 以前是从0开始,jpa是从1开始.
3 : 聚合 qr.getSingleResult(); 类似之前的uniqueResult(); 2.2.4 编写实体类,并使用注解配置
//级联保存 (保存客户的同时把关联的联系人给保存了)
//jpa的注解里面 @OneToMany 添加属性cascade = CascadeType.PERSIST_STORE
//根据一的一方保存多的一方的数据.
// 级联保存 (保存联系人的同时把关联的客户给保存了)
// jpa的注解里面 @ManyToOne 添加属性cascade=CascadeType.PERSIST
//jpa的一对多没有普通删除
// 级联删除
// jpa的注解里面 @OneToMany 添加属性cascade=CascadeType.REMOVE (All) /**
* 客户的实体类
*/
@Entity
@Table(name="cst_customer")
public class Customer implements Serializable { @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="cust_id")
private Long custId; @Column(name="cust_name")
private String custName; @Column(name="cust_source")
private String custSource; @Column(name="cust_industry")
private String custIndustry; @Column(name="cust_level")
private String custLevel; @Column(name="cust_address")
private String custAddress; @Column(name="cust_phone")
private String custPhone; public Long getCustId() {
return custId;
}
public void setCustId(Long custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
@Override
public String toString() {
return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource
+ ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress
+ ", custPhone=" + custPhone + "]";
}
} 2.3 常用注解说明
@Entity
作用 : 指定当前类是实体类.写上此注解用于在创建SessionFactory/EntityManager时,加载映射配置. @Table
作用 : 指定实体类和表之间的对应关系.
属性 :
name : 指定数据库表的名称. @Id
作用 : 指定当前字段是主键. @GeneratedValue
作用 : 指定主键的生成方式.JPA的主键生成方式
属性 :
strategy : 指定主键生成策略.JPA支持四种生成策略, @Column :
作用 : 指定实体类属性和数据库表之间的对应关系.
属性 :
name : 指定数据库表的列名称.
unique : 是否唯一 .
nullable : 是否可以为空
inserttable : 是否可以插入
updateable : 是否可以更新
columnDefinition : 定义建表时创建此列的DDL.
secondaryTable : 从表名.如果此列不建在主表上(默认键在主表),该属性定义该列所在从表的名字.
2.4主键生成策略
通过annotation(注解)来映射hibernate实体的,基于annotation的hibernate主键标识为@Id,
其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法。
JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO。具体说明如下:
2.4.1IDENTITY:主键由数据库自动生成(主要是自动增长型)
用法:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long custId;
2.4.2SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
用法:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="payablemoney_seq")
@SequenceGenerator(name="payablemoney_seq", sequenceName="seq_payment")
说明:
@SequenceGenerator源码中的定义
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface SequenceGenerator {
String name();
String sequenceName() default "";
int initialValue() default 0;
int allocationSize() default 50;
}
name:表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中。
sequenceName:属性表示生成策略用到的数据库序列名称。
initialValue:表示主键初识值,默认为0。
allocationSize:表示每次主键值增加的大小,例如设置1,则表示每次插入新记录后自动加1,默认为50。 2.4.3AUTO:主键由程序控制。
用法:
@Id
@GeneratedValue(strategy = GenerationType.AUTO) 2.5JPA的CRUD操作
2.5.1保存
/**
* 保存一个实体
*/
@Test
public void testAdd(){
//定义对象
Customer c = new Customer();
c.setCustName("传智学院");
c.setCustLevel("VIP客户");
c.setCustSource("网络");
c.setCustIndustry("IT教育");
c.setCustAddress("昌平区北七家镇");
c.setCustPhone("010-84389340");
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
em.persist(c);
//提交事务
tx.commit();
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
} 2.5.2修改
/**
* 修改
*/
@Test
public void testUpdate(){
//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer c1 = em.find(Customer.class, 1L);
c1.setCustName("江苏传智学院");
//提交事务
tx.commit(); //使用JPA中快照机制实现更新
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
} merge方法实现修改
@Test
public void testMerge(){
//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer c1 = em.find(Customer.class, 6L);
c1.setCustName("江苏传智学院");
em.clear();//把c1对象从缓存中清除出去
em.merge(c1);
//提交事务
tx.commit();
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
}
2.5.3删除
/**
* 删除
*/
@Test
public void testRemove(){
//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer c1 = em.find(Customer.class, 6L);
em.remove(c1);
//提交事务
tx.commit();
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
}
2.5.4查询一个
/**
* 查询一个:
* 使用立即加载的策略
*/
@Test
public void testGetOne(){
//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer c1 = em.find(Customer.class, 1L);
//提交事务
tx.commit();
System.out.println(c1); //输出查询对象
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
} 查询实体的缓存问题
@Test
public void testGetOne(){
//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer c1 = em.find(Customer.class, 1L);
Customer c2 = em.find(Customer.class, 1L);
System.out.println(c1 == c2);//输出结果是true,EntityManager也有缓存
//提交事务
tx.commit();
System.out.println(c1);
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
} 延迟加载策略的方法:
/**
* 查询一个:
* 使用延迟加载策略
*/
@Test
public void testLoadOne(){
//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Customer c1 = em.getReference(Customer.class, 1L);
//提交事务
tx.commit();
System.out.println(c1);
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
}
2.5.5查询所有
/**
* 查询所有
* 涉及的对象:
* Query(注意:不是Hibernate的Query)
* 如何获取:
* 使用EntityManager的createQuery(String JPQL)方法;
* 参数的含义
* JPQL:jpa query language
* JPQL的写法:
* 表名使用实体类名称替代
* 列名使用实体类属性名称替代
* 不能使用*号。查询所有,需要在from关键字后面的类名上加别名
* 例如: select c from Customer c
* 查询条件可以使用?作为参数占位符。
* 给占位符赋值时,占位符索引位置从1开始
* 获取结果集的方法
* getResultList():查询结果是一个List集合
* getSingleResult():查询结果是一个对象
*/
@Test
public void testFindAll(){
//定义对象
EntityManager em=null;
EntityTransaction tx=null;
try{
//获取实体管理对象
em=JPAUtil.getEntityManager();
//获取事务对象
tx=em.getTransaction();
//开启事务
tx.begin();
//执行操作
Query query = em.createQuery("select c from Customer c where custName like ? ");
query.setParameter(1,"%学院%");
List list = query.getResultList();
//提交事务
tx.commit(); for(Object o : list){
System.out.println(o);
}
}catch(Exception e){
//回滚事务
tx.rollback();
e.printStackTrace();
}finally{
//释放资源
em.close();
}
} 3.1一对多关系映射
3.1.1常用注解
3.1.1.1@OneToMany:
作用:
建立一对多的关系映射
属性:
targetEntityClass:指定多的方的类的字节码
mappedBy:指定从表实体类中引用主表对象的名称。
cascade:指定要使用的级联操作
fetch:指定是否采用延迟加载
orphanRemoval:是否使用孤儿删除
3.1.1.2@ManyToOne
作用:
建立多对一的关系
属性:
targetEntityClass:指定一的一方实体类字节码
cascade:指定要使用的级联操作
fetch:指定是否采用延迟加载
optional:关联是否可选。如果设置为false,则必须始终存在非空关系。
3.1.1.3@JoinColumn
作用:
用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。
3.1.2配置代码
3.1.2.1客户配置
/**
* 客户的实体类
* 明确使用的注解都是JPA规范的
* 所以导包都要导入javax.persistence包下的
*
*/
@Entity//表示当前类是一个实体类
@Table(name="cst_customer")//建立当前实体类和表之间的对应关系
public class Customer implements Serializable { @Id//表明当前私有属性是主键
@GeneratedValue(strategy=GenerationType.IDENTITY)//指定主键的生成策略
@Column(name="cust_id")//指定和数据库表中的cust_id列对应
private Long custId;
@Column(name="cust_name")//指定和数据库表中的cust_name列对应
private String custName;
@Column(name="cust_source")//指定和数据库表中的cust_source列对应
private String custSource;
@Column(name="cust_industry")//指定和数据库表中的cust_industry列对应
private String custIndustry;
@Column(name="cust_level")//指定和数据库表中的cust_level列对应
private String custLevel;
@Column(name="cust_address")//指定和数据库表中的cust_address列对应
private String custAddress;
@Column(name="cust_phone")//指定和数据库表中的cust_phone列对应
private String custPhone; @OneToMany(targetEntity=LinkMan.class,mappedBy="customer")
private Set<LinkMan> linkmans = new HashSet<LinkMan>(0); public Long getCustId() {
return custId;
}
public void setCustId(Long custId) {
this.custId = custId;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustSource() {
return custSource;
}
public void setCustSource(String custSource) {
this.custSource = custSource;
}
public String getCustIndustry() {
return custIndustry;
}
public void setCustIndustry(String custIndustry) {
this.custIndustry = custIndustry;
}
public String getCustLevel() {
return custLevel;
}
public void setCustLevel(String custLevel) {
this.custLevel = custLevel;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
public Set<LinkMan> getLinkmans() {
return linkmans;
}
public void setLinkmans(Set<LinkMan> linkmans) {
this.linkmans = linkmans;
}
@Override
public String toString() {
return "Customer [custId=" + custId + ", custName=" + custName + ", custSource=" + custSource
+ ", custIndustry=" + custIndustry + ", custLevel=" + custLevel + ", custAddress=" + custAddress
+ ", custPhone=" + custPhone + "]";
}
}
3.1.2.2联系人配置
/**
* 联系人的实体类(数据模型)
*/
@Entity
@Table(name="cst_linkman")
public class LinkMan implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="lkm_id")
private Long lkmId;
@Column(name="lkm_name")
private String lkmName;
@Column(name="lkm_gender")
private String lkmGender;
@Column(name="lkm_phone")
private String lkmPhone;
@Column(name="lkm_mobile")
private String lkmMobile;
@Column(name="lkm_email")
private String lkmEmail;
@Column(name="lkm_position")
private String lkmPosition;
@Column(name="lkm_memo")
private String lkmMemo; //多对一关系映射:多个联系人对应客户
@ManyToOne(targetEntity=Customer.class)
@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
private Customer customer;//用它的主键,对应联系人表中的外键 public Long getLkmId() {
return lkmId;
}
public void setLkmId(Long lkmId) {
this.lkmId = lkmId;
}
public String getLkmName() {
return lkmName;
}
public void setLkmName(String lkmName) {
this.lkmName = lkmName;
}
public String getLkmGender() {
return lkmGender;
}
public void setLkmGender(String lkmGender) {
this.lkmGender = lkmGender;
}
public String getLkmPhone() {
return lkmPhone;
}
public void setLkmPhone(String lkmPhone) {
this.lkmPhone = lkmPhone;
}
public String getLkmMobile() {
return lkmMobile;
}
public void setLkmMobile(String lkmMobile) {
this.lkmMobile = lkmMobile;
}
public String getLkmEmail() {
return lkmEmail;
}
public void setLkmEmail(String lkmEmail) {
this.lkmEmail = lkmEmail;
}
public String getLkmPosition() {
return lkmPosition;
}
public void setLkmPosition(String lkmPosition) {
this.lkmPosition = lkmPosition;
}
public String getLkmMemo() {
return lkmMemo;
}
public void setLkmMemo(String lkmMemo) {
this.lkmMemo = lkmMemo;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
@Override
public String toString() {
return "LinkMan [lkmId=" + lkmId + ", lkmName=" + lkmName + ", lkmGender=" + lkmGender + ", lkmPhone="
+ lkmPhone + ", lkmMobile=" + lkmMobile + ", lkmEmail=" + lkmEmail + ", lkmPosition=" + lkmPosition
+ ", lkmMemo=" + lkmMemo + "]";
}
}
3.2多对多关系映射
3.2.1常用注解:
3.2.1.1@ManyToMany
作用:
用于映射多对多关系
属性:
cascade:配置级联操作。
fetch:配置是否采用延迟加载。
targetEntity:配置目标的实体类。映射多对多的时候不用写。
3.2.1.2@JoinTable
作用:
针对中间表的配置
属性:
name:配置中间表的名称
joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段
inverseJoinColumn:中间表的外键字段关联对方表的主键字段 3.2.1.3@JoinColumn
作用:
用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。 3.2.2配置代码
3.2.2.1用户配置
/**
* 用户的数据模型
*/
@Entity
@Table(name="sys_user")
public class SysUser implements Serializable { @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="user_id")
private Long userId;
@Column(name="user_code")
private String userCode;
@Column(name="user_name")
private String userName;
@Column(name="user_password")
private String userPassword;
@Column(name="user_state")
private String userState; //多对多关系映射
@ManyToMany(mappedBy="users")
private Set<SysRole> roles = new HashSet<SysRole>(0); public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public String getUserState() {
return userState;
}
public void setUserState(String userState) {
this.userState = userState;
}
public Set<SysRole> getRoles() {
return roles;
}
public void setRoles(Set<SysRole> roles) {
this.roles = roles;
}
@Override
public String toString() {
return "SysUser [userId=" + userId + ", userCode=" + userCode + ", userName=" + userName + ", userPassword="
+ userPassword + ", userState=" + userState + "]";
}
} 3.2.2.2角色配置
/**
* 角色的数据模型
*/
@Entity
@Table(name="sys_role")
public class SysRole implements Serializable { @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="role_id")
private Long roleId;
@Column(name="role_name")
private String roleName;
@Column(name="role_memo")
private String roleMemo; //多对多关系映射
@ManyToMany
@JoinTable(name="user_role_rel",//中间表的名称
//中间表user_role_rel字段关联sys_role表的主键字段role_id
joinColumns={@JoinColumn(name="role_id",referencedColumnName="role_id")},
//中间表user_role_rel的字段关联sys_user表的主键user_id
inverseJoinColumns={@JoinColumn(name="user_id",referencedColumnName="user_id")}
)
private Set<SysUser> users = new HashSet<SysUser>(0); public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleMemo() {
return roleMemo;
}
public void setRoleMemo(String roleMemo) {
this.roleMemo = roleMemo;
}
public Set<SysUser> getUsers() {
return users;
}
public void setUsers(Set<SysUser> users) {
this.users = users;
}
@Override
public String toString() {
return "SysRole [roleId=" + roleId + ", roleName=" + roleName + ", roleMemo=" + roleMemo + "]";
} } 第4章JPA的多表操作
4.1一对多关系的增删改操作
4.1.1保存操作
保存原则:先保存主表,再保存从表。
/**
* 保存操作
* 需求:
* 保存一个客户和一个联系人
* 要求:
* 创建一个客户对象和一个联系人对象
* 建立客户和联系人之间关联关系(双向一对多的关联关系)
* 先保存客户,再保存联系人
*/
@Test
public void test1(){
//创建客户和联系人对象
Customer c = new Customer();//瞬时态
c.setCustName("TBD云集中心");
c.setCustLevel("VIP客户");
c.setCustSource("网络");
c.setCustIndustry("商业办公");
c.setCustAddress("昌平区北七家镇");
c.setCustPhone("010-84389340"); LinkMan l = new LinkMan();//瞬时态
l.setLkmName("TBD联系人");
l.setLkmGender("male");
l.setLkmMobile("13811111111");
l.setLkmPhone("010-34785348");
l.setLkmEmail("98354834@qq.com");
l.setLkmPosition("老师");
l.setLkmMemo("还行吧"); //建立他们的双向一对多关联关系
l.setCustomer(c);
c.getLinkmans().add(l);
//获取JPA操作对照
EntityManager em = JPAUtil.getEntityManager();
//获取JPA事务对象
EntityTransaction tx= em.getTransaction();
//开启事务
tx.begin();
//按照要求:先保存客户,再保存联系人(此时符合保存原则:先保存主表,再保存从表)
em.persist(c);
em.persist(l);
tx.commit();
} JPA注解的配置方式:不涉及多一条update语句的问题
4.1.2删除操作
/**
* 删除操作
* 删除从表数据:可以随时任意删除。
* 删除主表数据:
* 有从表数据引用
* 1、不能删除
* 2、如果还想删除,使用级联删除
* 没有从表数据引用:随便删
*
* 在实际开发中,级联删除请慎用!(在一对多的情况下)
*/
@Test
public void test3(){
//获取JPA操作对照
EntityManager em = JPAUtil.getEntityManager();
//获取JPA事务对象
EntityTransaction tx= em.getTransaction();
//开启事务
tx.begin();
//查询id为1的客户
Customer c1 = em.find(Customer.class, 2L);
//删除id为1的客户
em.remove(c1);
tx.commit();
} 级联删除的配置:
@OneToMany(targetEntity=LinkMan.class,mappedBy="customer",cascade=CascadeType.ALL) //用CascadeType.REMOVE也可以
private Set<LinkMan> linkmans = new HashSet<LinkMan>(0);
4.2多对多关系的增删操作
4.2.1保存操作
/**
* 需求:
* 保存用户和角色
* 要求:
* 创建2个用户和3个角色
* 让1号用户具有1号和2号角色(双向的)
* 让2号用户具有2号和3号角色(双向的)
* 保存用户和角色
*/
@Test
public void test1(){
//创建对象
SysUser u1 = new SysUser();
u1.setUserName("用户1");
SysUser u2 = new SysUser();
u2.setUserName("用户2"); SysRole r1 = new SysRole();
r1.setRoleName("角色1");
SysRole r2 = new SysRole();
r2.setRoleName("角色2");
SysRole r3 = new SysRole();
r3.setRoleName("角色3"); //建立关联关系
u1.getRoles().add(r1);
u1.getRoles().add(r2);
r1.getUsers().add(u1);
r2.getUsers().add(u1); u2.getRoles().add(r2);
u2.getRoles().add(r3);
r2.getUsers().add(u2);
r3.getUsers().add(u2); //获取JPA操作对照
EntityManager em = JPAUtil.getEntityManager();
//获取JPA事务对象
EntityTransaction tx= em.getTransaction();
//开启事务
tx.begin();
em.persist(u1);
em.persist(u2);
em.persist(r1);
em.persist(r2);
em.persist(r3);
tx.commit();
} JPA注解的配置方式:不涉及保存失败的问题:
4.2.2删除操作
/**
* 删除操作
* 在多对多的删除时,双向级联删除根本不能配置
* 禁用
* 如果配了的话,如果数据之间有相互引用关系,可能会清空所有数据
*/
@Test
public void test2(){
//获取JPA操作对照
EntityManager em = JPAUtil.getEntityManager();
//获取JPA事务对象
EntityTransaction tx= em.getTransaction();
//开启事务
tx.begin();
SysUser u1 = em.find(SysUser.class,3L);
em.remove(u1);
tx.commit();
} 在多对多映射配置中不能出现双向级联删除的配置,无论注解还是XML配置 5.2JPA和hibernate中操作数据的方法对照
操作 Hibernate中的方法 JPA中的方法 说明
保存操作 save(Object entity) persist(Object entity) 共同点:都是把临时态对象转成了持久态。
区别:
提供者不一样:
save方法是hibernate提供的。
persist方法是JPA规范提供的。
在没有事务的情况下:
save会去数据库中保存,hibernate提供了一个内置的事务来执行。
persist什么都不会做。
更新操作 update (Object entity) merge (Object entity) Hibernate和jpa都可以利用快照机制,不调用任何方法去更新。
Update方法在更新时,如果遇到一级缓存已经包含了一个相同OID的对象会报错。merge则可以执行成功。
删除操作 delete (Object entity) remove (Object entity) 都是删除一个实体
查询一个操作 get (Class clazz,Serializable id)
load(Class clazz,Serializable id) find(Class clazz,Object id)
getReerence(Class clazz,Object id) get和find都是立即加载。load和getReference一样都是延迟加载。
查询所有操作 Query:使用HQL语句查询 Query:使用JPQL查询 查询语句的形式不一样。
查询返回唯一结果操作 uniqueResult() getSingleResult() 查询都是返回一个唯一的结果。 JPA一对多的注解配置:
案例:
// ps: jpa提供的注解都在:javax.persistence包下
@Entity
@Table(name="cst_customer")
public class Customer
{
@Id
@Column(name="cust_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long cust_id; // '客户编号(主键)', @Column(name="cust_name")
private String cust_name; // '客户名称(公司名称)', @Column(name="cust_source")
private String cust_source; // '客户信息来源', @Column(name="cust_industry")
private String cust_industry; // '客户所属行业', @Column(name="cust_level")
private String cust_level; // '客户级别', @Column(name="cust_address")
private String cust_address; // '客户联系地址', @Column(name="cust_phone")
private String cust_phone; // '客户联系电话 // 有多的一方的集合
/*targetEntity:对方的类型
* mappedBy:自己在对方里的属性名称 (mappedBy写在哪方,哪方意味着放弃外键的维护)
*
* */
@OneToMany(targetEntity=LinkMan.class,mappedBy="customer",cascade=CascadeType.REMOVE)
private Set<LinkMan> linkmans=new HashSet(); @Entity
@Table(name="cst_linkman")
public class LinkMan
{
@Id
@Column(name="lkm_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long lkm_id;// '联系人编号(主键)', @Column(name="lkm_name")
private String lkm_name;// '联系人姓名', @Column(name="lkm_gender")
private String lkm_gender;// '联系人性别', @Column(name="lkm_phone")
private String lkm_phone;// '联系人办公电话', @Column(name="lkm_mobile")
private String lkm_mobile;// '联系人手机', @Column(name="lkm_email")
private String lkm_email;// '联系人邮箱', @Column(name="lkm_qq")
private String lkm_qq;// '联系人qq', @Column(name="lkm_position")
private String lkm_position;// '联系人职位', @Column(name="lkm_memo")
private String lkm_memo;// '联系人备注', // 有一的一方的对象 PERSIST
@ManyToOne(targetEntity=Customer.class,cascade=CascadeType.PERSIST)
/*name:代表着外键字段的名称*/
/*referencedColumnName:指向的主键字段的命名称*/
@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")
private Customer customer; 多表对多表的注解配置:
@Entity
@Table(name="sys_user")
public class User
{
@Id
@Column(name="user_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long user_id;// '用户id',
@Column(name="user_code")
private String user_code;// '用户账号',
@Column(name="user_name")
private String user_name;// '用户名称',
@Column(name="user_password")
private String user_password;// '用户密码',
@Column(name="user_state")
private String user_state;// '1:正常,0:暂停', // 有角色的集合
/*targetEntity:对方的类型
*
*
* */
@ManyToMany(targetEntity=Role.class,cascade=CascadeType.ALL)
/*name: 中间表的名称
joinColumns:自己在中间表的一些配置
inverseJoinColumns:对方在中间表的一些配置*/
@JoinTable(name="sys_user_role",
joinColumns={
/*name:自己在中间表的外键字段名称
referencedColumnName:指向自己的主键字段名*/
@JoinColumn(name="user_id",referencedColumnName="user_id")
},
inverseJoinColumns={
/*name:对方在中间表的外键字段名称
referencedColumnName:指向的对方的主键字段名称*/
@JoinColumn(name="role_id",referencedColumnName="role_id")
})
private Set<Role> roles=new HashSet(); @Entity
@Table(name="sys_role")
public class Role
{
@Id
@Column(name="role_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long role_id;// 主键id @Column(name="role_name")
private String role_name;// '角色名称',
@Column(name="role_memo")
private String role_memo;// '备注', // 有用户的集合
/*targetEntity:对方的类型
* mappedBy:自己在对方的属性名
* */
@ManyToMany(targetEntity=User.class,mappedBy="roles")
private Set<User> users=new HashSet(); JPA需要在项目src下新建一个META-INF文件夹在文件夹里面配置以下信息:
例如 :
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<!-- ps:当前根目录下必须得有一个持久化单元(至少要有一个数据库的连接信息配置) -->
<persistence-unit name="aaa">
<!-- 数据库的连接信息 -->
<properties>
<!-- 必选5项 -->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql:///hibernate3"></property>
<property name="hibernate.connection.username" value="root"></property>
<property name="hibernate.connection.password" value="1234"></property>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"></property> <!-- 可选的 -->
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"></property>
<property name="hibernate.show_sql" value="true"></property>
<property name="hibernate.format_sql" value="true"></property>
<property name="hibernate.hbm2ddl.auto" value="update"></property> </properties>
</persistence-unit>
</persistence>
JPA单表操作 :
例如 :
package cn.baidu.demo; public class Demo1
{
@Test //需求:保存一个客户
public void t1()
{
// 加载配置文件--返回一个类似Sessionfactory的对象
EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");
// 类似session
EntityManager em = factory.createEntityManager();
// 获取事务
EntityTransaction tx = em.getTransaction(); // 事务未开启
// 开启事务
tx.begin(); // 保存操作
Customer ct = new Customer();
ct.setCust_name("李冰冰");
em.persist(ct); // 类似save() // 手动提交
tx.commit(); // 释放资源
em.close(); } @Test //查询1
public void t2()
{
EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");
EntityManager em = factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 查询
Customer ct = em.find(Customer.class, 1L); // 立即加载 类似get()
System.out.println(ct);
tx.commit();
em.close();
} @Test //查询2
public void t3()
{
EntityManagerFactory factory = Persistence.createEntityManagerFactory("aaa");
EntityManager em = factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 查询2
Customer ct = em.getReference(Customer.class, 1L); //延迟加载 类似load()
System.out.println(ct);
tx.commit();
em.close();
} @Test //修改
public void t4()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 修改
Customer ct = em.find(Customer.class, 1L);
ct.setCust_name("rose");
em.merge(ct); //类似update tx.commit();
em.close();
} @Test //修改 jpa支持一级缓存? 支持
public void t5()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 修改
Customer ct = em.find(Customer.class, 1L);
ct.setCust_name("rose123"); tx.commit();
em.close();
} @Test //删除
public void t6()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); //删除
Customer ct = em.find(Customer.class, 1L);
em.remove(ct); // 类似之前的delete() tx.commit();
em.close();
} /// jpa的批量查询方式
// 类似咱们之前学习的query方式
// 1 qr.getResultList(); //类似之前的 qr.list()
// 2 hibernate对于占位符?是从0开始 jpa是从1开始
// 3 聚合 qr.getSingleResult(); //类似之前的 qr.uniqueResult(); @Test
public void t7()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 全查
Query qr = em.createQuery("from Customer");
List<Customer> list = qr.getResultList(); //类似之前的 qr.list()
for (Customer customer : list) {
System.out.println(customer);
} tx.commit();
em.close();
} @Test
public void t8()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 条件
Query qr = em.createQuery("from Customer where cust_name like ?");
qr.setParameter(1, "b%"); // 注意:hibernate对于占位符?是从0开始 jpa是从1开始 List<Customer> list = qr.getResultList();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
em.close();
} @Test
public void t9()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 分页
Query qr = em.createQuery("from Customer");
qr.setFirstResult(1);
qr.setMaxResults(3); List<Customer> list = qr.getResultList();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
em.close();
} @Test
public void t10()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 单列
Query qr = em.createQuery("select cust_name from Customer");
List<Object> list = qr.getResultList();
for (Object object : list) {
System.out.println(object);
}
tx.commit();
em.close();
} @Test
public void t11()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 多列
Query qr = em.createQuery("select cust_id,cust_name from Customer");
List<Object[]> list = qr.getResultList();
for (Object[] object : list) {
System.out.println(Arrays.toString(object));
}
tx.commit();
em.close();
} @Test
public void t12()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 投影
Query qr = em.createQuery("select new Customer(cust_id,cust_name) from Customer");
List<Customer> list = qr.getResultList();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
em.close();
} @Test
public void t13()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 排序
Query qr = em.createQuery("from Customer order by cust_id desc");
List<Customer> list = qr.getResultList();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
em.close();
} @Test
public void t14()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); // 聚合
Query qr = em.createQuery("select avg(cust_id) from Customer");
Object obj = qr.getSingleResult();
System.out.println(obj);
tx.commit();
em.close();
}
} JPA一对多表的操作 :
/*
一对多的操作*/
public class Demo2
{
@Test // 保存一的客户3个联系人
public void t1()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Customer ct = new Customer();
ct.setCust_name("马总");
LinkMan l1 = new LinkMan();
l1.setLkm_name("大秘");
LinkMan l2 = new LinkMan();
l2.setLkm_name("中秘");
LinkMan l3 = new LinkMan();
l3.setLkm_name("小秘"); // 双向关联
ct.getLinkmans().add(l1);
ct.getLinkmans().add(l2);
ct.getLinkmans().add(l3);
l1.setCustomer(ct);
l2.setCustomer(ct);
l3.setCustomer(ct); //保存
em.persist(ct);
em.persist(l1);
em.persist(l2);
em.persist(l3);
tx.commit();
em.close();
} @Test // 级联保存 (保存客户的同时把关联的联系人给保存了)
// jpa的注解里面 @OneToMany 添加属性cascade=CascadeType.PERSIST
public void t2() // 根据一的一方保存多的一方的数据(掌握)
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Customer ct = new Customer();
ct.setCust_name("马总");
LinkMan l1 = new LinkMan();
l1.setLkm_name("大秘");
LinkMan l2 = new LinkMan();
l2.setLkm_name("中秘");
LinkMan l3 = new LinkMan();
l3.setLkm_name("小秘"); // 双向关联
ct.getLinkmans().add(l1);
ct.getLinkmans().add(l2);
ct.getLinkmans().add(l3);
l1.setCustomer(ct);
l2.setCustomer(ct);
l3.setCustomer(ct); //保存
em.persist(ct);
/*em.persist(l1);
em.persist(l2);
em.persist(l3);*/
tx.commit();
em.close();
} @Test // 级联保存 (保存联系人的同时把关联的客户给保存了)
// jpa的注解里面 @ManyToOne 添加属性cascade=CascadeType.PERSIST
public void t3() // 根据多的一方保存一的一方的数据(不常用)
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Customer ct = new Customer();
ct.setCust_name("马总");
LinkMan l1 = new LinkMan();
l1.setLkm_name("大秘");
LinkMan l2 = new LinkMan();
l2.setLkm_name("中秘");
LinkMan l3 = new LinkMan();
l3.setLkm_name("小秘"); // 双向关联
ct.getLinkmans().add(l1);
ct.getLinkmans().add(l2);
ct.getLinkmans().add(l3);
l1.setCustomer(ct);
l2.setCustomer(ct);
l3.setCustomer(ct); //保存
/*em.persist(ct);*/
em.persist(l1);
em.persist(l2);
em.persist(l3);
tx.commit();
em.close();
} @Test // 普通删除
public void t4()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); Customer ct = em.find(Customer.class, 4L);
em.remove(ct);
tx.commit();
em.close();
} @Test // 级联删除
// jpa的注解里面 @OneToMany 添加属性cascade=CascadeType.REMOVE (All)
public void t5() //根据一的一方删除关联的多的一方的所有数据(掌握)
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); Customer ct = em.find(Customer.class, 4L);
em.remove(ct);
tx.commit();
em.close();
} } JPA多表对多表的操作 :
package cn.baidu.demo; import javax.persistence.CascadeType;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.ManyToMany; import org.junit.Test; import cn.baidu.domain.Role;
import cn.baidu.domain.User;
import cn.baidu.utils.JPAutils; /*
多对多的操作*/
public class Demo3
{
@Test //普通保存 保存2个用户 3个角色
public void t1()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); User user1 = new User();
user1.setUser_name("jack");
User user2 = new User();
user2.setUser_name("rose"); Role r1 = new Role();
r1.setRole_name("员工");
Role r2 = new Role();
r2.setRole_name("班主任");
Role r3 = new Role();
r3.setRole_name("助教"); // 双向关联
user1.getRoles().add(r1);
user1.getRoles().add(r3);
user2.getRoles().add(r1);
user2.getRoles().add(r2); r1.getUsers().add(user1);
r1.getUsers().add(user2);
r2.getUsers().add(user2);
r3.getUsers().add(user1); // 保存
em.persist(user1);
em.persist(user2);
em.persist(r1);
em.persist(r2);
em.persist(r3); tx.commit();
em.close();
} // jpa多对多的级联操作
// 级联保存: 保存用户的同时把关联的角色给保存了(不用)
// @ManyToMany 添加cascade=cascade=CascadeType.PERSIST
@Test
public void t2()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
User user1 = new User();
user1.setUser_name("jack");
User user2 = new User();
user2.setUser_name("rose"); Role r1 = new Role();
r1.setRole_name("员工");
Role r2 = new Role();
r2.setRole_name("班主任");
Role r3 = new Role();
r3.setRole_name("助教"); // 双向关联
user1.getRoles().add(r1);
user1.getRoles().add(r3);
user2.getRoles().add(r1);
user2.getRoles().add(r2); r1.getUsers().add(user1);
r1.getUsers().add(user2);
r2.getUsers().add(user2);
r3.getUsers().add(user1); // 保存
em.persist(user1);
em.persist(user2);
/*em.persist(r1);
em.persist(r2);
em.persist(r3);*/ tx.commit();
em.close();
} @Test // 普通删除(常用)
public void t3()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); User user = em.find(User.class, 1L);
em.remove(user);
tx.commit();
em.close();
} @Test // 级联删除(避免去使用)
public void t4()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); User user = em.find(User.class, 2L);
em.remove(user);
tx.commit();
em.close();
} // jpa的用户角色分配
// 添加角色
// 删除角色
// 修改角色
@Test
public void t5()
{
EntityManager em = JPAutils.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
// 获取用户
User user = em.find(User.class, 3L);
// 获取班主任
Role rl = em.find(Role.class, 6L);
//给用户添加
user.getRoles().add(rl);
tx.commit();
em.close();
} } 总结:
JPA的作用?
给所有的orm框架提供了一套接口
好处: 所有的ORM框架只要实现了这个JPA接口,用来操作数据库数据的方式和方法以及注解都一致了 jpa的环境搭建: 在hibernate的环境基础上多加一个包--hibernate-entitymanager-5.0.7.Final.jar 单表的映射
@Entity 实体类
@Table(name="cst_customer") 与表的映射
@Id 指定OID属性
@Column(name="cust_id") 指定映射的字段
@GeneratedValue(strategy=GenerationType.IDENTITY) 指定主键的生成策略 crud:
persist()
----保存 find() : 立即加载
getReference():延迟加载
-----单条数据的oid查询 merge()
---修改 remove()
---删除 批量查询:
类似之前的query方式 一对多:
一: @OneToMany(targetEntity=LinkMan.class,mappedBy="customer")
多: @ManyToOne(targetEntity=LinkMan.class)
一对多的关系配置:
@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id") 多对多:
多(被动): @ManyToMany(targetEntity=User.class,mappedBy="roles")
多(主动): @ManyToMany(targetEntity=Role.class)
多对多的关系配置:
@JoinTable(name="中间表的名称",joinColumns="自己在中间表的配置(数组)"
inverseJoinColumns="对方在中间表的配置(数组)") 级联:
cascade=CascadeType.ALL 做级联保存以及级联删除
cascade=CascadeType.PERSIST 只做级联保存
cascade=CascadeType.REMOVE 只做级联删除

SSH框架之Hibernate第四篇的更多相关文章

  1. SSH框架之hibernate《四》

    hibernate第四天     一.JPA相关概念         1.1JPA概述             全称是:Java Persistence API.是sun公司推出的一套基于ORM的规范 ...

  2. SSH框架之Spring第四篇

    1.1 JdbcTemplate概述 : 它是spring框架中提供的一个对象,是对原始JdbcAPI对象的简单封装.spring框架为我们提供了很多的操作模板类. ORM持久化技术 模板类 JDBC ...

  3. SSH框架之Hibernate第三篇

    1.1 多表关系分析和创建. 1.1.1 表关系分析和创建 表数据和表数据之间可以存在的关系? 一对多的关系 客户和联系人 建立关系原则: 在多的一方创建一个字段,这个字段作为外键指向一的一方的主键 ...

  4. SSH框架中hibernate 出现 user is not mapped 问题

    SSH框架中hibernate 出现 user is not mapped 问题      在做SSH框架整合时,在进行DAO操作时.这里就只调用了chekUser()方法.运行时报  user is ...

  5. 【SSH三大框架】Hibernate基础第二篇:编写HibernateUtil工具类优化性能

    相对于上一篇中的代码编写HibernateUtil类以提高程序的执行速度 首先,仍然要写一个javabean(User.java): package cn.itcast.hibernate.domai ...

  6. SSH框架之Hibernate第二篇

    1.1 持久化类的编写规则 1.1.1 什么是持久化类? 持久化类 : 与表建立了映射关系的实体类,就可以称之为持久化类. 持久化类 = Java类 + 映射文件. 1.1.2 持久化类的编写规则 ( ...

  7. SSH框架之Hibernate第一篇

    1.2Hibernate的概述: 1.2.1 什么Hibernate? Hibernate(开发源代码的对象关系映射框架)是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它 ...

  8. 【SSH三大框架】Hibernate基础第一篇:编写第一个Hibernate程序

    接下来这几章节学习的是Hibernate,Hibernate的主要作用就是用来和数据库进行连接,简化了JDBC的操作. 首先,我们创建项目,然后把Hibernate的jar包和sqlserver的驱动 ...

  9. 【SSH三个框架】Hibernate第十篇基础:inverse属性具体解释

    inverse后经常用于双向1-N在相关性.它也可以在使用N-N该协会,这里,例如用双1-N联想 或两个与各部门及工作人员,两javabean没有写. 首先,我们的员工看映射文件: <?xml ...

随机推荐

  1. HDU 4777 Rabbit Kingdom (2013杭州赛区1008题,预处理,树状数组)

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. Uncaught RangeError&colon; Maximum call stack size exceeded解决思路

    今天突然碰到这样的JavaScript错误:Uncaught RangeError: Maximum call stack size exceeded 这个翻译过来就是堆栈溢出了. 1.原因:有小类到 ...

  3. why does txid&lowbar;current&lpar;&rpar; assign new transaction-id&quest;

    Naoya: Hi,hackers! I have a question about txid_current(). it is "Why does txid_current() assig ...

  4. 如何处理ABBYY中出现错误代码142和55的问题

    在使用ABBYY FineReader 12OCR文字识别软件创建PDF文件时,有时会出现以下错误提示:内部程序错误..\Src\SpecialFontFactory.cpp,142和内部程序错误.. ...

  5. C&plus;&plus;开源代码项目汇总

    Google的C++开源代码项目 v8  -  V8 JavaScript EngineV8 是 Google 的开源 JavaScript 引擎.V8 采用 C++ 编写,可在谷歌浏览器(来自 Go ...

  6. PHPStudy&plus;PHPStorm下配置隐藏项目入口文件

    img { max-width: 100% } 默认情况下项目入口文件是站点根目录下index.php文件,一般程序启动时通过这个文件,定义文件路径,配置重要节点(比如是否开启调试模式),注册路由等, ...

  7. noj 算法 八数码问题

    描述 在九宫格里放在1到8共8个数字还有一个是空格,与空格相邻的数字可以移动到空格的位置,问给定的状态最少需要几步能到达目标状态(用0表示空格):1 2 34 5 67 8 0   输入 输入一个给定 ...

  8. 14&period; Encryption tools (加密工具 8个)

    SSH(Secure Shell)现在是无处不在的程序,用于在远程机器上登录或执行命令. 它通过不安全的网络在两个不受信任的主机之间提供安全的加密通信,取代了可怕的不安全的telnet / rlogi ...

  9. c3p0配置Spring

    jdbc.properties jdbcUrl=jdbc:mysql://localhost:3306/myoa?useUnicode=true&characterEncoding=utf-8 ...

  10. Trident中的解析包含的函数操作与投影操作

    一:函数操作 1.介绍 Tuple本身是不可变的 Function只是在原有的基础上追加新的tuple 2.说明 如果原来的字段是log,flag 新增之后的tuple可以访问这些字段,log,fla ...