• Spring同时集成JPA与Mybatis


    @

    ORM

    • ORM的出现,使得关系型数据库映射成了对象;简单来说,有了ORM之后,JAVA程序员从面向JDBC编程转化成面向JAVA对象编程。

    在这里插入图片描述

    Spring ORM

    • Spring对ORM的解决方案主要体现在以下方面:

      1. 统一的资源管理方式与异常管理:Spring使用各种ORM框架,资源管理及使用方式都是统一的;同时Spring会将各个ORM框架的异常转译到Spring异常体系下。
      2. 统一的事务管理:Spring通过IoC和AOP技术,形成了事务管理抽象层,接管了各种ORM框架下的数据访问的事务管理。
    • 随着版本的升级,Spring核心包中对ORM的各种解决方案也越来越精炼。本文我们重点将介绍同时集成Spring Data JPAMybatis两个ORM框架。

    Spring ORM 同时集成JPA与Mybatis

    • 在同一个项目中一般只会单独集成Spring Data JPA,或者单独集成Mybatis。但两者也可以混合使用(一般没这个必要),本文为了更加深入探索Spring ,将通过一个DEMO应用两者的并展示相似点与不同之处。
    一、创建一个SpringBoot项目
    1. IntelliJ IDEA中创建新项目
      在这里插入图片描述
    2. 通过地址https://start.spring.io/初始化项目;
      在这里插入图片描述
    3. 指定项目通用信息:
      在这里插入图片描述
    4. 选择项目依赖Starter
      在这里插入图片描述
    5. 生成的项目结构:
      在这里插入图片描述
    二、建立用户信息登记表
    • 根据用户信息模型类,设计用户信息登录表
    DROP DATABASE IF EXISTS user_info;
    
    CREATE DATABASE user_info
    	DEFAULT CHARACTER SET utf8
    	DEFAULT COLLATE utf8_general_ci;
    
    use user_info;
    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for user
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user`  (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    SET FOREIGN_KEY_CHECKS = 1;
    
    

    在这里插入图片描述

    三、Web应用项目集成mysql
    • 增加依赖
     <!--Mysql依赖包-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
                <scope>runtime</scope>
            </dependency>
     <!-- 数据库连接池:druid数据源驱动 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
    
    • Spring数据源配置
    ###数据源配置
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        username: root
        password: root
        driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
        url: jdbc:log4jdbc:mysql://localhost:3306/user_info?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
    
    四、添加Spring Data JPA和Mybatis依赖
    <!--pom.xml-->
    		<!--Spring Data JPA-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
             <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.2</version>
            </dependency>
    
    五、添加数据表映射实体类
    /**
     * 用户类--映射表user
     *
     * @author zhuhuix
     */
    @Entity
    @Table(name="user_info")
    public class User implements Serializable {
        // 用户id
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        // 用户名
        @NotBlank(message = "用户名称不能为空")
        @Column(name="name")
        private String name;
        // 邮箱
        @Column(name="email")
        @Pattern(message ="邮箱格式不符", regexp = "^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$")
        private String email;
    
        public User(Long id, String name, String email) {
            this.id = id;
            this.name = name;
            this.email = email;
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    }
    
    六、创建数据接口层
    6.1 声明JPA接口
    • 借助Spring Data JPA,我们可以通过继承CrudRepository接口,快速定义应用的数据层。CrudRepository定义并实现了很多用于crud(创建、读取、更新、删除)操作的方法,我们根本就不用编写实现类!当应用启动的时候,Spring Data JPA会在运行期自动生成实现类。
    /**
     * 基于SpringMVC框架开发web应用--数据操作层
     */
    public interface UserRepository extends CrudRepository<User,Long> {
    
    }
    
    • CrudRepository的一些默认实现
    public interface CrudRepository<T, ID> extends Repository<T, ID> {
        <S extends T> S save(S var1);
    
        <S extends T> Iterable<S> saveAll(Iterable<S> var1);
    
        Optional<T> findById(ID var1);
    
        boolean existsById(ID var1);
    
        Iterable<T> findAll();
    
        Iterable<T> findAllById(Iterable<ID> var1);
    
        long count();
    
        void deleteById(ID var1);
    
        void delete(T var1);
    
        void deleteAll(Iterable<? extends T> var1);
    
        void deleteAll();
    }
    
    6.2 声明MyBatis接口
    • 虽然强大的Spring Data JPA已经帮我们封装了多种数据操作,但由于业务逻辑的复杂度及自定义 SQL的需求,我们仍然可以运用MyBatis框架完成ORM的处理。
    /**
     * mybatis数据层接口
     *
     */
    @Repository
    public interface UserMapper {
    
        // 自定义添加通过用户名称模糊查找用户信息
        List<User> findByName(String name);
        
    }
    
    • Mybatis Mapper映射
    <?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.demo.mybatis.UserMapper">
    	<!-- 自定义模糊查找 SQL -->
        <select id="findByName" resultType="com.example.demo.register.User">
            select * from user where name like concat('%',#{name},'%')
        </select>
    
    </mapper>
    
    • Spring添加MyBatis配置
      修改application.yml配置文件:定位mapper文件扫描路径
    #MyBatis扫描mapper文件配置
    mybatis:
      mapper-locations: classpath:mapper/*Mapper.xml
    

    在这里插入图片描述

    • 在启动类里加上注解用于给出需要扫描的mapper文件路径
    @SpringBootApplication
    @MapperScan(basePackages = "com.example.demo.register")
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    
    七、创建业务服务层
    • 创建UserService服务层直接调用由Spring Data JPAMybatis接口各自提供的数据操作方法,以实现用户信息的增删改查。
    /**
     * 调用Spring Data JPA和Mybatis接口进行业务处理
     */
    @Service
    public class UserService {
    
        // Spring Data JPA
        @Autowired
        private UserRepository userRepository;
        // Mybatis
        @Autowired
        private UserMapper userMapper;
    
        // 返回所有的用户
        public List<User> listUsers() {
            return (List<User>) userRepository.findAll();
        }
    
        // 保存用户
        public User saveUser(User user) {
            return userRepository.save(user);
        }
    
        // 删除用户
        public void deleteUser(Long id) {
            userRepository.deleteById(id);
        }
    
        // 查找用户
        public User findUser(Long id) {
            return userRepository.findById(id).get();
        }
    
        // 根据名称查找用户--Mybatis
        public List<User> searchUser(String name) {
            return userMapper.findByName(name);
        }
    
    }
    
    
    八、创建控制器
    • 控制器的主要职责是处理HTTP请求传递给视图以便于渲染浏览器展现。

    • SpirngMVC的请求注解

    注解 描述
    @RequestMapping 通用的请求
    @GetMapping 处理HTTP GET请示
    @PostMapping 处理HTTP POST请示
    @PutMapping 处理HTTP PUT请示
    @DeleteMapping 处理HTTP DELETE请示
    /**
     * 用户控制器
     */
    @RestController
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        private UserService userService;
    
        // 保存用户并返回到用户列表页面
        @PostMapping
        public ModelAndView saveUser(@Valid User user, Errors errors, Model model) {
            if (errors.hasErrors()) {
                model.addAttribute("user", user);
                if (errors.getFieldError("name") != null) {
                    model.addAttribute("nameError", errors.getFieldError("name").getDefaultMessage());
                }
                if (errors.getFieldError("email") != null) {
                    model.addAttribute("emailError", errors.getFieldError("email").getDefaultMessage());
                }
                return new ModelAndView("register", "userModel", model);
            }
            userService.saveUser(user);
            //重定向到list页面
            return new ModelAndView("redirect:/user");
        }
    
        // 获取用户操作表单页面
        @GetMapping("/form")
        public ModelAndView createForm(Model model, @RequestParam(defaultValue = "0") Long id) {
            if (id > 0) {
                model.addAttribute("user", userService.findUser(id));
            } else {
                model.addAttribute("user", new User());
            }
            return new ModelAndView("register", "userModel", model);
        }
    
        // 获取用户列表显示页面
        @GetMapping
        public ModelAndView list(Model model) {
            model.addAttribute("userList", userService.listUsers());
            return new ModelAndView("userlist", "userModel", model);
        }
    
        // 模糊查找输入页面
        @GetMapping("/index")
        public ModelAndView index(Model model) {
            model.addAttribute("user", new User());
            return new ModelAndView("index", "userModel", model);
        }
    
        // 查找提交并跳转用户列表
        @PostMapping("/search")
        public ModelAndView search(@ModelAttribute User user, Model model) {
            model.addAttribute("userList", userService.searchUser(user.getName()));
            return new ModelAndView("userlist", "userModel", model);
        }
    
        // 删除用户
        @RequestMapping(path = "/del")
        public ModelAndView del(@RequestParam(name = "id") Long id) {
            userService.deleteUser(id);
            return new ModelAndView("redirect:/user");
        }
    }
    
    
    九、设计视图模板
    9.1 设计一个用户列表的视图模板
    • Thymeleaf提供了一个属性th:each,它会迭代一个元素集合,为集合中的每个条目渲染HTML,我们可以利用这个属性,设计出用户的列表视图。
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"
          xmlns:layout="http://www.ultrag.net.nz/thymeleaf/layout"
    >
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    <h3>用户列表</h3>
    <div>
        <a th:href="@{/user/form}">创建用户</a>
        <a th:href="@{/user/index}">查找用户</a>
    </div>
    <table border="1">
        <thead>
        <tr>
            <td>ID</td>
            <td>邮箱</td>
            <td>名称</td>
            <td>操作</td>
        </tr>
        </thead>
        <tbody>
        <tr th:if="${userModel.userList.size()} eq 0">
            <td colspan="3">没有用户信息!</td>
        </tr>
        <tr th:each="user:${userModel.userList}">
            <td th:text="${user.id}"></td>
            <td th:text="${user.email}"></td>
            <td th:text="${user.name}"></td>
            <td><a th:href="@{/user/form(id=${user.id})}"> 修改 </a> <a th:href="@{/user/del(id=${user.id})}"> 删除 </a></td>
        </tr>
        </tbody>
    </table>
    </body>
    </html>
    
    9.2 设计一个提交用户信息的表单模板
    • 用户通过这个视图,录入名称与邮箱地址,提交保存新用户的信息。
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org"
          xmlns:layout="http://www.ultrag.net.nz/thymeleaf/layout"
    >
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    <h3>登记用户</h3>
    <form action="/users" th:action="@{/user}" method="POST" th:object="${userModel.user}">
        <input type="hidden" name="id" th:value="*{id}">
        名称:<br>
        <input type="text" name="name" th:value="*{name}">
        <br>
        邮箱:<br>
        <input type="text" name="email" th:value="*{email}">
        <input type="submit" value="提交" >
    </form>
    </body>
    </html>
    
    9.3 设计一个用户模糊查找页面模板
    <!-- index.html-->
    <!DOCTYPE html>
    <html  xmlns:th="http://www.thymeleaf.org" >
    <head>
         <meta charset="UTF-8"/>
         <title>Title</title>
    </head>
     <body>
    
         <h3>查找用户</h3>
         <form action="/users" th:action="@{/user/search}" method="POST" th:object="${userModel.user}">
             名称:<br>
             <input type="text" name="name" th:value="*{name}" >
             <br>
             <input type="submit" value="查询" >
         </form>
    
     </body>
     </html>
    
    十、运行应用
    • 到目前为止,我们已经开发了User用户类、JPA数据接口、Mybatis数据接口、UserService用户服务类、UserController控制器、用户列表视图模板、用户登记视图模板、用户模糊查找页面模板,接下来我们尝试启动程序,并进行操作测试。
      在这里插入图片描述
    10.1用户列表

    在这里插入图片描述

    10.2增加用户
    • 点击页面上的创建用户,登记新用户,并提交
      在这里插入图片描述
      在这里插入图片描述
    10.3查找用户

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    该web应用一切运行正常。


    我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1lslxkle78msp

  • 相关阅读:
    applycationContext.xml文件配置信息
    原生json的异步操作
    解析xm文件
    druid(德鲁伊)连接池的DataSourceUtils的写法及原生写法
    MYSQL的JDBCUtils的写法
    模拟服务器
    关于函数式接口
    浅谈树和二叉树
    &和&&的区别
    全排列问题(c语言实现)
  • 原文地址:https://www.cnblogs.com/zhuhuix/p/13475758.html
Copyright © 2020-2023  润新知