需要使用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@AutowiredPersistenceContext

所以一个快速简单的解释。 @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页面的两张表有外键关系的主要内容,如果未能解决你的问题,请参考以下文章

java - 如何在Java Spring和Hibernate的单个事务中管理2个DAO方法?

SSH框架整合中Hibernate实现Dao层常用结构

为 Hibernate 创建一个通用的 DAO 类

DAO、Spring 和 Hibernate

Spring 对 DAO 的支持

Hibernate 干货