当前位置: 澳门新豪天地3559 > 互联网 > 正文

Spring入门---JPA学习笔记,---jpa学习笔记

时间:2019-06-29 09:41来源:互联网
声明:本文内容来源于网络,如有侵权请联系删除 1.实体类实现 分别建立dao,filter,model,util的包,并在model中实现实体类,这里以User.java为例. 注意对于 数据库中外键 ,比如adress表中有外键

声明:本文内容来源于网络,如有侵权请联系删除

1.实体类实现

分别建立dao,filter,model,util的包,并在model中实现实体类,这里以User.java为例.

注意对于数据库中外键,比如adress表中有外键user_id,那么在Adress.java中就可以直接给个User对象,在取adress表的时候就把user一并取出来.

User.java

package com.model;

import java.util.List;

/**
 * Created by nl101 on 2016/2/22.
 */
public class User {
    private int id;//id
    private String username;
    private String password;
    private String nickname;//昵称
    private int type;//1表示管理员,2表示注册用户

    private List addresses;

    public List getAddresses() {
        return addresses;
    }

    public void setAddresses(List addresses) {
        this.addresses = addresses;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

Adress.java

package com.model;

/**
 * Created by nl101 on 2016/2/22.
 */
public class Address {
    private int id;
    private String name;
    private String phone;
    private String postcode;
    //直接给user对象,来代替user_id
    private User user;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getPostcode() {
        return postcode;
    }

    public void setPostcode(String postcode) {
        this.postcode = postcode;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

Spring入门---JPA学习笔记,---jpa学习笔记

  用了一段时间的Spring,到现在也只是处于会用的状态,对于深入一点的东西都不太了解。所以决定开始深入学习Spring。

  本文主要记录JPA学习。在学习JPA之前,需要了解一些ORM的概念。

ORM概念:

  对象关系映射ORM(Object/Relation Mapping)是一种为了解决面向对象和关系数据之间存在互不匹配现象的技术(范式不匹配)。简而言之,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到数据库中。本质上是将数据从一种形式转换到另外一种形式。(个人考虑:但是这么做,感觉好像和一般方法比起来会有额外的开销吧?待解决)

  范式不匹配:

 

ORM具备功能:

  一般ORM框架包括以下四个功能:

 

映射发生情况:

  对象-关系映射一般发生在以下情况:

 

 


  以上就是JPA的一些概念,接下来上JPA。

JPA功能:

  JPA(Java persistence API)主要用用于Java中处理持久化操作。对ORM特性和功能进行标准化。分别定义了用来将对象模型映射到关系模型的API、可以在对象上执行CRUD操作、一种对象查询语言以及通过对象图获取数据的标准API。

  JPA好处:???都还没怎么用,没法做出比较。还是先使用一段时间后,再来评价

 

使用JPA:

定义实体:

  实体定义:一个对象在数据库端与一个带有主键的记录相对应,那么该对象就称为实体。

  下面代码定义了一个最简单的实体类:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * 
 * <p>ClassName: User.java<p>
 * <p>用户实体类<p>
 * @author linzj
 * @createTime 2016年3月17日  下午1:08:35
 */
@Entity
@Table(name="user")
public class User {

    @Id
    @GeneratedValue
    private Long id;

}

  JPA为映射提供了java注解,可以发现这些注解都在javax.persistence包下。上面的@Entity注解定义了User类为持久化类型,并有一个对应的表。@Table注解指定了表名,如果没有指定表明则默认使用类名为其表名。

  @Id注解标记了主键属性。如果主键列名与属性名不匹配,则可以使用@Column来指定对应的主键列名,如添加上@Column(name=”uid”),就与uid列表对应。应用程序并不负责生成主键值,而是在新记录插入期间由JPA供应商分配(如Hibernate)。通过@GenerateValue注解告诉JPA,应用程序将不会负责分配主键值,而是有JPA供应商处理。

属性映射到列:

  为了更加直观的理解。我先建了一张User表:

mysql> create table user(
    -> id int(5) not null primary key auto_increment,
    -> username varchar(60) not null,
    -> passwd varchar(60) not null);
Query OK, 0 rows affected (0.14 sec)

mysql> describe user;
 ---------- ------------- ------ ----- --------- ---------------- 
| Field    | Type        | Null | Key | Default | Extra          |
 ---------- ------------- ------ ----- --------- ---------------- 
| id       | int(5)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(60) | NO   |     | NULL    |                |
| passwd   | varchar(60) | NO   |     | NULL    |                |
 ---------- ------------- ------ ----- --------- ---------------- 

  接下来我们就可以将刚刚的User实体类添加对应的属性,并将属性映射到上面这张user表中对应的列了:

/**
 * 
 * <p>ClassName: User.java<p>
 * <p>用户实体类<p>
 * @author linzj
 * @createTime 2016年3月17日  下午1:08:35
 */
@Entity
@Table(name="user")
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String username;

    @Column(name = "passwd")
    private String password;

    @Transient
    private String others;
}

  因为表中没有password这个字段,所以我们必须指定映射的列名,即指定password映射到passwd。我们还发现实体类中多了一个表里没有的属性others,注意这个others属性已经注解为@Transient,因此others属性将被JPA忽略,不会进行映射。

对象之间创建关联:

  数据库关联类型有:

  • 一对一(1:1)
  • 多对1(M:1)
  • 一对多(1:M)
  • 多对多(M:M)

一对一关联:

/**
 * 
 * <p>ClassName: User.java<p>
 * <p>
 *     用户实体类,通过@OneToOne注解标识一对一关联,
 *     @JoinColumn注解更加User和Adress实体指定了
 *     表之间的外键关系。用户表中的列引用了地址表
 * <p>
 * @author linzj
 * @createTime 2016年3月17日  下午1:08:35
 */
@Entity
@Table(name="user")
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String username;

    @Column(name = "passwd")
    private String password;

    @OneToOne
    @JoinColumn(name = "adress_id")//添加外键
    private Adress adress;
}


/**
 * 
 * <p>ClassName: Adress.java<p>
 * <p>地址实体类<p>
 * @author linzj
 * @createTime 2016年3月17日  下午1:52:30
 */
@Entity
public class Adress {
    //...pass
}

多对一:

/**
 * 
 * <p>ClassName: Employe.java<p>
 * <p>
 *     雇员实体类,使用了@ManyToOne注解,并使用了@JoinColumn指定两表之间的外键关系,
 *     optional=false 标识关联是Employe必须的,即:Employe不能单独存在。
 * <p>
 * @author linzj
 * @createTime 2016年3月17日  下午1:55:11
 */
@Entity
public class Employe {

    //...pass

    @ManyToOne(optional = false)
    @JoinColumn(name = "company_id")
    private Company company;

}

@Entity
public class Company {
    //...pass
}

多对一:

/**
 * 
 * <p>ClassName: Student.java<p>
 * <p>
 *     学生实体类,@OneToMany注解在学生和书本之间创建了一对多的关系,
 *     用@JoinColumn指定外键,不同的是这次外键列存在于Book实体中。
 * <p>
 * @author linzj
 * @createTime 2016年3月17日  下午2:01:23
 */
@Entity
public class Student {

    //...pass
    @OneToMany
    @JoinColumn(name = "student_id")
    private Set<Book> books = new HashSet<Book>();

}

@Entity
public class Book {

    //...pass

}

多对多:

/**
 * 
 * <p>ClassName: Product.java<p>
 * <p>
 *     产品实体类,@ManyToMany创建多对多关联,
 *     注意这里用的是@JoinTable而不是@JoinColumn,
 *     因为一边的多个实例可以与另一边的多个实例相关联。因此无法再一个列中保存指向另一个表的关联数据。
 *     所以这里就需要提供一个关联表,该表包含每个表的主键列引用。
 *     本示例中,关联表是product_catalog,joinColumns和inverseJoinColumns指定
 *     product_catalog表中的列名,joinColumns指定Product表主键的引用,inverseJoinColumns
 *     指定Catalog表主键的引用。
 * <p>
 * @author linzj
 * @createTime 2016年3月17日  下午2:07:47
 */
@Entity
public class Product {
    @Id
    @GeneratedValue
    private Long id;

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name = "product_catalog", joinColumns = @JoinColumn(name = "product_id"), 
    inverseJoinColumns = @JoinColumn(name = "catalog_id"))
    private Set<Catalog> catalog = new HashSet<Catalog>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Set<Catalog> getCatalog() {
        return catalog;
    }

    public void setCatalog(Set<Catalog> catalog) {
        this.catalog = catalog;
    }
}

@Entity
public class Catalog {
    @Id
    @GeneratedValue
    private Long id;
}
/**
对应的表如下:
mysql> describe product_catalog;
 ------------ ------------ ------ ----- --------- ------- 
| Field      | Type       | Null | Key | Default | Extra |
 ------------ ------------ ------ ----- --------- ------- 
| product_id | bigint(20) | NO   | PRI | NULL    |       |
| catalog_id | bigint(20) | NO   | PRI | NULL    |       |
 ------------ ------------ ------ ----- --------- ------- 
2 rows in set (0.01 sec)

mysql> select * from product_catalog;
 ------------ ------------ 
| product_id | catalog_id |
 ------------ ------------ 
|          1 |          1 |
|          1 |          2 |
 ------------ ------------ 
2 rows in set (0.00 sec)

mysql> select * from product;
 ---- 
| id |
 ---- 
|  1 |
 ---- 
1 row in set (0.00 sec)

mysql> select * from catalog;
 ---- 
| id |
 ---- 
|  1 |
|  2 |
 ---- 
*/

  关联的方向性:

  关联的方向性只有两种:单向和双向。

  在单向关联中,只能从关联的源对象到目标对象。双向关联则处理能从关联的源对象到目标对象外,还可以从目标对象到源对象。

 

图片 1

一.项目功能结构

在如下代码中,我们只是将上面的Adress实体类修改了下,就构成了双向关联。我们在Adress实体类代码中,添加了@OneToOne(mappedBy

"adress"),并且添加了mappedBy属性,通过该属性,JPA可以识别该属性,从而管理两个实体之间的关联。使用mappedBy属性的一边可以看作成一个镜子,或者是只读的。它并不会对数据库的数据产生影响。拿下面的代码说明就是,用下面的实体类做持久化操作后,数据库的Adress表里并不会多一列关于user的字段。

@Entity
@Table(name="user")
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String username;

    @Column(name = "passwd")
    private String password;

    @OneToOne
    @JoinColumn(name = "adress_id")//添加外键
    private Adress adress;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Adress getAdress() {
        return adress;
    }

    public void setAdress(Adress adress) {
        this.adress = adress;
    }

}

@Entity
public class Adress {
    @Id
    @GeneratedValue
    private Long id;

    @OneToOne(mappedBy = "adress")
    private User user;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

}

 

上面代码放在我的GITHUB

另外提供一些关于JPA的博客:

以上是本人学习JPA的记录,下一篇介绍配置和使用JPA。

用了一段时间的Spring,到现在也只是处于会用的状态,对于深入一点的东西都不太了解。所以决定开...

图片 2

3.对应sql语句

CREATE DATABASE shop;
use shop;

create table user(
  id int(11) primary key auto_increment,
  username varchar(100),
  password varchar(100),
  nickname varchar(100),
  type int(5)
);

INSERT INTO user VALUES (null,'admin','7946521','管理员',1);

CREATE TABLE address(
  id INT(10) PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255),
  phone VARCHAR(100),
  postcode VARCHAR(100),
  user_id INT(10),
  CONSTRAINT FOREIGN KEY (user_id) REFERENCES user(id)
);
INSERT INTO address VALUES (NULL ,'安徽阜阳','1234567890','236000','1');

SELECT t1.*,t2.* FROM address t1 LEFT JOIN user t2 ON t1.user_id = t2.id where t1.user_id =1 ;

create table orders(
  id int(11) primary key auto_increment,
  buy_date datetime,
  pay_date datetime,
  confirm_date datetime,
  status int(5),
  user_id int(11),
  address_id int(11),
  CONSTRAINT FOREIGN KEY(user_id) REFERENCES user(id),
  CONSTRAINT FOREIGN KEY(address_id) REFERENCES address(id)
);

create table category(
  id int(11) primary key auto_increment,
  name varchar(100)
);

create table goods(
  id int(11) primary key auto_increment,
  name varchar(100),
  price double,
  intro text,
  img varchar(100),
  stock int(10),
  c_id int(10),
  CONSTRAINT FOREIGN KEY(c_id) REFERENCES category(id)
);

create table goods_orders(
  id int(11) primary key auto_increment,
  goods_id int(10),
  orders_id int(10),
  CONSTRAINT FOREIGN KEY(goods_id) REFERENCES goods(id),
  CONSTRAINT FOREIGN KEY(orders_id) REFERENCES orders(id)
);

图片 3

1.功能

图片 4

图片 5

javaWEB简单商城项目(一)

项目中使用到了上一篇博文的分页框架,还有mybatis,重点是学习mybatis.
现在有些小迷茫,不知道该干啥,唉,不想那么多了,学就对了


图片 6

2.分页框架准备

分页主要是写pager.java和SystemContext.java以及SystemFilter.java三个类.可以参开前面的博文,jsp通用分页框架


完整建立后如下

图片 7

) 项目中使用到了上一篇博文的分页框架,还有mybatis,重点是学习mybatis. 现在有些小迷茫,不知道该干啥,唉,不想那么多了...

User.java

二.项目准备

图片 8

2.实体

图片 9

对应sql语句

图片 10

完整建立后如下

图片 11

编辑:互联网 本文来源:Spring入门---JPA学习笔记,---jpa学习笔记

关键词: www.3559.com