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/Hibernate | MyBatis | MyBatis-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方法名自动生成查询
📝 发现内容有误?点击此处直接编辑