需要使用hibernate dao实现方法保存不同jsp页面的两张表有外键关系
Posted
技术标签:
【中文标题】需要使用hibernate dao实现方法保存不同jsp页面的两张表有外键关系【英文标题】:Need to save two tables from different jsp pages with foreign key relationship using hibernate dao implementation method 【发布时间】:2017-08-23 00:21:54 【问题描述】:表关系参考图
由于新手的限制,从银行jsp页面提交后,从卡jsp提交后都在一张图片中
我也是 *** 的新手SPRING
。我试图用外键概念创建两个表。我遵循了一些关于 *** 以及其他资源丰富的网站的示例,并设法创建了两个具有一对多关系的表。但问题是当我从卡片 jsp 页面提交时,我必须获取 cart_id 列下的第一行 id。相反,从卡 jsp 页面提交后,在 bankadmin 表下创建了新行,并且它的 id 被返回。我很困惑,不知道如何纠正解决这个问题。请善待并指导我。而且我一直在***中搜索一周,找不到任何对我有帮助的东西。提前致谢。
银行管理员模型
@Entity
@Table(name = "bankAdmin")
public class bankAdmin implements Serializable
@GeneratedValue(strategy=GenerationType.AUTO)
@Column (name = "bcode", nullable=false)
@Id private int bcode;
@Column (name = "bname")
private String bname;
@Column (name = "address")
private String address;
@Column (name = "phno")
private int phno;
@OneToMany(mappedBy="bankAdmin",cascade = CascadeType.ALL)
private Set<Cards> cards;
卡片模型
@Entity
@Table(name = "cards")
public class Cards implements Serializable
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="cname", unique=true)
@Id private int cname;
@Column (name = "ctype")
private String ctype;
@Column (name = "min_sal")
private int min_sal;
@Column (name = "year_fee")
private int year_fee;
@Column (name = "rewards")
private String rewards;
@Column (name = "jperks")
private String jperks;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="cart_id", nullable=false)
private bankAdmin bankAdmin;
public Cards()
public Cards(String ctype, int min_sal, int year_fee, String rewards, String jperks, bankAdmin b)//int cname,
this.ctype=ctype;
this.min_sal=min_sal;
this.year_fee=year_fee;
this.jperks=jperks;
this.rewards=rewards;
this.bankAdmin=b;
public bankAdmin getBankAdmin()
return bankAdmin;
public void setBankAdmin(bankAdmin bankAdmin)
this.bankAdmin = bankAdmin;
CardDaoImpl
public class CardsDaoImpl implements CardsDao
@Autowired
SessionFactory sessionfactory;
public void save(Cards cards)
Session session = null;
Transaction tx = null;
try
session = this.sessionfactory.openSession();
tx = session.beginTransaction();
bankAdmin bankadmin =new bankAdmin(); //=null;
String _ctype = cards.getctype();
int _min_sal = cards.getmin_sal();
int _year_fee = cards.getyear_fee();
String _rewards = cards.getrewards();
String _jperks = cards.getjperks();
Set<Cards> card = new HashSet<Cards>();
Cards config = new Cards(_ctype,_min_sal,_year_fee,_rewards,_jperks,bankadmin);
card.add(config);
bankadmin.setcards(card);
// System.out.println("bankadmin: before " + bankadmin);
// bankadmin.setbname(bankadmin.getbname());// "SBI"
// bankadmin.setphno(bankadmin.getphno());//1234567890
// bankadmin.setaddress(bankadmin.getaddress());//Bengaluru
// System.out.println("bankadmin: after " + bankadmin);
// int _cname = cards.getcname();
// int bankadmin = bankadmin.getbcode();
//_cname,_ctype,_min_sal,_year_fee,_rewards,_jperks,bankadmin
// card.add(config);
// config.setBankAdmin(cards.getBankAdmin(bankadmin));
// config.setcname(cards.getcname());
// config.setctype(cards.getctype());
// config.setmin_sal(cards.getmin_sal());
// config.setyear_fee(cards.getyear_fee());
// config.setrewards(cards.getrewards());
// config.setjperks(cards.getjperks());
// config.setBankAdmin(cards.getBankAdmin());
session.save(bankadmin);
session.save(config);
tx.commit();
catch (HibernateException e)
e.printStackTrace();
finally
session.close();
// get lms lights config from DB
public List<Cards> Ccards()
Session session = null;
// Transaction tx = null;
List<Cards> Ccards = null;
try
session = this.sessionfactory.openSession();
Ccards = session.createQuery("FROM Cards").list();
System.out.println("cards dao impl executed...");
System.out.println("cards config : "+ Ccards.toString());
catch (Exception e)
System.out.println("bankAdmin Dao impl Ex : " + e);
finally
session.close();
return Ccards;
BankDaoImpl
public class bankAdminDaoImpl implements bankAdminDao
@Autowired
SessionFactory sessionfactory;
public void save(bankAdmin badmin)
Session session = null;
Transaction tx = null;
try
session = this.sessionfactory.openSession();
tx = session.beginTransaction();
// bankAdmin bankadmin = new bankAdmin();
bankAdmin config = new bankAdmin();
config.setbcode(badmin.getbcode());
config.setbname(badmin.getbname());
config.setaddress(badmin.getaddress());
config.setphno(badmin.getphno());
session.save(config);//save//persist
tx.commit();
catch (HibernateException e)
e.printStackTrace();
finally
session.close();
// get lms lights config from DB
public List<bankAdmin> BbankAdmin()
Session session = null;
// Transaction tx = null;
List<bankAdmin> BbankAdmin = null;
try
session = this.sessionfactory.openSession();
BbankAdmin = session.createQuery("FROM bankAdmin").list();
System.out.println("bankAdmin dao impl executed...");
System.out.println("bankAdmin config : "+ BbankAdmin.toString());
catch (Exception e)
System.out.println("bankAdmin Dao impl Ex : " + e);
finally
session.close();
return BbankAdmin;
【问题讨论】:
我很想帮助你,但我现在没有时间,所以我稍后会回来。您在银行数据库中得到一个 id 为 2 的空条目,因为您在CardDaoImpl.save()
中创建了一个新的 bankAdmin
。您正在创建没有任何属性的对象,这就是它在您的数据库中为空的原因。您要做的是找到 id 为 1 的银行,创建一张新卡,然后关联这两个对象,然后保存该对象。
能否请您发布数据库结构的 SQL 转储?
@kkflf ,老实说,当我使用 Windows 10 时,我不知道如何转储数据库结构。所有示例都与 Linux shell 有关。关于两个对象的关联,我怎样才能找到 ID 为 1 的银行?由于这与“bankAdmin bankadmin”类有关,因此无法将查询强制转换为 bankAdmin 。此外,如果我单独使用查询,则银行管理员将不会映射到此查询。我一直在努力。
安装mysql工作台。您可以在那里创建结构的数据库转储。这是最简单的方法,除非您可以从 cmd 或 powershell 访问 mysql 二进制文件。你试过我上面的建议了吗?
删除表如果存在bankadmin
; /*!40101 SET @saved_cs_client = @@character_set_client /; /!40101 SET character_set_client = utf8 */;创建表 bankadmin
(bcode
int(11) NOT NULL AUTO_INCREMENT, address
varchar(255) 默认空, bname
varchar(255) 默认空, phno
int(11) 默认空, 主键 ( bcode
) ) 引擎=InnoDB AUTO_INCREMENT=3 默认字符集=utf8; @kkflf
【参考方案1】:
好的。我已经发布了您的问题的解决方案。
首先,Spring 框架非常好用。该框架有很多功能,您应该利用这些功能。我不确定我是否能够涵盖这篇文章中的所有内容,所以请随时问我。
我创建了一个简单的 Spring Boot 应用程序。我一共得到了 6 个重要的文件,这些文件发布在下面。
请注意,我将您的课程重命名为 CamelCase,首字母大写。如BankAdmin
。这被认为是编写 java 类的标准方式。另请注意,我将Cards
重命名为Card
,因此请记住也要重命名数据库中的表。还要记得将bankadmin 表重命名为bank_admin。
您必须查看一些注释。 @Transactional
、@Autowired
和 PersistenceContext
。
所以一个快速简单的解释。 @Transactional
为您管理所有事务,因此您不必开始和提交事务。 @Autowired
为您创建对象,因此您不必自己管理对象依赖项。 PersistenceContext
基本上为您创建和 EntityManager 并为您管理它。您不必创建会话或 EntitManagerFactory。这三个注释的解释非常简短,因此您应该自己阅读它们。
我还删除了@Table(name = "bankAdmin")
和@Table(name = "cards")
。如果您遵循命名类和数据库表的标准方式,JPA 可以自动查找这些表。这实际上很简单,但我仍然鼓励您自己研究一下。简而言之,大写的驼峰式转换为小写,_
在每个以大写字母开头的单词之间。 IE。如果您的类名是 BankAdmin
,那么 JPA 将自动在您的数据库中查找名为 bank_admin
的表。
application.properties - 关于您的数据库的详细信息
spring.datasource.url=jdbc:mysql://localhost:3306/***?useSSL=false
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.show-sql = true
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto = update
以下代码仅用于测试功能
@SpringBootApplication
public class ***Application
public static void main(String[] args)
ApplicationContext ctx = SpringApplication.run(***Application.class, args);
//Calling a class that is only made with the purpose of testing
Verification ts = ctx.getBean(Verification.class);
ts.run();
@Component
class Verification
@Autowired
private BankAdminDao bad;
@Autowired
private CardsDao cd;
void run()
//Create a new BankAdmin
BankAdmin ba = new BankAdmin();
ba.setAddress("someStreet");
ba.setPhno(12341234);
ba.setBname("myBanker");
//Create two cards and add them to a HashSet.
Card c1 = new Card("Visa", 1000, 1999, "Alot of", "Babes", ba);
Card c2 = new Card("Master Card", 2000, 500, "someThing", "anotherThing", ba);
Set<Card> cardList = new HashSet<>();
cardList.add(c1);
cardList.add(c2);
//Create a associatio between the BankAdmin and list of Cards
ba.setCards(cardList);
//Save them to the database.
bad.save(ba);
//Here we add a Card to an existing BankAdmin with the id 6 in the database.
//Create a new Card.
//The BankAdmin is set to null, because we not have not yet loaded the BankAdmin
Card c3 = new Card("Visa", 9999, 1337, "Alot of", "Male Babes", null);
//Save Card c3 with the BankAdmin id 6
cd.save(c3, 6);
银行管理员
@Entity
public class BankAdmin implements Serializable
@GeneratedValue(strategy=GenerationType.AUTO)
@Column (name = "bcode", nullable=false)
@Id private int bcode;
@Column (name = "bname")
private String bname;
@Column (name = "address")
private String address;
@Column (name = "phno")
private int phno;
@OneToMany(mappedBy="bankAdmin",cascade=CascadeType.ALL)
private Set<Card> cards;
//Getters and Setters have been removed to reduce the amount of code.
BankAdminDao
@Repository
//Transactional makes transaction automatical, so you do not have to begin and commit transactions yourself!
@Transactional
public class BankAdminDao
//This makes your life a lot eaier!
//It will take care of your EntitManagerFactory and Sessions
@PersistenceContext
EntityManager em;
public void save(BankAdmin bank)
em.merge(bank);
//get lms lights config from DB
public List<BankAdmin> getAllBankAdmin()
List<BankAdmin> bankList = (List<BankAdmin>)em.createQuery("SELECT b FROM BankAdmin b");
return bankList;
public BankAdmin getBankAdmin(int bankId)
return em.find(BankAdmin.class, bankId);
卡片
@Entity
public class Card implements Serializable
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="cname", unique=true)
@Id private int cname;
@Column (name = "ctype")
private String ctype;
@Column (name = "min_sal")
private int min_sal;
@Column (name = "year_fee")
private int year_fee;
@Column (name = "rewards")
private String rewards;
@Column (name = "jperks")
private String jperks;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="cart_id", nullable=false)
private BankAdmin bankAdmin;
public Card()
public Card(String ctype, int min_sal, int year_fee, String rewards, String jperks, BankAdmin b)
this.ctype=ctype;
this.min_sal=min_sal;
this.year_fee=year_fee;
this.jperks=jperks;
this.rewards=rewards;
this.bankAdmin=b;
public BankAdmin getBankAdmin()
return bankAdmin;
public void setBankAdmin(BankAdmin bankAdmin)
this.bankAdmin = bankAdmin;
卡道
@Repository
@Transactional
public class CardsDao
@PersistenceContext
EntityManager em;
@Autowired
BankAdminDao bad;
public void save(Card cards, int bankId)
BankAdmin bank = bad.getBankAdmin(bankId);
cards.setBankAdmin(bank);
bank.getCards().add(cards);
em.merge(bank);
public List<Card> getAllCards()
List<Card> cardList = (List<Card>)em.createQuery("SELECT c FROM Cards c");
return cardList;
public Card getCard(int cardId)
return em.find(Card.class, cardId);
【讨论】:
我可以将网页控制器自动连接到 CardDao 吗?我正在尝试您上面的建议。我忙于大学考试。我也在使用服务实现“CardServiceImpl”。 在笔记本电脑前花了很长时间后,我已经成功解决了我的问题。谢谢你。而且我没有使用实体管理器,我使用 sessionfactory 并在 DAO 下使用了您的方法以及 SERVICE 因此它起作用了!。 很高兴听到!你真的应该考虑使用实体管理器。它是 JPA 的标准组件。 Sessionsmanger 是特定于休眠的。我很高兴听到你解决了你的问题。摇滚吧!以上是关于需要使用hibernate dao实现方法保存不同jsp页面的两张表有外键关系的主要内容,如果未能解决你的问题,请参考以下文章