再看看SpringBoot项目全局配置文件 application.properties
# 配置tomcat端口号 server.port=8081 # 配置SpringMVC视图解析器 spring.mvc.view.prefix=http://www.likecs.com/WEB-INF/views/ spring.mvc.view.suffix=.jsp # 配置连接池,默认使用的是tomcat的连接池,但实际很少用tomcat的连接池 spring.datasource.url=jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF8 spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 配置方言 否则提示:Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect # 自动更新数据库表结构,也可以是 validate | update | create | create-drop spring.jpa.properties.hibernate.hbm2ddl.auto=update # 显示sql语句 spring.jpa.show-sql=true全局配置文件可以是application.properties 也可以是 application.yml,建议放在resources目录下。更多配置: https://github.com/ITDragonBlog/daydayup/blob/master/SpringBoot/SpringData/springbootStudy/src/main/resources/springboot.properties
核心注解最后是SpringBoot HelloWorld项目的入口类,只需要下面一个java文件,执行main方法,即可实现页面的跳转和数据返回的功能。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @SpringBootApplication public class SpringbootStudyApplication { @RequestMapping("http://www.likecs.com/") public String index() { return "index"; } @RequestMapping("hello") @ResponseBody public String helloWorld() { return "Hello SpringBoot !"; } public static void main(String[] args) { SpringApplication.run(SpringbootStudyApplication.class, args); } }@SpringBootApplication:是 SpringBoot 的核心注解,一般用在入口类上。它是一个组合注解,其中主要内容有一下三个
@SpringBootConfiguration:是一个类级注释,指示对象是一个bean定义的源,可以理解为xml中的beans,一般和 @Bean 注解一起使用。
@EnableAutoConfiguration:启用 Spring 应用程序上下文的自动配置,试图猜测和配置您可能需要的bean。自动配置类通常采用基于你的 classpath 和已经定义的 beans 对象进行应用。
@ComponentScan:该注解会自动扫描指定包下的全部标有 @Component、@Service、@Repository、@Controller注解 的类,并注册成bean
SpringData入口类
package com.itdragon; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StartApplication { public static void main(String[] args) { SpringApplication.run(StartApplication.class, args); } } SpringDataJPA 知识SpringData 是一个用于简化数据库访问,并支持云服务的开源框架。支持非关系型数据库(NoSQL) 和 关系型数据库。其主要目的是使数据库的访问变得方便快捷。
SpringData JPA 是由Spring提供的简化JPA开发的框架,致力于减少数据访问层的开发量。
创建实体类User 表,对应数据库表名是 itdragon_user,id作为自增长的主键,plainPassword是不保存到数据库的明文密码。
import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; /** * 用户实体类 * @author itdragon * */ @Table(name="itdragon_user") @Entity public class User { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; // 自增长主键 private String account; // 登录的账号 private String userName; // 注册的昵称 @Transient private String plainPassword; // 登录时的密码,不持久化到数据库 private String password; // 加密后的密码 private String salt; // 用于加密的盐 private String iphone; // 手机号 private String email; // 邮箱 private String platform; // 用户来自的平台 private String createdDate; // 用户注册时间 private String updatedDate; // 用户最后一次登录时间 // 省略get/set/toString 方法 } Repository接口层创建UserRepository,这是SpringData 的核心知识点,我们先看代码
import java.util.List; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import com.itdragon.pojo.User; /** * 核心知识:SpringData Repository 接口 * * CrudRepository 接口提供了最基本的对实体类的添删改查操作 * - T save(T entity); //保存单个实体 * - T findOne(ID id); // 根据id查找实体 * - void delete(ID/T/Iterable); // 根据Id删除实体,删除实体,批量删除 * PagingAndSortingRepository 提供了分页与排序功能 * - <T, ID extends Serializable> // 第一个参数传实体类,第二个参数传注解数据类型 * - Iterable<T> findAll(Sort sort); // 排序 * - Page<T> findAll(Pageable pageable); // 分页查询(含排序功能) * JpaSpecificationExecutor 提供了Specification(封装 JPA Criteria查询条件)的查询功能 * - List<T> findAll(Specification<T> spec); * - Page<T> findAll(Specification<T> spec, Pageable pageable); * - List<T> findAll(Specification<T> spec, Sort sort); * * 开发建议 * 1. 这里值列出的是常用方法 * 2. CrudRepository 中的findAll() 方法要慎用。当数据库中数据量大,多线程脚本调用findAll方法,系统可能会宕机。 * 3. CrudRepository 中的deletAll()方法要慎用。这是物理删除,现在企业一般采用逻辑删除。 * 4. PagingAndSortingRepository 和 JpaSpecificationExecutor 能满足大部分业务需求。 */ public interface UserRepository extends PagingAndSortingRepository<User, Long>, JpaSpecificationExecutor<User>{ /** * 重点知识:SpringData 查询方法定义规范 * * 1. 查询方法名一般以 find | read | get 开头,建议用find * findByAccount : 通过account查询User * account是User的属性,拼接时首字母需大写 * 2. 支持的关键词有很多比如 Or,Between,isNull,Like,In等 * findByEmailEndingWithAndCreatedDateLessThan : 查询在指定时间前注册,并以xx邮箱结尾的用户 * And : 并且 * EndingWith : 以某某结尾 * LessThan : 小于 * * 注意 * 若有User(用户表) Platform(用户平台表) 存在一对一的关系,且User表中有platformId字段 * SpringData 为了区分: * findByPlatFormId 表示通过platformId字段查询 * findByPlatForm_Id 表示通过platform实体类中id字段查询 * * 开发建议 * 表的设计,尽量做单表查询,以确保高并发场景减轻数据库的压力。 */ // 1 通过账号查用户信息 User findByAccount(String account); // 2 获取指定时间内以xx邮箱结尾的用户信息 List<User> findByEmailEndingWithAndCreatedDateLessThan(String email, String createdDate); /** * 重点知识:使用 @Query 注解 * * 上面的方法虽然简单(不用写sql语句),但它有最为致命的问题-----不支持复杂查询,其次是命名太长 * 1. 使用@Query 注解实现复杂查询,设置 nativeQuery=true 使查询支持原生sql * 2. 配合@Modifying 注解实现创建,修改,删除操作 * 3. SpringData 默认查询事件为只读事务,若要修改数据则需手动添加事务注解 * * 注意 * 若@Query 中有多个参数,SpringData 提供两种方法: * 第一种 ?1 ... ?2 要求参数顺序一致 * 第二种 :xxx ... :yyy xxx 和 yyy 必须是实体类对应的属性值,不要求参数顺序但参数前要加上@Param("xxx") * 模糊查询可使用 %xxx% * * 开发建议 * 1. 参数填写的顺序要保持一致,不要给自己添加麻烦 * 2. 建议使用@Query,可读性较高 */ // 3 获取某平台活跃用户数量 @Query(value="SELECT count(u.id) FROM User u WHERE u.platform = :platform AND u.updatedDate <= :updatedDate") long getActiveUserCount(@Param("platform")String platform, @Param("updatedDate")String updatedDate); // 4 通过邮箱或者手机号模糊查询用户信息 @Query(value="SELECT u FROM User u WHERE u.email LIKE %?1% OR u.iphone LIKE %?2%") List<User> findByEmailAndIhpneLike(String email, String iphone); // 5 修改用户邮箱 @Modifying @Query("UPDATE User u SET u.email = :email WHERE u.id = :id") void updateUserEmail(@Param("id") Long id, @Param("email") String email); }