应用程序创建数据库,但不创建表

时间:2014-05-08 00:19:28

标签: java spring hibernate postgresql

在我的spring项目中,我正在寻找一种方法来创建数据库,我的应用程序将使用它来避免最终用户手动创建它。

我有这个服务类,我想实现这个功能:

@Service
public class InstallService {

    public boolean create_database(String maquina, String usuario, String senha) {
        return false;
    }

    public boolean create_user(String usuario, String senha, String email) {
        return false;
    }
}

在网上搜索,我在stackoverflow中找到了这个主题,并建议为mysql执行此操作:

creating a database in mysql from java

在我的应用程序中,数据库是通过向导中的一个步骤创建的,其中用户通知机器运行DBMS的位置,以及将拥有数据库的用户名和密码。

另外,我使用的是Hibernate,然后jdbc驱动程序和db名称已存储在名为persistence.properties的文件中,该文件包含以下内容:

jdbc.Classname=org.postgresql.Driver
jdbc.url=
jdbc.user=
jdbc.pass=
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=update

用户通知机器,用户名和密码数据后,我也希望将此数据保存在此文件中。

任何人都可以指出如何修改其他主题中的示例以实现我想要的目标吗?

ps:项目是这样的:

https://github.com/klebermo/webapp_horario_livre

更新

我当前的代码(仍然没有创建数据库):

@Service
public class InstallService {

    @Autowired
    UsuarioHome usuario;

    @Autowired
    AutorizacaoHome autorizacao;

    public boolean create_database(String maquina, String usuario, String senha) {
        Configuration config = new Configuration();
        config.setProperty("jdbc.Classname", "org.postgresql.Driver");
        config.setProperty("jdbc.url", "jdbc:postgresql://"+maquina+"/horario?charSet=LATIN1");
        config.setProperty("jdbc.user", usuario);
        config.setProperty("jdbc.pass", senha);
        config.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        config.setProperty("hibernate.show_sql", "false");
        config.setProperty("hibernate.hbm2ddl.auto", "create");

        SchemaExport schema = new SchemaExport(config);
        schema.create(true, true);

        Properties properties = new Properties();
        properties.setProperty("jdbc.Classname", "org.postgresql.Driver");
        properties.setProperty("jdbc.url", "jdbc:postgresql://"+maquina+"/horario?charSet=LATIN1");
        properties.setProperty("jdbc.user", usuario);
        properties.setProperty("jdbc.pass", senha);
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        properties.setProperty("hibernate.show_sql", "false");
        properties.setProperty("hibernate.hbm2ddl.auto", "validate");

        try {
            File file = new File("classpath:database.properties");
            FileOutputStream fileOut = new FileOutputStream(file);
            properties.store(fileOut, "propriedades");
            fileOut.close();
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        }

        return autorizacao.persist(new Autorizacao("permissao_teste"));
    }

    public boolean create_user(String login, String senha, String pnome, String unome) {
        Usuario novo = new Usuario(login, senha, pnome, unome);
        novo.setAutorizacao(autorizacao.findALL());
        return usuario.persist(novo);
    }
}

更新2

我当前的代码(创建数据库,但不创建表):

@Service
public class InstallService {

    @Autowired
    private UsuarioHome usuario;

    @Autowired
    private AutorizacaoHome autorizacao;

    public boolean create_database(String maquina, String usuario, String senha) {
        try {
            Class.forName("org.postgresql.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("ClassNotFoundException");
        }
        try {
            String url = "jdbc:postgresql://"+maquina+"/postgres";
            System.out.println("url = "+url);
            System.out.println("usuario = "+usuario);
            System.out.println("senha = "+senha);
            Connection conn = DriverManager.getConnection(url,usuario,senha);
            Statement stmt = conn.createStatement();

            ResultSet rs = stmt.executeQuery("SELECT count(*) FROM pg_catalog.pg_database WHERE datname = 'horario';");
            rs.next();
            int counter  = rs.getInt(1);
            System.out.println("counter = "+counter);
            if(counter > 0) {
                System.out.println("calling_create_tables");
                create_tables(maquina, usuario, senha);
                rs.close();
                stmt.close();
                conn.close();
                return true;
            }

            int result = stmt.executeUpdate("CREATE DATABASE horario WITH OWNER "+usuario+";");
            System.out.println("result = "+result);
            if(result > 0) {
                System.out.println("calling_create_tables");
                create_tables(maquina, usuario, senha);
                rs.close();
                stmt.close();
                conn.close();
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("SQLException");
            return false;
        }
        System.out.println("retornando false");
        return false;
    }

    public void create_tables(String maquina, String usuario, String senha) {
        System.out.println("create_tables");
        create_properties(maquina, usuario, senha);

        Configuration config = new Configuration();
        Properties props = new Properties();
        FileInputStream fos;
        try {
            fos = new FileInputStream( "database.properties" );
            props.load(fos);
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        config.setProperties(props);

        try {
            String url = props.getProperty("jdbc.url");
            Connection conn = DriverManager.getConnection(url,usuario,senha);
            SchemaExport schema = new SchemaExport(config, conn);
            schema.create(true, true);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        insert_default_values();
    }

    public void insert_default_values() {
        System.out.println("insert_default_values");
        String [] autorizacoes = {"cad_evento", "lista_evento", "cad_horario", "lista_horario", "cad_usuario", "lista_usuario", "cad_campo", "cad_tipo", "cad_permissao"};
        for(int i=0; i<autorizacoes.length; i++) {
            autorizacao.persist(new Autorizacao(autorizacoes[i]));
        }
    }

    public void create_properties(String maquina, String usuario, String senha) {
        System.out.println("create_properties");
        Properties props = new Properties();

        props.setProperty("jdbc.Classname", "org.postgresql.Driver");
        props.setProperty("jdbc.url", "jdbc:postgresql://"+maquina+"/horario" );
        props.setProperty("jdbc.user", usuario );
        props.setProperty("jdbc.pass", senha );

        props.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        props.setProperty("hibernate.show_sql", "false");
        props.setProperty("hibernate.hbm2ddl.auto", "update");

        FileOutputStream fos;
        try {
            fos = new FileOutputStream( "database.properties" );
            props.store( fos, "propriedades" );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean create_user(String login, String senha, String pnome, String unome) {
        System.out.println("create_user");
        Usuario novo = new Usuario(login, senha, pnome, unome);

        if(usuario.persist(novo))
            novo.setAutorizacao(autorizacao.findALL());
        else
            return false;

        if(usuario.merge(novo) != null)
            return true;
        else
            return false;
    }
}

2 个答案:

答案 0 :(得分:0)

在您设置配置之后但在创建会话之前,以下几行将为您创建数据库:

SchemaExport schema = new SchemaExport(config);
schema.create(true, true);

或者,将hibernate.hbm2ddl.auto属性设置为create-drop或create。后者创建数据库表,前者在退出后删除它们。

<强>更新

您的编辑不起作用 - 请参阅任何hibernate教程,了解如何正确执行此操作。但是,这是一个可以做你想做的黑客攻击:

   Connection conn1 = DriverManager.getConnection("jdbc:postgresql://"+maquina+"/template1??charSet=LATIN1", usario, senha);
   conn1.createStatement().execute("CREATE DATABASE horario");
   conn1.close(); 

在声明属性之后但在建立连接之前,您将这些行放入。

更新#2

您应该在单独的配置文件中设置属性。默认情况下,hibernate在类路径的根目录中查找名为hibernate.cfg.xml的文件。它应该看起来像

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
        <property name="hibernate.connection.username">postgres</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/hibernatedb</property>
        <property name="connection_pool_size">1</property>
        <property name="hbm2ddl.auto">create-drop</property>
        <property name="show_sql">true</property>
    </session-factory>
</hibernate-configuration>

要加载此文件,假设它处于默认名称和位置:

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
/**
* Hibernate Utility class with a convenient method to get Session Factory object.
*
* @author hd1
*/
public class HibernateUtil {
   private static final SessionFactory sessionFactory;

   static {
      try {
         // Create the SessionFactory from standard (hibernate.cfg.xml)
         // config file.
         sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
      } catch (Throwable ex) {
         // Log the exception.
         System.err.println("Initial SessionFactory creation failed." + ex);
         throw new ExceptionInInitializerError(ex);
      }

    }

    public static SessionFactory getSessionFactory() {
       return sessionFactory;
    }
}

希望有帮助...

答案 1 :(得分:0)

好的,最后我完成了我的目标,现在正在创建数据库和表。 create_tables()方法的最终代码是:

public void create_tables(String maquina, String usuario, String senha) {
    System.out.println("create_tables");
    create_properties(maquina, usuario, senha);

    Configuration config = new Configuration();
    Properties props = new Properties();
    FileInputStream fos;
    try {
        fos = new FileInputStream( "database.properties" );
        props.load(fos);
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    config.setProperties(props);

    config.addAnnotatedClass(com.horariolivre.entity.Atributo.class);
    config.addAnnotatedClass(com.horariolivre.entity.ConfigHorarioLivre.class);
    config.addAnnotatedClass(com.horariolivre.entity.Evento.class);
    config.addAnnotatedClass(com.horariolivre.entity.HorarioLivre.class);
    config.addAnnotatedClass(com.horariolivre.entity.Key.class);
    config.addAnnotatedClass(com.horariolivre.entity.Tipo.class);
    config.addAnnotatedClass(com.horariolivre.entity.Value.class);
    config.addAnnotatedClass(com.horariolivre.entity.Autorizacao.class);
    config.addAnnotatedClass(com.horariolivre.entity.Usuario.class);

    try {
        String url = props.getProperty("jdbc.url");
        Connection conn = DriverManager.getConnection(url,usuario,senha);
        SchemaExport schema = new SchemaExport(config, conn);
        schema.create(true, true);
    } catch (SQLException e) {
        e.printStackTrace();
    }

    insert_default_values();
}