美文网首页SpringBoot专题
SpringBoot入门建站全系列(五)使用Spring-dat

SpringBoot入门建站全系列(五)使用Spring-dat

作者: 逍遥天扬 | 来源:发表于2019-05-23 12:37 被阅读7次

    SpringBoot入门建站全系列(五)使用Spring-data-jpa操作数据库

    SpringBoot操作数据库有多种方式,如

    JDBC直接操作:太古老了,没人愿意这样玩

    Mybatis插件:比较时髦,比较适合sql复杂,或者对性能要求高的应用,因为sql都是自己写的。

    Spring-data-jpa: 使用hibernate作为实现,基本上不需要写sql,因为sql都是统计的,总是会产生多余的查询,性能上相对而言会低,但不绝对,影响性能的因素是多种的,这里说的性能是 从最终的查询的sql来对比的,毕竟生成的sql没有经过深思熟虑写出来的性能好。

    JdbcTemplate:spring在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。Spring-data-jpa引入的时候,JdbcTemplate必然会被引入的。

    当然还有其他中间件,主流使用的就是Mybatis和Spring-data-jpa。

    品茗IT-SpringBoot专题-同步发布

    品茗IT 提供在线支持:

    一键快速构建Spring项目工具

    一键快速构建SpringBoot项目工具

    一键快速构建SpringCloud项目工具

    一站式Springboot项目生成

    Mysql一键生成Mybatis注解Mapper

    一、引入依赖

    需要同时引入数据库的connector和数据源datasource。和使用mybatis一样,只需要替换Mybatis引入的jar依赖即可。

    依赖如下:

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
    </dependency>
    

    完整的依赖如下所示:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.pomit</groupId>
        <artifactId>testjpa</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
        </parent>
        <name>testjpa</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-dbcp2</artifactId>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    
    

    二、配置数据库连接信息

    server.port=8080
    
    spring.application.name=pomit
    
    spring.datasource.driverClassName = com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/boot?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    spring.datasource.username=cff
    spring.datasource.password=123456
    
    spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
    spring.datasource.dbcp2.max-wait-millis=60000
    spring.datasource.dbcp2.min-idle=20
    spring.datasource.dbcp2.initial-size=2
    spring.datasource.dbcp2.validation-query=SELECT 1
    spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
    spring.datasource.dbcp2.validation-query=SELECT 1
    spring.datasource.dbcp2.test-while-idle=true
    spring.datasource.dbcp2.test-on-borrow=true
    spring.datasource.dbcp2.test-on-return=false
    
    #JPA Configuration:  
    spring.jpa.database=MySQL
    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto=none
    spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
    spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
    
    

    这里面,包含了数据库连接信息、数据源的连接池配置信息、jpa配置信息。

    spring.jpa.hibernate.ddl-auto属性,是对表的操作:

    • create 启动时删数据库中的表,然后创建,退出时不删除数据表
    • create-drop 启动时删数据库中的表,然后创建,退出时删除数据表 如果表不存在报错
    • update 如果启动时表格式不一致则更新表,原有数据保留
    • validate 项目启动表结构进行校验 如果不一致则报错
    • none 啥都不做

    spring.jpa.hibernate.naming.implicit-strategy和spring.jpa.hibernate.naming.physical-strategy是对表和实体字段映射的默认处理方式。

    实体名称映射到数据库中时,分成两个步骤:

    • 第一个阶段是从对象模型中提取一个合适的逻辑名称,这个逻辑名称可以由用户指定,通过@Column和@Table等注解完成,也可以通过被Hibernate的ImplicitNamingStrategy指定;
    • 第二个阶段是将上述的逻辑名称解析成物理名称,物理名称是由Hibernate中的PhysicalNamingStrategy决定;

    PhysicalNamingStrategy和ImplicitNamingStrategy的区别:

    • 从处理的效果上来看,其实没有什么区别,但是从程序设计分层的角度来看,类似于MVC的分层,ImplicitNamingStrategy只管模型对象层次的处理,PhysicalNamingStrategy只管映射成真实的数据名称的处理,但是为了达到相同的效果,比如将userName映射城数据列时,在PhysicalNamingStrategy决定映射成user_name,但是在ImplicitNamingStrategy也可以做到;
    • 从处理的场景来看,
      无论对象模型中是否显式地指定列名或者已经被隐式决定,PhysicalNamingStrategy都会应用;
      但是对于ImplicitNamingStrategy,仅仅只有当没有显式地提供名称时才会使用,也就是说当对象模型中已经指定了@Table或者@Entity等name时,设置的ImplicitNamingStrategy并不会起作用。

    所以,这里的配置,映射到表字段时,所有点都被下划线替换,骆驼情况也被下划线替换。默认情况下,所有表名都以小写生成

    三、使用Spring-data-Jpa

    3.1 表与Java实体

    假设我们有一张这个表user_role :

    在这里插入图片描述

    实体:

    package cn.pomit.testboot.domain;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    @Entity
    @Table(name = "user_role")
    public class UserRole {
        @Id
        private int id;
        @Column(name = "user_name")
        private String userName;
        private String role;
        private String phone;
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getId() {
            return id;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setRole(String role) {
            this.role = role;
        }
    
        public String getRole() {
            return role;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public String getPhone() {
            return phone;
        }
    
    }
    

    3.2 建立Dao层进行数据库访问

    UserRoleDao:

    
    import java.util.List;
    
    import org.springframework.data.repository.CrudRepository;
    
    import cn.pomit.testboot.domain.UserRole;
    
    public interface UserRoleDao extends CrudRepository<UserRole, Integer> {
        List<UserRole> findByRole(String role);
    }
    

    可以看到,使用Spring-data-jpa就是就这么简单,只需要继承CrudRepository即可。

    同时,Spring-data-jpa还支持findBy + 字段(And 字段)进行查询。deleteBy + 字段(And 字段)进行删除。

    分页等其他操作后续再讲。

    四、service逻辑调用Dao。

    UserRoleService:

    import java.util.List;
    
    import javax.transaction.Transactional;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import cn.pomit.testboot.domain.UserRole;
    import cn.pomit.testboot.mapper.UserRoleDao;
    
    @Service
    public class UserRoleService {
        @Autowired
        UserRoleDao userRoleDao;
    
        public List<UserRole> selectAll() {
            return (List<UserRole>) userRoleDao.findAll();
        }
    
        public void saveTest(UserRole userRole) {
            userRoleDao.save(userRole);
        }
    
        @Transactional
        public void update(Integer id, String phone) {
            UserRole userRole = userRoleDao.findById(id).orElse(null);
            if (userRole != null) {
                userRole.setPhone(phone);
                userRoleDao.save(userRole);
            }
    
        }
    
        @Transactional
        public void delete(Integer id) {
            userRoleDao.deleteById(id);
        }
    
        public List<UserRole> findByRole(String role) {
            return userRoleDao.findByRole(role);
        }
    }
    

    五、开放接口调用service

    MybatisRest:

    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import cn.pomit.testboot.domain.UserRole;
    import cn.pomit.testboot.service.UserRoleService;
    
    @RestController
    @RequestMapping("/db")
    public class TestJpaRest {
        @Autowired
        UserRoleService userRoleService;
    
        @RequestMapping(value = "/query")
        public List<UserRole> query() {
            return userRoleService.selectAll();
        }
    
        @RequestMapping(value = "/testFind")
        public List<UserRole> testFind() {
            return userRoleService.findByRole("ADMIN");
        }
    
        @RequestMapping(value = "/save")
        public String save() {
            UserRole userRole = new UserRole();
            userRole.setRole("TEST");
            userRole.setUserName("TEST");
            userRole.setPhone("3424234");
            userRoleService.saveTest(userRole);
            return "0000";
        }
    
        @RequestMapping(value = "/update")
        public String update() {
            userRoleService.update(4, "454");
            return "0000";
        }
    
        @RequestMapping(value = "/delete")
        public String delete() {
            userRoleService.delete(4);
            return "0000";
        }
    
    }
    

    六、启动

    package cn.pomit.testboot;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class JpaApplication {
        public static void main(String[] args) {
            SpringApplication.run(JpaApplication.class, args);
        }
    }
    
    

    喜欢这篇文章么,喜欢就加入我们一起讨论SpringBoot技术吧!


    品茗IT交流群

    相关文章

      网友评论

        本文标题:SpringBoot入门建站全系列(五)使用Spring-dat

        本文链接:https://www.haomeiwen.com/subject/jgyvzqtx.html