全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 10 分钟 ✍️ juanwangdev

ORM集成

Spring提供对JPA、Hibernate、MyBatis等ORM框架的集成支持。

JPA集成

配置

YAML
# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        format_sql: true
        dialect: org.hibernate.dialect.MySQL8Dialect
Java
@Configuration
@EnableJpaRepositories(basePackages = "com.example.repository")
public class JpaConfig {

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean em =
            new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("com.example.entity");

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);

        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "update");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
        em.setJpaProperties(properties);

        return em;
    }

    @Bean
    public PlatformTransactionManager transactionManager(
            EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory);
        return txManager;
    }
}

Entity定义

Java
@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 50)
    private String username;

    @Column(unique = true)
    private String email;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    @Version
    private Integer version;  // 乐观锁

    // Getter/Setter
}

Repository使用

Java
// Spring Data JPA Repository
public interface UserRepository extends JpaRepository<User, Long> {

    // 方法名查询
    User findByUsername(String username);

    List<User> findByAgeGreaterThan(int age);

    // @Query查询
    @Query("SELECT u FROM User u WHERE u.email LIKE %:domain")
    List<User> findByEmailDomain(@Param("domain") String domain);

    // 原生SQL
    @Query(value = "SELECT * FROM users WHERE status = ?1", nativeQuery = true)
    List<User> findByStatusNative(String status);

    // 更新查询
    @Modifying
    @Query("UPDATE User u SET u.status = :status WHERE u.id = :id")
    int updateStatus(@Param("id") Long id, @Param("status") String status);
}

MyBatis集成

配置

YAML
# application.yml
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.entity
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: true
Java
@Configuration
@MapperScan("com.example.mapper")
public class MyBatisConfig {

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setMapperLocations(
            new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/*.xml"));
        factoryBean.setTypeAliasesPackage("com.example.entity");

        org.apache.ibatis.session.Configuration config =
            new org.apache.ibatis.session.Configuration();
        config.setMapUnderscoreToCamelCase(true);
        factoryBean.setConfiguration(config);

        return factoryBean.getObject();
    }
}

Mapper定义

Java
@Mapper
public interface UserMapper {

    @Select("SELECT * FROM users WHERE id = #{id}")
    User findById(Long id);

    @Select("SELECT * FROM users WHERE username = #{username}")
    User findByUsername(String username);

    @Insert("INSERT INTO users(username, email) VALUES(#{username}, #{email})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(User user);

    @Update("UPDATE users SET username=#{username}, email=#{email} WHERE id=#{id}")
    int update(User user);

    @Delete("DELETE FROM users WHERE id = #{id}")
    int delete(Long id);

    // XML方式
    List<User> findByCondition(UserQuery query);
}

XML Mapper

XML
<!-- mapper/UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
    <resultMap id="userResultMap" type="User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="email" column="email"/>
    </resultMap>

    <select id="findByCondition" resultMap="userResultMap">
        SELECT * FROM users
        <where>
            <if test="username != null">
                AND username LIKE #{username}
            </if>
            <if test="minAge != null">
                AND age >= #{minAge}
            </if>
        </where>
    </select>

    <insert id="batchInsert">
        INSERT INTO users(username, email) VALUES
        <foreach collection="list" item="user" separator=",">
            (#{user.username}, #{user.email})
        </foreach>
    </insert>
</mapper>

MyBatis-Plus集成

Java
@Configuration
@MapperScan("com.example.mapper")
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

// Entity
@Data
@TableName("users")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String username;
    private String email;
}

// Mapper继承BaseMapper
public interface UserMapper extends BaseMapper<User> {
    // 自动拥有 CRUD 方法
}

// Service继承ServiceImpl
@Service
public class UserService extends ServiceImpl<UserMapper, User> {
    // 自动拥有 CRUD 方法
}

事务管理

Java
@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public Order createOrder(Long userId, OrderRequest request) {
        User user = userRepository.findById(userId)
            .orElseThrow(() -> new RuntimeException("用户不存在"));

        Order order = new Order();
        order.setUser(user);
        order.setAmount(request.getAmount());

        return orderRepository.save(order);
    }

    @Transactional(readOnly = true)
    public List<Order> getUserOrders(Long userId) {
        return orderRepository.findByUserId(userId);
    }
}

ORM框架对比

特性JPA/HibernateMyBatisMyBatis-Plus
SQL控制自动生成手写SQL自动+手写
学习曲线较陡较平缓中等
灵活性中等
性能优化较复杂简单简单
复杂查询较弱

多ORM共存

Java
@Configuration
@EnableJpaRepositories(basePackages = "com.example.jpa.repository")
@MapperScan("com.example.mybatis.mapper")
public class MultiOrmConfig {

    // JPA事务管理器
    @Bean
    @Primary
    public PlatformTransactionManager jpaTransactionManager(
            EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }

    // MyBatis事务管理器
    @Bean
    public PlatformTransactionManager mybatisTransactionManager(
            DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

要点总结

  • JPA使用@Entity/@Table定义实体,Repository继承JpaRepository
  • MyBatis使用@Mapper接口+XML或注解SQL
  • MyBatis-Plus提供BaseMapper简化CRUD
  • Spring统一事务管理,@Transactional适用所有ORM
  • JPA适合简单CRUD,MyBatis适合复杂SQL
  • Spring Data JPA方法名自动生成查询

📝 发现内容有误?点击此处直接编辑

← 上一篇 JdbcTemplate使用
下一篇 → 数据源配置
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库