从零到一掌握MyBatis与JPA:企业级数据库操作实战全攻略

114 阅读7分钟

简介

在现代Java企业级开发中,ORM(对象关系映射)框架是简化数据库操作的核心工具。MyBatis与JPA作为两大主流ORM框架,分别以“半自动”和“全自动”的特性满足不同场景下的开发需求。本文将从零开始,通过完整的开发步骤、详细的代码示例和企业级实践案例,带你全面掌握MyBatis与JPA的核心技术。无论你是初学者还是进阶开发者,都能通过本文构建扎实的数据库操作能力,并掌握在实际项目中高效整合框架的技巧。


ORM框架的核心价值与选型策略

1. ORM框架的基本概念

ORM(Object-Relational Mapping)是一种将关系型数据库表与面向对象编程语言中的类进行映射的技术。通过ORM框架,开发者可以以面向对象的方式操作数据库,无需直接编写复杂的SQL语句。

1.1 ORM框架的优势

  • 降低代码复杂度:通过实体类与数据库表的映射,开发者只需关注业务逻辑,而无需手动处理SQL拼接和结果集映射。
  • 提高开发效率:ORM框架提供标准化的API,显著减少重复代码的编写。
  • 跨数据库兼容性:ORM框架通常支持多种数据库,减少数据库迁移成本。
  • 事务管理支持:框架内置事务管理功能,确保数据操作的一致性和完整性。

1.2 MyBatis与JPA的区别

特性MyBatisJPA
SQL控制需手动编写SQL语句自动生成JPQL(Java Persistence Query Language)
灵活性高,支持动态SQL和复杂查询中等,依赖注解和接口定义
学习曲线简单,适合中小型项目中等,需熟悉JPA规范
性能调优更灵活,可直接优化SQL依赖框架的查询优化能力

2. MyBatis实战:半自动化的数据库操作

2.1 MyBatis的快速入门

MyBatis是一款半自动化的ORM框架,通过XML或注解定义SQL语句,实现对数据库的灵活操作。

2.1.1 环境搭建
  1. 添加Maven依赖

    <dependencies>
        <!-- MyBatis核心依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.12</version>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
    </dependencies>
    
  2. 创建数据库表

    CREATE TABLE `user` (
      `id` BIGINT PRIMARY KEY AUTO_INCREMENT,
      `username` VARCHAR(50) NOT NULL,
      `password` VARCHAR(50) NOT NULL
    );
    
2.1.2 核心配置文件

创建 mybatis-config.xml 文件,配置数据库连接信息:

<?xml version="1.0" encoding="UTF-8" ?>
<!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">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mydb?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>
2.1.3 实体类与映射文件
  1. 实体类定义

    public class User {
        private Long id;
        private String username;
        private String password;
    
        // Getter和Setter方法
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
    
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
    
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
    
  2. 映射文件 UserMapper.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.mapper.UserMapper">
        <insert id="insertUser">
            INSERT INTO user (username, password) VALUES (#{username}, #{password})
        </insert>
    
        <select id="selectUserById" resultType="com.example.model.User">
            SELECT * FROM user WHERE id = #{id}
        </select>
    
        <update id="updateUser">
            UPDATE user SET username = #{username}, password = #{password} WHERE id = #{id}
        </update>
    
        <delete id="deleteUserById">
            DELETE FROM user WHERE id = #{id}
        </delete>
    </mapper>
    
2.1.4 核心代码实现
  1. 初始化SqlSessionFactory

    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
  2. 执行数据库操作

    public class MyBatisDemo {
        public static void main(String[] args) {
            try (SqlSession session = sqlSessionFactory.openSession()) {
                UserMapper mapper = session.getMapper(UserMapper.class);
    
                // 插入数据
                User newUser = new User();
                newUser.setUsername("admin");
                newUser.setPassword("123456");
                mapper.insertUser(newUser);
    
                // 查询数据
                User user = mapper.selectUserById(1L);
                System.out.println("User ID: " + user.getId());
                System.out.println("Username: " + user.getUsername());
    
                // 更新数据
                user.setPassword("654321");
                mapper.updateUser(user);
    
                // 删除数据
                mapper.deleteUserById(1L);
            }
        }
    }
    

2.2 MyBatis的高级特性

2.2.1 动态SQL

MyBatis支持通过 <if><choose><when> 等标签实现动态SQL查询。

<select id="selectUserByUsername" resultType="com.example.model.User">
    SELECT * FROM user
    <where>
        <if test="username != null">
            AND username LIKE CONCAT('%', #{username}, '%')
        </if>
    </where>
</select>
2.2.2 结果集映射

对于复杂查询,可以通过 <resultMap> 定义字段与实体类属性的映射关系。

<resultMap id="userResultMap" type="com.example.model.User">
    <id property="id" column="user_id"/>
    <result property="username" column="user_name"/>
    <result property="password" column="user_password"/>
</resultMap>

<select id="selectUserById" resultMap="userResultMap">
    SELECT user_id, user_name, user_password FROM user WHERE user_id = #{id}
</select>
2.2.3 分页查询

通过 RowBounds 实现分页查询:

public List<User> selectUsersByPage(int offset, int limit) {
    try (SqlSession session = sqlSessionFactory.openSession()) {
        UserMapper mapper = session.getMapper(UserMapper.class);
        return mapper.selectUsers(new RowBounds(offset, limit));
    }
}

3. JPA实战:全自动化的数据库操作

3.1 JPA的核心概念

JPA(Java Persistence API)是Java EE的一部分,提供了一套标准化的ORM接口。通过注解定义实体类与数据库表的映射关系,JPA会自动生成SQL语句并管理数据库操作。

3.2 JPA的快速入门

3.2.1 环境搭建
  1. 添加Maven依赖

    <dependencies>
        <!-- JPA核心依赖 -->
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>javax.persistence-api</artifactId>
            <version>2.2</version>
        </dependency>
        <!-- Hibernate作为JPA实现 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.6.0.Final</version>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
    </dependencies>
    
  2. 创建数据库表

    CREATE TABLE `user` (
      `id` BIGINT PRIMARY KEY AUTO_INCREMENT,
      `username` VARCHAR(50) NOT NULL,
      `password` VARCHAR(50) NOT NULL
    );
    
3.2.2 核心配置文件

创建 persistence.xml 文件,配置JPA的持久化单元:

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
    http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <class>com.example.model.User</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mydb?useSSL=false"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="123456"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>
3.2.3 实体类与注解定义
  1. 实体类定义
    @Entity
    @Table(name = "user")
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Column(name = "username", nullable = false)
        private String username;
    
        @Column(name = "password", nullable = false)
        private String password;
    
        // Getter和Setter方法
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
    
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
    
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
    
3.2.4 核心代码实现
  1. 初始化EntityManagerFactory

    Map<String, Object> properties = new HashMap<>();
    properties.put("javax.persistence.jdbc.url", "jdbc:mysql://localhost:3306/mydb?useSSL=false");
    properties.put("javax.persistence.jdbc.user", "root");
    properties.put("javax.persistence.jdbc.password", "123456");
    properties.put("javax.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
    properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
    
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPersistenceUnit", properties);
    
  2. 执行数据库操作

    public class JpaDemo {
        public static void main(String[] args) {
            EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPersistenceUnit");
            EntityManager em = emf.createEntityManager();
    
            // 插入数据
            User newUser = new User();
            newUser.setUsername("admin");
            newUser.setPassword("123456");
            em.getTransaction().begin();
            em.persist(newUser);
            em.getTransaction().commit();
    
            // 查询数据
            User user = em.find(User.class, 1L);
            System.out.println("User ID: " + user.getId());
            System.out.println("Username: " + user.getUsername());
    
            // 更新数据
            user.setPassword("654321");
            em.getTransaction().begin();
            em.merge(user);
            em.getTransaction().commit();
    
            // 删除数据
            em.getTransaction().begin();
            em.remove(user);
            em.getTransaction().commit();
    
            em.close();
            emf.close();
        }
    }
    

3.3 JPA的高级特性

3.3.1 JPQL查询

JPA支持通过JPQL(Java Persistence Query Language)进行查询操作:

public List<User> findUsersByUsername(String username) {
    EntityManager em = emf.createEntityManager();
    TypedQuery<User> query = em.createQuery(
        "SELECT u FROM User u WHERE u.username LIKE :username", User.class
    );
    query.setParameter("username", "%" + username + "%");
    return query.getResultList();
}
3.3.2 关联映射

JPA支持一对多、多对一等关联关系的映射。例如,定义用户与订单的关联:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username", nullable = false)
    private String username;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Order> orders = new ArrayList<>();

    // Getter和Setter方法
}

@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    // Getter和Setter方法
}
3.3.3 乐观锁与版本控制

通过 @Version 注解实现乐观锁,防止并发修改冲突:

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username", nullable = false)
    private String username;

    @Version
    private Integer version;

    // Getter和Setter方法
}

4. 企业级开发中的MyBatis与JPA整合

4.1 Spring Boot整合MyBatis

4.1.1 添加Spring Boot依赖
<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- MyBatis Spring Boot Starter -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.3.0</version>
    </dependency>
    <!-- MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.29</version>
    </dependency>
</dependencies>
4.1.2 配置数据源

application.properties 中配置数据源:

spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
4.1.3 创建Mapper接口
@Mapper
public interface UserMapper {
    @Insert("INSERT INTO user (username, password) VALUES (#{username}, #{password})")
    void insertUser(User user);

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

    @Update("UPDATE user SET username = #{username}, password = #{password} WHERE id = #{id}")
    void updateUser(User user);

    @Delete("DELETE FROM user WHERE id = #{id}")
    void deleteUserById(Long id);
}
4.1.4 创建Service层
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public void addUser(User user) {
        userMapper.insertUser(user);
    }

    public User getUserById(Long id) {
        return userMapper.selectUserById(id);
    }

    public void updateUser(User user) {
        userMapper.updateUser(user);
    }

    public void deleteUserById(Long id) {
        userMapper.deleteUserById(id);
    }
}
4.1.5 创建Controller层
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<String> createUser(@RequestBody User user) {
        userService.addUser(user);
        return ResponseEntity.ok("User created successfully");
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }

    @PutMapping("/{id}")
    public ResponseEntity<String> updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        userService.updateUser(user);
        return ResponseEntity.ok("User updated successfully");
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<String> deleteUser(@PathVariable Long id) {
        userService.deleteUserById(id);
        return ResponseEntity.ok("User deleted successfully");
    }
}

4.2 Spring Boot整合JPA

4.2.1 添加Spring Boot依赖
<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Spring Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.29</version>
    </dependency>
</dependencies>
4.2.2 配置数据源

application.properties 中配置数据源:

spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
4.2.3 创建Repository接口
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByUsernameContaining(String username);
}
4.2.4 创建Service层
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public void addUser(User user) {
        userRepository.save(user);
    }

    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    public List<User> getUsersByUsername(String username) {
        return userRepository.findByUsernameContaining(username);
    }

    public void updateUser(User user) {
        userRepository.save(user);
    }

    public void deleteUserById(Long id) {
        userRepository.deleteById(id);
    }
}
4.2.5 创建Controller层
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<String> createUser(@RequestBody User user) {
        userService.addUser(user);
        return ResponseEntity.ok("User created successfully");
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }

    @GetMapping("/search")
    public ResponseEntity<List<User>> searchUsers(@RequestParam String username) {
        List<User> users = userService.getUsersByUsername(username);
        return ResponseEntity.ok(users);
    }

    @PutMapping("/{id}")
    public ResponseEntity<String> updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        userService.updateUser(user);
        return ResponseEntity.ok("User updated successfully");
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<String> deleteUser(@PathVariable Long id) {
        userService.deleteUserById(id);
        return ResponseEntity.ok("User deleted successfully");
    }
}

总结

ORM框架是Java企业级开发中不可或缺的工具。MyBatis以其灵活性和高性能,适合需要精细控制SQL的场景;JPA则通过标准化接口和自动化操作,适合快速开发和维护。通过本文的详细讲解和代码示例,你已经掌握了从零开始搭建MyBatis与JPA项目的方法,并了解了如何在企业级开发中整合这些框架。无论是小型项目还是大型系统,ORM框架都能显著提升开发效率和代码质量。现在,动手实践吧!