learn/framework

ORM (Object-Relational Mapping)

사겅이 2023. 9. 22. 05:35

 

객체와 관계형 데이터베이스 간의 매핑을 자동화하는 프로그래밍 기법

개발자가 직접 SQL 쿼리를 작성하지 않고도 객체 지향 코드에서 관계형 데이터베이스에 접근

 

  • 객체-관계 매핑: ORM은 개체와 테이블 간의 매핑을 제공합니다. 클래스를 테이블로, 객체를 레코드로, 속성을 열로 매핑하여 개체 모델과 데이터베이스 스키마 간의 일치를 달성
  • CRUD 작업: ORM은 생성(Create), 조회(Read), 갱신(Update), 삭제(Delete) 작업에 대한 추상화 계층을 제공하여 개발자가 데이터베이스와 상호작용할 때 객체 지향적인 인터페이스를 사용할 수 있도록 함
  • 지연 로딩 및 즉시 로딩: ORM은 연관된 객체들을 필요한 시점에 로드하는 지연 로딩(Lazy Loading)과 한 번에 모든 연관된 객체들을 즉시 로드하는 즉시 로딩(Eager Loading) 기능을 제공합니다.
  • 캐싱: ORM은 자주 액세스되는 데이터나 쿼리 결과를 메모리 내의 캐시에 저장하여 성능 향상
  • 트랜잭션 관리: ORM은 트랜잭션 관리 기능을 제공하여 일관된 상태 유지와 데이터베이스 변경의 원자성 보장 등과 같은 ACID 원칙을 준수

 

Hibernate

  • Mapping Class
<!-- pom.xml -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.5.7.Final</version> <!-- 사용하는 Hibernate 버전에 맞게 변경 -->
</dependency>
<!-- hibernate.cfg.xml -->
<hibernate-configuration>
<session-factory>
<!-- 데이터베이스 연결 정보 설정 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>

<!-- Hibernate Dialect 설정 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- 매핑 클래스 설정 -->
<mapping class="com.example.User"/>
</session-factory>
</hibernate-configuration>
@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "username")
    private String username;

    @Column(name = "email")
    private String email;

    // 생성자, getter 및 setter 메서드
}
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Main {

    public static void main(String[] args) {
        // Hibernate 설정 로드
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");

        try (SessionFactory sessionFactory = configuration.buildSessionFactory()) {
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();

            try {
                // Create operation
                Employee employee1 = new Employee();
                employee1.setFirstName("John");
                session.save(employee1);

                Long employee2ID =(Long ) session.save(employee2);
                session.flush(); // 변경 내용 반영

                // Read operation
                Employee savedEmployee= session.get(Employee.class, employee2ID );
                System.out.println(savedEmployee.getFirstName());

                // Update operation
                savedEmployee.setFirstName("Jane");
                session.update(savedEmployee);
                session.flush(); // 변경 내용 반영

                // Delete operation
                session.delete(savedEmployee);
                session.flush(); // 변경 내용 반영
            } catch(Exception e){
                transaction.rollback();
                e.printStackTrace();

            }
        }
    }
}

 

  • Mapping File
<!-- hibernate.cfg.xml -->

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

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
        <property name="connection.username">your_username_here</property>
        <property name="connection.password">your_password_here</property>

        <!-- Mapping file -->
        <mapping resource="Employee.hbm.xml"/>

    </session-factory>

</hibernate-configuration>
public class Employee {
    private Long id;
    private String firstName;
    private String lastName;

    // Getters and setters

}
<!-- Employee.hbm.xml -->

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.example.model">

    <class name="Employee" table="employees">
        <id name="id" column="employee_id">
            <generator class="native"/>
        </id>
        <property name="firstName" column="first_name"/>
        <property name="lastName" column="last_name"/>
    </class>

</hibernate-mapping>
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Main {

    public static void main(String[] args) {
        // Hibernate 설정 로드
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");

        try (SessionFactory sessionFactory = configuration.buildSessionFactory()) {
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();

            try {
                // Create operation
                Employee employee1 = new Employee();
                employee1.setFirstName("John");
                employee1.setLastName("Doe");

                Long employeeId = (Long) session.save(employee1);
                System.out.println("Employee ID: " + employeeId);

                // Read operation
                Employee savedEmployee = session.get(Employee.class, employeeId);
                System.out.println("First Name: " + savedEmployee.getFirstName());
                System.out.println("Last Name: " + savedEmployee.getLastName());

                // Update operation
                savedEmployee.setFirstName("Jane");

                session.update(savedEmployee);

            } catch (Exception e) {
                transaction.rollback();
                e.printStackTrace();
            }
        }
    }
}

 

iBatis

  • Mapping file
<!-- pom.xml -->

<dependencies>
    <!-- iBATIS Core -->
    <dependency>
        <groupId>org.apache.ibatis</groupId>
        <artifactId>ibatis-core</artifactId>
        <version>3.0.6</version>
    </dependency>

    <!-- Oracle JDBC Driver -->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>{ojdbc_version}</version>
    </dependency>
</dependencies>
public class Employee {
    private Long id;
    private String firstName;
    private String lastName;

    // Getters and setters

}
<!-- Employee.xml -->

<!DOCTYPE mapper PUBLIC "-//iBATIS.com//DTD Mapper 3.0//EN"
        "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.example.dao.EmployeeDao">

    <!-- CREATE -->
    <insert id="createEmployee" parameterType="com.example.model.Employee">
        INSERT INTO employees (employee_id, first_name, last_name)
        VALUES (#{id}, #{firstName}, #{lastName})
    </insert>

    <!-- READ -->
    <select id="getEmployeeById" parameterType="java.lang.Long" resultType="com.example.model.Employee">
        SELECT * FROM employees WHERE employee_id = #{id}
    </select>

    <!-- UPDATE -->
    <update id="updateEmployee" parameterType="com.example.model.Employee">
        UPDATE employees SET first_name = #{firstName}, last_name = #{lastName}
        WHERE employee_id = #{id}
    </update>

    <!-- DELETE -->
    <delete id="deleteEmployeeById" parameterType="java.lang.Long">
        DELETE FROM employees WHERE employee_id = #{id}
    </delete>

</mapper>
public interface EmployeeDao {
    void createEmployee(Employee employee);
    Employee getEmployeeById(Long id);
    void updateEmployee(Employee employee);
    void deleteEmployeeById(Long id);
}
public class EmployeeDaoImpl implements EmployeeDao {
    private SqlSessionFactory sqlSessionFactory;

    public EmployeeDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public void createEmployee(Employee employee) {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            session.insert("com.example.dao.EmployeeDao.createEmployee", employee);
            session.commit();
        }
    }

    @Override
    public Employee getEmployeeById(Long id) {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            return session.selectOne("com.example.dao.EmployeeDao.getEmployeeById", id);
        }
    }

    @Override
    public void updateEmployee(Employee employee) {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            session.update("com.example.dao.EmployeeDao.updateEmployee", employee);
            session.commit();
        }
    }

    @Override
    public void deleteEmployeeById(Long id) {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            session.delete("com.example.dao.EmployeeDao.deleteEmployeeById", id);
            session.commit();
        }
    }
}
<!-- mybatis-config.xml -->

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- Database connection settings -->
                <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
                <property name="username" value="{your_username_here}"/>
                <property name="password" value="{your_password_here}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- Mappers -->
    <mappers>
        <mapper resource="Employee.xml"/>
    </mappers>

</configuration>
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class Main {

    public static void main(String[] args) {
        try {
            // MyBatis 설정 파일 로드
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            // EmployeeDao 인스턴스 생성
            EmployeeDao employeeDao = new EmployeeDaoImpl(sqlSessionFactory);

            // 데이터 생성
            Employee employee1 = new Employee();
            employee1.setId(1L);
            employee1.setFirstName("John");
            employee1.setLastName("Doe");
            employeeDao.createEmployee(employee1);

            // 데이터 조회
            Long employeeId = 1L;
            Employee employee = employeeDao.getEmployeeById(employeeId);
            System.out.println("First Name: " + employee.getFirstName());
            System.out.println("Last Name: " + employee.getLastName());

            // 데이터 갱신
            employee.setFirstName("Jane");
            employeeDao.updateEmployee(employee);

            // 데이터 삭제
            employeeDao.deleteEmployeeById(employeeId);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

MyBatis

  • Mapping file
<!-- pom.xml -->

<dependencies>
    <!-- MyBatis Core -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>

    <!-- Oracle JDBC Driver -->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>{ojdbc_version}</version>
    </dependency>
</dependencies>
public class Employee {
    private Long id;
    private String firstName;
    private String lastName;

    // Getters and setters

}
public interface EmployeeMapper {

    // CREATE
    void createEmployee(Employee employee);

    // READ
    Employee getEmployeeById(Long id);

    // UPDATE
    void updateEmployee(Employee employee);

    // DELETE
    void deleteEmployeeById(Long id);
}
<!-- EmployeeMapper.xml -->

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.dao.EmployeeMapper">

    <!-- CREATE -->
    <insert id="createEmployee" parameterType="com.example.model.Employee">
        INSERT INTO employees (employee_id, first_name, last_name)
        VALUES (#{id}, #{firstName}, #{lastName})
    </insert>

    <!-- READ -->
    <select id="getEmployeeById" parameterType="java.lang.Long" resultType="com.example.model.Employee">
        SELECT * FROM employees WHERE employee_id = #{id}
    </select>

    <!-- UPDATE -->
    <update id="updateEmployee" parameterType="com.example.model.Employee">
        UPDATE employees SET first_name = #{firstName}, last_name = #{lastName}
        WHERE employee_id = #{id}
    </update>

    <!-- DELETE -->
    <delete id="deleteEmployeeById" parameterType="java.lang.Long">
        DELETE FROM employees WHERE employee_id = #{id}
    </delete>

</mapper>
<!-- mybatis-config.xml -->

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- Database connection settings -->
                <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="{jdbc_url}"/>
                <property name="username" value="{username}"/>
                <property name="password" value="{password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- Mappers -->
    <mappers>
        <mapper resource="{path_to_mapper_xml_file}/EmployeeMapper.xml"/>
    </mappers>

</configuration>
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class Main {

    public static void main(String[] args) {
        try {
            // MyBatis 설정 파일 로드
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            // SqlSession 생성
            try (SqlSession session = sqlSessionFactory.openSession()) {
                // Mapper 인스턴스 생성
                EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);

                // 데이터 생성
                Employee employee1 = new Employee();
                employee1.setId(1L);
                employee1.setFirstName("John");
                employee1.setLastName("Doe");
                employeeMapper.createEmployee(employee1);

                // 데이터 조회
                Long employeeId = 1L;
                Employee employee = employeeMapper.getEmployeeById(employeeId);

                System.out.println("First Name: " + employee.getFirstName());
                System.out.println("Last Name: " + employee.getLastName());

                // 데이터 갱신
                employee.setFirstName("Jane");
                employeeMapper.updateEmployee(employee);

                // 데이터 삭제
                employeeMapper.deleteEmployeeById(employeeId);


            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

'learn > framework' 카테고리의 다른 글

Spring  (0) 2023.09.22
Struts  (0) 2023.09.22