欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【spring实战第五版遇到的坑】3.2中配置关系映射时,表名和3.1中不一样

程序员文章站 2022-03-30 21:49:48
3.2章中按照书中的步骤写好相应类的映射关系,发现启动时,之前在3.1章中建的表全部被删重新建立了,并且 表的数据没了,由于使用了JPA,默认使用的是hibernate,在启动时会删除所有的表并重新的建立表结构,而且 和`data.sql`中的语句并没有执行。解决办法很简单,在application ......

3.2章中按照书中的步骤写好相应类的映射关系,发现启动时,之前在3.1章中建的表全部被删重新建立了,并且ingredient表的数据没了,由于使用了jpa,默认使用的是hibernate,在启动时会删除所有的表并重新的建立表结构,而且schema.sqldata.sql中的语句并没有执行。解决办法很简单,在application.properties文件中加入下面的配置:

spring.jpa.hibernate.ddl-auto=none

关闭掉hibernate的ddl的处理功能就能行了。

不过还有一些地方需要调整,在3.1章的表字段的命名是java风格的,在执行hibernate的查询语句时会报错,就拿taco来说:

package tacos;
import java.util.date;
import java.util.list;

import javax.persistence.entity;
import javax.persistence.generatedvalue;
import javax.persistence.generationtype;
import javax.persistence.id;
import javax.persistence.manytomany;
import javax.persistence.prepersist;
import javax.validation.constraints.notnull;
import javax.validation.constraints.size;

import lombok.data;

@data
@entity
public class taco {
  
  @id
  @generatedvalue(strategy=generationtype.identity)
  private long id;
  
  private date createdat;
  
  @notnull
  @size(min=5, message="name must be at least 5 characters long")

  private string name;

  @manytomany(targetentity=ingredient.class)
  @size(min=1, message="you must choose at least 1 ingredient")
  private list<ingredient> ingredients;
  
  @prepersist
  void createdat() {
    this.createdat = new date();
  }
  
}

由于createdat属性未加上@column注解,那么你会认为它对应的字段会是createdat,实际上再查询时,你会发现他映射的字段是created_at,即使你给他加上@column(name="createdat")也不起作用,但是你给他加上@column(name="createdat")确实可以的。可能是spring强制你的字段必须符合sql的字段命名标准,会自动将java的驼峰命名的熟悉名转换成用下划线分隔的形式。

如果逐步的去按照@column(name="createdat")这样的方式去处理实在太麻烦了,所以直接修改了表结构的ddl语句,如下:

drop table taco_ingredients if exists;
drop table taco_order_tacos if exists;

create table if not exists ingredient (
  id varchar(4) not null,
  name varchar(25) not null,
  type varchar(10) not null
);

create table if not exists taco (
  id identity,
  name varchar(50) not null,
  created_at timestamp not null
);

create table if not exists taco_ingredients (
  taco_id bigint not null,
  ingredients_id varchar(4) not null
);

alter table taco_ingredients
    add foreign key (taco_id) references taco(id);
alter table taco_ingredients
    add foreign key (ingredients_id) references ingredient(id);

create table if not exists taco_order (
    id identity,
    delivery_name varchar(50) not null,
    delivery_street varchar(50) not null,
    delivery_city varchar(50) not null,
    delivery_state varchar(2) not null,
    delivery_zip varchar(10) not null,
    cc_number varchar(16) not null,
    cc_expiration varchar(5) not null,
    cccvv varchar(3) not null,
    placed_at timestamp not null
);

create table if not exists taco_order_tacos (
    order_id bigint not null,
    taco_id bigint not null
);

alter table taco_order_tacos
    add foreign key (order_id) references taco_order(id);
alter table taco_order_tacos
    add foreign key (taco_id) references taco(id);

把上面的语句放入schema.sql文件就能完美解决问题。