zoukankan      html  css  js  c++  java
  • 使用Spring Boot 和Spring Data JPA访问mysql数据库

    在Spring中使用JdbcTemplate是一种基本的数据访问方式,但是仍然需要较多的代码,为了解决这些大量枯燥的数据操作语句,我们可以使用ORM框架,比如:Hibernate,通过整合Hibernate,解决抽象各个Java实体基本的“增删改查”操作,通常会以泛型的方式封装一个模板Dao来进行抽象简化,那些具体的Dao实现完全就是对模板Dao的简单代理,Spring-data-jpa正可以完成这一项工作。

    JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate,TopLink,JDO等ORM框架各自为营的局面。Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用实现,并支持扩展,使用 Spring Data JPA 可以极大提高开发效率。

    1.新建Spring Boot项目,

    2.添加spring jpa依赖

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

    ----

    3.添加User实体类

    @Entity  
    public class User {
    
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;
    
        @Column(nullable = false)
        private String name;
        
        private Integer age;
        
        protected User(){
        }
        
        public User(String name, int age)
        {
            this.name = name;
            this.age = age;
        }
    
        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 Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
    }

    ---

    4.添加配置文件

    spring.jpa.hibernate.ddl-auto=create
    
    spring.datasource.url=jdbc:mysql://localhost:3306/lgtest
    spring.datasource.username=root
    spring.datasource.password=pwd
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver

    ---spring.jpa.hibernate.ddl-auto值可以是noneupdatecreatecreate-drop,根据Hibernate的说明,他们的意义如下:

    none: 表示Hibernate不改变表结构

    update: Hibernate会根据Entity修改表结构

    create: Hibernate每次加载都创建表,但是SessionFactory关闭时不drop表

    create-drop: Hibernate每次加载都创建表,SessionFactory关闭时drop表

    所以第一次运行时应该选择Create,之后应该选择为update或none。

    内存数据库如H2的默认值为create-drop,MySql默认值为none。

    5.创建数据访问接口

    public interface UserRepository extends CrudRepository<User, Long> {
    
        List<User> findByName(String name);
        
        @Modifying
        @Query("update User u set u.name = ?1 where u.id = ?2")
        int modifyByIdAndUserId(String name, Long id);
            
        @Transactional(timeout = 10)
        @Modifying
        @Query("delete from User where name = ?1")
        void deleteByUserName(String name);
    
    }

    ---JpaRepository接口本身已经实现了创建(save)、更新(save)、删除(delete)、查询(findAll、findOne)等基本操作的函数,因此对于这些基础操作的数据访问就不需要开发者再自己定义。

    6.创建一个controller做测试

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Resource
        private UserRepository repository;
    
        @RequestMapping("/add")
        public User addUser(@RequestParam(value="name")String name, @RequestParam(value="age")Integer age) {
            return repository.save(new User(name, age));
        }
        
        @RequestMapping("/delete")
        public void delete(@RequestParam(value="id")Long id) {
            repository.delete(id);
        }
    
        @RequestMapping("/queryAll")
        public List<User> queryAll() {
            return (List<User>) repository.findAll();
        }
        
        @RequestMapping("/queryById")
        public User queryById(@RequestParam(value="id")Long id) {
            return  repository.findOne(id);
        }
        
        @RequestMapping("/queryByName")
        public List<User> queryByName(@RequestParam(value="name")String name) {
            return repository.findByName(name);
        }
    
    }

    ---

    启动即可调试。 

    补充:

    自定义简单查询

    自定义的简单查询就是根据方法名来自动生成SQL,支持findBy,readBy,queryBy,countBygetBy,deleteBy后面加属性名称

    User findByUserName(String userName);

    可以组合And、 Or,如 User findByUserNameOrEmail(String username, String email);

    可以组合LIKE、 IgnoreCase、 OrderBy如:

    List<User> findByEmailLike(String email);
    
    User findByUserNameIgnoreCase(String userName);
        
    List<User> findByUserNameOrderByEmailDesc(String email);

     --

    KeywordSampleJPQL snippet
    And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
    Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
    Is,Equals findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
    Between findByStartDateBetween … where x.startDate between ?1 and ?2
    LessThan findByAgeLessThan … where x.age < ?1
    LessThanEqual findByAgeLessThanEqual … where x.age ⇐ ?1
    GreaterThan findByAgeGreaterThan … where x.age > ?1
    GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
    After findByStartDateAfter … where x.startDate > ?1
    Before findByStartDateBefore … where x.startDate < ?1
    IsNull findByAgeIsNull … where x.age is null
    IsNotNull,NotNull findByAge(Is)NotNull … where x.age not null
    Like findByFirstnameLike … where x.firstname like ?1
    NotLike findByFirstnameNotLike … where x.firstname not like ?1
    StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
    EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
    Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
    OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
    Not findByLastnameNot … where x.lastname <> ?1
    In findByAgeIn(Collection ages) … where x.age in ?1
    NotIn findByAgeNotIn(Collection age) … where x.age not in ?1
    TRUE findByActiveTrue() … where x.active = true
    FALSE findByActiveFalse() … where x.active = false
    IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)

    分页查询

    分页查询在实际使用中非常普遍了,spring data jpa已经帮我们实现了分页的功能,在查询的方法中,需要传入参数Pageable,当查询中有多个参数的时候Pageable建议做为最后一个参数传入

    Page<User> findALL(Pageable pageable);
        
    Page<User> findByUserName(String userName,Pageable pageable);

    Pageable 是spring封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则

    @Test
    public void testPageQuery() throws Exception {
        int page=1,size=10;
        Sort sort = new Sort(Direction.DESC, "id");
        Pageable pageable = new PageRequest(page, size, sort);
        userRepository.findALL(pageable);
        userRepository.findByUserName("testName", pageable);
    }

    限制数量查询:

    ser findFirstByOrderByLastnameAsc();
    
    User findTopByOrderByAgeDesc();
    
    Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
    
    List<User> findFirst10ByLastname(String lastname, Sort sort);
    
    List<User> findTop10ByLastname(String lastname, Pageable pageable);

    自定义SQL查询

    spring data也是支持自定义的SQL查询的;在SQL的查询方法上面使用@Query注解,删除和修改使用@Modifying. 也可以根据需要添加 @Transactional 开启事务,查询超时的设置等

    @Modifying
    @Query("update User u set u.userName = ?1 where c.id = ?2")
    int modifyByIdAndUserId(String  userName, Long id);
        
    @Transactional
    @Modifying
    @Query("delete from User where id = ?1")
    void deleteByUserId(Long id);
      
    @Transactional(timeout = 10)
    @Query("select u from User u where u.emailAddress = ?1")
    User findByEmailAddress(String emailAddress);

    枚举

     如果希望数据库中存储的是枚举对应的String类型,而不是枚举的索引值,需要在属性上面添加@Enumerated(EnumType.STRING) 注解

    @Enumerated(EnumType.STRING) 
    @Column(nullable = true)
    private UserType type;

    不需要和数据库映射的属性

    在实体类上加入注解@Entity,会让实体类和表关连,如果其中某个属性不需要和数据库关联,只需要加上@Transient注解既可。 

    end

    觉得不错,点个赞吧
  • 相关阅读:
    高可用Redis(七):Redis持久化
    高可用Redis(六):瑞士军刀之bitmap,HyperLoglog和GEO
    高可用Redis(五):瑞士军刀之慢查询,Pipeline和发布订阅
    高可用Redis(四):列表,集合与有序集合
    高可用Redis(三):Hash类型
    高可用Redis(二):字符串类型
    高可用Redis(一):通用命令,数据结构和内部编码,单线程架构
    详解Django的CSRF认证
    详解MariaDB数据库的事务
    详解MariaDB数据库的触发器
  • 原文地址:https://www.cnblogs.com/luangeng/p/5450148.html
Copyright © 2011-2022 走看看