关于以前的JDBC:
//SQL语句
String sql = "insert into xx(xx,xx,xx) values(xx,xx,xx); ";
//加载驱动:
Class.forname(com.mysql.jdbc.Driver);
//建立连接
Connection con = DirverManager.getCon(username,password,url,driver);
//创建预处理对象
PreparedStatment psmt = con.prepareStatment(sql);
//进行赋值
psmt.setString(1,xxx);
psmt.setString(1,xxx);
....
//执行语句
psmt.executeUpdate();
ORM思想:
表示对象关系映射,在面向对象的软件开发中,同过ORM思想,就可以把对象映射到数据库中,就是只有一个操作就可以做到实体、属性和数据库表、字段的对应。
简单的说:就是建立实体类和和数据库表之间的关系,从而达到操作实体类就相当于操作和数据库表的目的。
主要为了解决原生的JDBC对数据库操作的复杂问题,让程序员重点在于业务开发上面。
建立两个映射关系:
实体类和表的映射关系
实体类属性和表的字段的映射关系
ORM的常见框架
常见的ORM框架有Mybatis、Hibernate、JPA
Hibernate:
概述:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将实体与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
JPA:
全称:Java Persistence API,即Java持久化API,是SUM公司推出的一套关于ORM的规范,内部都是抽象类和接口构成的
JPA的优势:
标准化、容器级特性的支持、简单方便、查询能力强、具有高级特性
JPA和Hibernate的关系:
JPA的实例:
-
一般操作
-
//基本步骤 //创建工厂类 //此处获取的是Persistence.xml里面配置的持久化单元名称 //EntityManagerFactory对象是一个安全的对象,支持并发访问,但是EntityManagerFactory此对象的创建及其浪费资源。我们可以使用静态代码块只加载一次就可以 EntityManagerFactory factory = Persistence.createEmtityManagerFactory("myJPA"); //生产实体管理类 EntityManager entitymanager = factory.createEntityManager(); //获取事务对象,开启事务 EntityTransaction transcation = entitymanager.getTransaction(); transcation.begin(); //进行操作、提交事务、回滚事务 tanscation.merge();//实体更新操作 tanscation.find();//查询操作 tanscation.getReference();//查询操作 tanscation.remove(); tanscation.persist(); entitymanager.commit(); //释放资源 entitymanager.close(); factory.close();
-
-
抽取JAPUtils
-
//类 public final class JPAUtil { // JPA的实体管理器工厂:相当于Hibernate的SessionFactory private static EntityManagerFactory em; // 使用静态代码块赋值 static { // 注意:该方法参数必须和persistence.xml中persistence-unit标签name属性取值一致 em = Persistence.createEntityManagerFactory("myPersistUnit"); } /** * 使用管理器工厂生产一个管理器对象 * @return */ public static EntityManager getEntityManager() { return em.createEntityManager(); } }
-
-
getReference
方法和find
方法的区别- find方法是在执行的方式就直接生成sql语句对数据库进行查询 --------------》立即加载方式
- 查询的对象就是当前的客户本身
- 调用方法时候就发送SQL查询
- getReference方法是在使用的时候才进行查询-------------------》延迟加载方式
- 获取的是一个动态代理对象
- 调用时候不会立即发生sql语句查询数据库,什么时候使用,什么时候发送sql查询
- find方法是在执行的方式就直接生成sql语句对数据库进行查询 --------------》立即加载方式
JPA的具体操作:
核心文件Persistence.xml
文件配置相关 此文件必须放在Resource下的META-INF文件里面
必须要加入的Persistence.xml的头部引入和配置持久化单元,相当于bean标签
<?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">
<!--持久化单元-->
<persistence-unit></persistence-unit>
</persistence>
具体配置
<?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">
<!--持久化单元
属性:
name:持久化单元的名称,便于使用
transaction-type:事务类型
JTA:分布式事务类型
RESOURCE_LOCAL:本地事务类型
-->
<persistence-unit name="myJPA" transaction-type="RESOURCE_LOCAL">
<!--配置JPA规范的服务提供商-->
<proveder>org.hibernate.jpa.HibernatePersistence</proveder>
<!--配置数据驱动-->
<properties>
<peoperty name="javax.persistence.jdbc.url" value="jdbc:mysql:localhost:3306/xxx"></peoperty>
<peoperty name="javax.persistence.jdbc.dirver" value="com.mysql.jdbc.driver"></peoperty>
<peoperty name="javax.persistence.jdbc.username" value="root"></peoperty>
<peoperty name="javax.persistence.jdbc.password" value="root"></peoperty>
</properties>
<!--配置jap提供者的可选配置
属性:
hibernate.show_sql:显示sql语句的 Boolean值:true|false
hibernate.hbn2ddl.auto:创建表的
取值:
create:运行时创建表(若原始有表存在,则会删除表之后再创建表在插入数据,说明只能插入最后一条数据,在插入多条数据时候不能使用)
update:运行时创建表(若原始有表存在,不会删除表,直接进行数据更新)
none:不创建表,若原始没有表,则会报错。
-->
<property name="" value=""></property>
</persistence-unit>
</persistence>
实体与数据库的关系
使用注解配置:
-
@ID:对于实体所对应的数据库的主键所标记
-
@Entity:声明此类是一个实体类
-
@Table:name=xxx :对应的数据库表的名字
-
@GeneratedValue:主键生成策略
- strategy=GenerationType.IDENTITY:自增, 需要底层的数据库支持自增功能 mysql,
- strategy=GenerationType.SEQUENCE:序列, 需要底层的数据库支持序列功能 oracle
- strategy=GenerationType.TABLE:自增, 是JPA提供的一种机制,通过生成一张表的形式帮我们完成主键自增
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7eQIfi6B-1626328199836)(C:\Users\肖森波\AppData\Roaming\Typora\typora-user-images\image-20210331123715204.png)]
- strategy=GenerationType.AUTO:由程序自动的帮助我们选择主键生成策略。
-
@Column
-
name:指定数据库表的列名称。
-
unique:是否唯一
-
nullable:是否可以为空
-
inserttable:是否可以插入
-
updateable:是否可以更新
-
columnDefinition: 定义建表时创建此列的DDL
-
secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境
-
/*
所有的注解都是使用JPA的规范提供的注解,
所以在导入注解包的时候,一定要导入javax.persistence下的
*/
@Entity
@Table(name="xxx")
public class Customer implements Serializable {
@ID
@GeneratedValue(stratecy=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;
}
}
实体与表的关系建立
@Entity:说明是实体类
@Table:对应表
实体的属性和表的字段的关系的建立
@ID:说明是主键
@GeneratedValue:主键自增策略
-
引入依赖
-
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.hibernate.version>5.0.7.Final</project.hibernate.version> </properties> <dependencies> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- hibernate对jpa的支持包 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${project.hibernate.version}</version> </dependency> <!-- c3p0 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-c3p0</artifactId> <version>${project.hibernate.version}</version> </dependency> <!-- log日志 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- Mysql and MariaDB --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> </dependencies>
-
-
JAP的CRUD操作
-
查询
@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); //Customer c1 = em.getReference((Customer.class, 6L); //提交事务 tx.commit(); }catch(Exception e){ //回滚事务 tx.rollback(); e.printStackTrace(); }finally{ //释放资源 em.close(); } }
-
删除
-
Customer c1 = em.find(Customer.class, 6L); c1.setCustName("aaa"); em.clear();//把c1对象从缓存中清除出去 em.remove(c1);
-
-
修改
-
Customer c1 = em.find(Customer.class, 6L); c1.setCustName("aaa"); em.clear();//把c1对象从缓存中清除出去 em.merge(c1);
-
-
插入
-
Customer c1 = em.find(Customer.class, 6L); c1.setCustName("aaa"); em.clear();//把c1对象从缓存中清除出去 em.persisent(c1);
-
-
-
JAP的复杂操作
JPQL:Java Persistence Query Language java持久化查询,其特征与原生SQL语句类似,并且完全面向对象,通过类名和属性访问,而不是表名和表的属性。
-
查询全部
-
sql:select * from xxx
-
JPQL:from xxx 返回值是一个集合,遍历打印即可
-
@Test public void findAll() { EntityManager em = null; EntityTransaction tx = null; try { //获取实体管理对象 em = JPAUtil.getEntityManager(); //获取事务对象 tx = em.getTransaction(); tx.begin(); // 创建query对象 String jpql = "from Customer"; Query query = em.createQuery(jpql); // 查询并得到返回结果 List list = query.getResultList(); // 得到集合返回类型 for (Object object : list) { System.out.println(object); } tx.commit(); } catch (Exception e) { // 回滚事务 tx.rollback(); e.printStackTrace(); } finally { // 释放资源 em.close(); } }
-
-
分页查询
-
sql:select * from xxx where xxx limit x,y
-
JPQL:from xxx
-
query.setFirstResults(x);
-
query.setMaxResults(y);
-
String JPQL = "from xxx";query.setfirstResult();query.setMaxResults();Object count = query.getSingleResult(); // 得到集合返回类型
-
-
-
条件查询
-
sql:select * from xxx where xxx like ?;
-
JPQL:from xxx where xxx like ?;
-
query.setParamter(1,"%xx%");
-
String JPQL = "from xxx where xxx like ?";query.setParamter(1,"%xx%");Object count = query.getSingleResult(); // 得到集合返回类型
-
-
-
排序查询
-
String jpql = "from Customer order by custId desc";Object count = query.getSingleResult(); // 得到集合返回类型
-
-
统计查询
-
String jpql = "select count(custId) from Customer";Object count = query.getSingleResult(); // 得到集合返回类型
-
-