• Как сделать ID для объектов?

    @nubus4000
    Можно использовать такой говнокод. Смысл - создавать класс на лету, если у него нет поля id или его нельзя нормально сравнить по equals и hashcode. Код надо подкрутить, он может не сработать. Писал на лету так сказать.

    import java.lang.reflect.*;
    import java.util.*;
    import java.util.concurrent.atomic.*;
    
    public class SimpleStorage {
    
        private Map<Integer, Object> objects = new HashMap<>();
        private AtomicInteger idGenerator = new AtomicInteger(0);
        private ClassMaker classMaker = new ClassMaker(0, null, null);
    
        private static final String[] EQUALS_NOT_SUPPORTED = {}; //указать имя классов, которые не поддерживают equals и hasCode
    
        public Integer getId(Object obj) {
            Object finalObj = obj;
            boolean isEqualsNotSupported = Arrays.stream(EQUALS_NOT_SUPPORTED)
                    .anyMatch(typeName -> finalObj.getClass().getCanonicalName().equalsIgnoreCase(typeName));
    
            if (isEqualsNotSupported) {
                final Integer id = getIdFromField(obj);
                return objects.entrySet()
                        .stream()
                        .filter(entry -> id.equals(entry.getValue()))
                        .map(Map.Entry::getKey)
                        .findFirst().get();
            }
    
            Object finalObj1 = obj;
            return objects.entrySet()
                    .stream()
                    .filter(entry -> finalObj1.equals(entry.getValue()))
                    .map(Map.Entry::getKey)
                    .findFirst().get();
        }
    
        public void add(Object obj) {
            Integer newId = idGenerator.incrementAndGet();
            obj = classMaker.createClassWithId(newId);
            objects.put(newId, obj);
        }
    
        public Object get(Integer id) {
            return objects.get(id);
        }
    
        private Integer getIdFromField(Object obj) {
            try {
                Field field = obj.getClass().getField(ClassMaker.FIELD_ID);
                field.setAccessible(true);
                return (Integer) field.get(obj);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                return null;
            }
        }
    
    }


    import java.io.*;
    import java.net.*;
    import java.util.*;
    import javax.tools.*;
    
    public class ClassMaker {
    
        public static final String FIELD_ID = "id";
    
        private Integer id = 0;
        private String className;
        private String sourceCode;
        private File sourceFile;
    
        public ClassMaker(Integer id, String className, String sourceCode) {
            this.id = id;
            this.className = className;
            this.sourceCode = sourceCode;
        }
    
        public Object createClassWithId(Integer id) {
            if (id != null)
                this.id = id;
    
            sourceCode = createSimpleString(id);
            Object obj = null;
            try (FileWriter writer = new FileWriter(createTmpFile())) {
                writer.write(sourceCode);
                compileClass();
                className = sourceFile.getName().split("\\.")[0];
                URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{sourceFile.getParentFile().toURI().toURL()});
                Class<?> newClass = classLoader.loadClass(className);
                obj = newClass.newInstance();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
                e.printStackTrace();
            }
            return obj;
        }
    
        private void compileClass() throws IOException {
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
            File parentDirectory = sourceFile.getParentFile();
            fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Collections.singletonList(parentDirectory));
            Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Collections.singletonList(sourceFile));
            compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
            fileManager.close();
        }
    
        private File createTmpFile() throws IOException {
            File sourceFile = File.createTempFile(className, ".java");
            sourceFile.deleteOnExit();
            this.sourceFile = sourceFile;
            return sourceFile;
        }
    
        private String createSimpleString(Integer id) {
            StringBuilder classBuilder = new StringBuilder();
            classBuilder.append("public class ")
                    .append(className)
                    .append(" {")
                    .append("private Integer id = ")
                    .append(id)
                    .append(";")
                    .append("    public void setId(Integer id) {\n")
                    .append("        this.id = id;\n").append("    }\n")
                    .append("\n").append("    public Integer getId() {\n")
                    .append("        return id;\n")
                    .append("    }").append("    @Override\n")
                    .append("    public boolean equals(Object o) {\n")
                    .append("        if (this == o) return true;\n")
                    .append("        if (o == null || getClass() != o.getClass()) return false;\n")
                    .append("\n")
                    .append(className)
                    .append(" that = ")
                    .append("(").append(className).append(")").append(" o;")
                    .append("\n")
                    .append("        return id != null ? id.equals(that.id) : that.id == null;\n")
                    .append("    }\n").append("\n").append("    @Override\n")
                    .append("    public int hashCode() {\n")
                    .append("        return id != null ? id.hashCode() : 0;\n")
                    .append("    }\n")
                    .append("}");
            return classBuilder.toString();
        }
    }


    А вообще странная задача - давать всем уникальные id. Откуда объекты берутся? Почему нельзя инкапсулировать всякие сеты и листы внутри пользовательских классов?
    Ответ написан
    Комментировать
  • Не происходит подключения к базе данных по URL?

    @nubus4000
    Попробуйте так. В папку META-INF, что в webapp, добавить context.xml с содержимым:
    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
    
        <Resource name="jdbc/est"
                  auth="Container"
                  type="javax.sql.DataSource"
                  maxActive="100" maxIdle="30" maxWait="10000"
                  username="root"
                  password="root"
                  driverClassName="com.mysql.jdbc.Driver"
                  url="jdbc:mysql://localhost/est?useEncoding=true&amp;characterEncoding=UTF-8"/>
    </Context>


    После сделайте класс DaoUtil и напишите туда это(и лучше его доработать, он перегружен всякими if и т.п.):
    public class DaoUtil {
    
        public static Connection getConnection(){
            Connection connection = null;
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            try {
                Context context = new InitialContext();
                Context initContext  = (Context )context.lookup("java:/comp/env");
                DataSource ds = (DataSource) initContext.lookup("jdbc/est");
                connection = ds.getConnection();
            }catch (SQLException | NamingException ex){
                ex.printStackTrace();
            }
            return connection;
        }
    
        public static void close(Statement statement, ResultSet rs,Connection connection){
            try {
    
                if (statement != null) {
                    statement.close();
                }
                if (rs != null) {
                    rs.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException ex){
                ex.printStackTrace();
            }
        }
    
    }


    Ну и в контроллере уже можно писать так:
    Connection connection = DaoUtil.getConnection();

    Ну и лучше работу с connection и всякими statement перенести в слой Dao.
    Ответ написан
    Комментировать