SpringBoot整合JPA操作数据库
1、pom中添加依赖jar包
在上一节pom基础上加入下列jar包
<dependencies> <!--SpringBoot整合JPA所需的jar包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!--连接mysql数据库所需要的jar包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--由于web启动包中集成了tomcat,并且默认使用tomcat启动,我选择使用jetty启动项目, 所以在这里把tomcat有关的包给排除掉--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!--引入SpringBoot集成的jetty启动包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> <!--如果需要热部署,则需要引入该包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
2、数据源配置
上一节中说到SpringBoot已经提供了许多集成框架的默认配置,我们不需要配置就可以构造一个web系统。但像数据库、Redis等部署在其它终端的需要远程链接地址和用户密码,因此我们还需要进行稍微配置来告诉SpringBoot我们要链接的地址以及用户名和密码。
Spring程序会按优先级从下面这些路径来加载application.properties配置文件
- 当前目录下的/config目录
- 当前目录
- classpath里的/config目录
- classpath 跟目录
#dataSource配置 spring.datasource.url = jdbc:mysql://localhost:3306/semp_dev?characterEncoding=utf-8 spring.datasource.username = root spring.datasource.password = admin spring.datasource.driverClassName = com.mysql.jdbc.Driver #jpa配置 spring.jpa.database = MYSQL spring.jpa.show-sql = true spring.jpa.hibernate.ddl-auto = update spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect #指定服务端口 server.port=8089
这些配置对于学习过hibernate的童鞋一定一眼就能看懂吧,这里不再细说。
3、编写实现代码
首先创建实体类,这里以jpa提供的注解方式实现与数据库的orm映射
@Entity @Table(name = "user") public class User implements Serializable{ private static final long serialVersionUID = -3989157339303587707L; @Id private Long id; @Column private String username; @Column private String password; @Column private String sex; @Column private int age; @Column private Long phone; 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; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Long getPhone() { return phone; } public void setPhone(Long phone) { this.phone = phone; } public User(){} public User(Long id, String username, String password, String sex, int age, Long phone) { this.id = id; this.username = username; this.password = password; this.sex = sex; this.age = age; this.phone = phone; } }
接下来是Dao层
public interface UserDao extends CrudRepository<User,Long>{ @Transactional public User save(User user); public List<User> findAll(); public List<User> findByUsername(String username); }
这里需要继承CrudRepository,进去可以看到它提供了一些简单的常用方法
@NoRepositoryBean public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { /** * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the * entity instance completely. * * @param entity * @return the saved entity */ <S extends T> S save(S entity); /** * Saves all given entities. * * @param entities * @return the saved entities * @throws IllegalArgumentException in case the given entity is {@literal null}. */ <S extends T> Iterable<S> save(Iterable<S> entities); /** * Retrieves an entity by its id. * * @param id must not be {@literal null}. * @return the entity with the given id or {@literal null} if none found * @throws IllegalArgumentException if {@code id} is {@literal null} */ T findOne(ID id); /** * Returns whether an entity with the given id exists. * * @param id must not be {@literal null}. * @return true if an entity with the given id exists, {@literal false} otherwise * @throws IllegalArgumentException if {@code id} is {@literal null} */ boolean exists(ID id); /** * Returns all instances of the type. * * @return all entities */ Iterable<T> findAll(); /** * Returns all instances of the type with the given IDs. * * @param ids * @return */ Iterable<T> findAll(Iterable<ID> ids); /** * Returns the number of entities available. * * @return the number of entities */ long count(); /** * Deletes the entity with the given id. * * @param id must not be {@literal null}. * @throws IllegalArgumentException in case the given {@code id} is {@literal null} */ void delete(ID id); /** * Deletes a given entity. * * @param entity * @throws IllegalArgumentException in case the given entity is {@literal null}. */ void delete(T entity); /** * Deletes the given entities. * * @param entities * @throws IllegalArgumentException in case the given {@link Iterable} is {@literal null}. */ void delete(Iterable<? extends T> entities); /** * Deletes all entities managed by the repository. */ void deleteAll(); }
它还继承自Repository,Repository里面没有任何方法,它仅仅是提供一个标识,表明只要是继承它的类都是一个数据仓库
以往我们创建完Dao接口还要去实现Dao,这里我们继承了CrudRepository,只要我们写的方法名称符合JPA规范,那么JPA会我们自动生成实现类,我们不用再去创建impl类。例如:
我们定义方法的时候它会自动提示我们去用什么方法名,我们按照它的方法来命名就可以不用写实现类了,接下来创建service
@Service @Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class) public class UserService { @Resource private UserDao userDao; public void save(User user){ userDao.save(user); } public List<User> queryAllUser(){ return userDao.findAll(); } public List<User> queryUsersByName(String userName){ return userDao.findByUsername(userName); } }
然后是controller层
@RestController public class UserController { @Autowired private UserService serService; @RequestMapping("/addUser") public void addUser(@RequestBody User user){ serService.save(user); } @RequestMapping("/queryUsers") public List<User> queryUsers(){ long start=System.currentTimeMillis(); List<User>list=serService.queryAllUser(); long end=System.currentTimeMillis(); System.out.println("查询耗费:"+(end-start)+"ms"); return list; } @RequestMapping("/queryUserByName") public List<User> queryUserByName(String name){ return serService.queryUsersByName(name); } }
到此一个简单的操作数据库接口已经创建好了,我们来启动服务
通过启动信息我们可以看到多了一些hibernate的日志和连接mysql的一些日志,jetty服务端口现在变成了8089,接下来我们进行测试
我测试使用的是Postman工具,这里首先测试增加方法
控制台成功打印出了hibernate的日志
然后我们测试查询接口
控制台打印sql如下
我们查看返回结果
测试成功,本节介绍了如何通过SpringBoot整合JPA操作数据库,下一节将详细介绍spring的核心配置文件以及自定义配置文件