建表语句,虽然可以自动建表,但我就是想皮一下,开心
CREATE TABLE t_user (
id INT NOT NULL auto_increment,
`name` VARCHAR (20),
PRIMARY KEY (id)
) ENGINE = INNODB DEFAULT charset = utf8;
CREATE TABLE t_orders (
id INT NOT NULL auto_increment,
`name` VARCHAR (20),
uid INT,
PRIMARY KEY (id),
CONSTRAINT t_user_id FOREIGN KEY (uid) REFERENCES t_user (id)
) ENGINE = INNODB DEFAULT CHARSET = utf8;
persistence.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="jpa" transaction-type="RESOURCE_LOCAL">
<!--
配置用什么ORM框架
1. 实际上配置的是 javax.persistence.spi.PersistenceProvider 接口的实现类
2. 如果JPA项目中只有一个JPA的实现产品,则可以不配置该节点
-->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- 添加持久化类 -->
<class>com.yjj.entity.Order</class>
<class>com.yjj.entity.User</class>
<properties>
<!-- 配置数据源信息 -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="123456"/>
<!-- 配置JPA实现产品的属性,即hibernate的属性 -->
<property name="hibernate.format_sql" value="true"/><!-- 是否格式化sql语句 -->
<property name="hibernate.show_sql" value="true"/> <!-- 是否在控制台打印sql语句 -->
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
实体类
一的一方表中就只有id和name,那么属性也就只有id和name
package com.yjj.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 单向多对一
* t_user表字段,id,name
*/
@Table(name = "t_user")
@Entity
public class User {
@Id
@GeneratedValue
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
多的一方表中有id,name,uid(外键对应t_user表的id),那么属性就有id,name,把uid换成对应的实体类User,维护一个User对象
package com.yjj.entity;
import javax.persistence.*;
/**
* 单向多对一
* t_orders表字段,id,name,uid
*/
@Table(name = "t_orders")
@Entity
public class Order {
@Id
@GeneratedValue
private Integer id;
private String name;
@JoinColumn(name = "uid")
@ManyToOne
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", name='" + name + '\'' +
", user=" + user +
'}';
}
}
测试类
User user =new User();
user.setName("殷俊杰");
Order order=new Order();
order.setName("订单一");
order.setUser(user);
Order order1=new Order();
order1.setName("订单二");
order1.setUser(user);
manager.persist(user);
manager.persist(order);
manager.persist(order1);
输出
Hibernate:
insert
into
t_user
(name)
values
(?)
Hibernate:
insert
into
t_orders
(name, uid)
values
(?, ?)
Hibernate:
insert
into
t_orders
(name, uid)
values
(?, ?)
单向多对一保存的时候必须先保存一方,否则会出现多余的update语句,从而影响性能
试一下先保存多的一方,再保存一的一方
manager.persist(order);
manager.persist(order1);
manager.persist(user);
输出
Hibernate:
insert
into
t_orders
(name, uid)
values
(?, ?)
Hibernate:
insert
into
t_orders
(name, uid)
values
(?, ?)
Hibernate:
insert
into
t_user
(name)
values
(?)
Hibernate:
update
t_orders
set
name=?,
uid=?
where
id=?
Hibernate:
update
t_orders
set
name=?,
uid=?
where
id=?
结论:如果先插入order,它的USER_ID字段会先为空,在插入user之后,再进行update操作,USER_ID。因此,在多对一映射关系的情况下,建议先插入“一”的对象(user),再插入“多”的对象(order),减少sql语句可以提高效率
查找
Order order=manager.find(Order.class,1);
System.out.println(order);
输出
Hibernate:
select
order0_.id as id1_1_0_,
order0_.name as name2_1_0_,
order0_.uid as uid3_1_0_,
user1_.id as id1_3_1_,
user1_.name as name2_3_1_
from
t_orders order0_
left outer join
t_user user1_
on order0_.uid=user1_.id
where
order0_.id=?
Order{id=1, name='订单一', user=User{id=1, name='殷俊杰'}}
@ManyToOne(fetch=FetchType.LAZY)在ManyToOne注解中可加入FetchType.LAZY延迟加载,在用到一的对象时才真正查询一的对象
删除
Order order=entityManager.find(Order.class,1);
entityManager.remove(order);
输出
Hibernate:
select
order0_.id as id1_0_0_,
order0_.ordername as ordernam2_0_0_,
order0_.userid as userid3_0_0_,
user1_.id as id1_3_1_,
user1_.name as name2_3_1_
from
t_order order0_
left outer join
user user1_
on order0_.userid=user1_.id
where
order0_.id=?
Hibernate:
delete
from
t_order
where
id=?
不会关联删除user因为还有其他订单关联着user,如果先删除user的话会报错,因为外键关联。
更新
Order order=entityManager.find(Order.class,2);
order.getUser().setName("霸波尔奔");
transaction.commit();
输出
Hibernate:
select
order0_.id as id1_0_0_,
order0_.ordername as ordernam2_0_0_,
order0_.userid as userid3_0_0_,
user1_.id as id1_3_1_,
user1_.name as name2_3_1_
from
t_order order0_
left outer join
user user1_
on order0_.userid=user1_.id
where
order0_.id=?
Hibernate:
update
user
set
name=?
where
id=?
更新时不用persist再保存,提交事务时会自动将缓存保存到数据库,但是一定要提交事务。
很烦,不想写注释,反正自己看
参考文章
http://blog.csdn.net/je_ge/article/details/53493897