工作需要,用到了jpa,很久没用了,忘了,写一个简单的demo,方便日后查看。
数据库配置文件
在SpringBoot中,application.properties的配置:注意,SpringBoot会默认有数据源的配置,否则启动报错不需要,则在启动类当中加上如下注解:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
application.properties的配置:
spring.datasource.url=jdbc:mysql://localhost:3306/db_electric_car?
useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true
新建一个实体类:
package com.cn.restyle.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name ="tb_app_user") // 对应数据库表名
public class AppUser {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) // id自增
private Integer id;
private String mobile;
private String pass;
@Column(name="os") // 此注解映射实体和数据库字段不一致的情况
private String osString;
private String brand;
@Column(name="create_time")
private Date createTime;
@Column(name="update_time")
private Date updateTime;
private Integer isDelete;
public AppUser(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getOsString() {
return osString;
}
public void setOsString(String osString) {
this.osString = osString;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Integer getIsDelete() {
return isDelete;
}
public void setIsDelete(Integer isDelete) {
this.isDelete = isDelete;
}
public AppUser(Integer id, String mobile, String pass, String osString, String brand, Date createTime,
Date updateTime, Integer isDelete) {
super();
this.id = id;
this.mobile = mobile;
this.pass = pass;
this.osString = osString;
this.brand = brand;
this.createTime = createTime;
this.updateTime = updateTime;
this.isDelete = isDelete;
}
@Override
public String toString() {
return "AppUser [id=" + id + ", mobile=" + mobile + ", pass=" + pass + ", osString=" + osString + ", brand="
+ brand + ", createTime=" + createTime + ", updateTime=" + updateTime + ", isDelete=" + isDelete + "]";
}
}
本人习惯运用的工具类Result:
package com.cn.restyle.unit;
public class Result<T> {
public static final Integer OK = 0;
public static final Integer error = -1;
private Integer code;
private String msg;
private T data;
public Result(){
this.code = OK;
this.msg = "success";
}
public Result(Integer code, String msg) {
super();
this.code = code;
this.msg = msg;
}
public Result(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Result(T data) {
super();
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static Integer getOk() {
return OK;
}
public static Integer getError() {
return error;
}
}
定义接口:
package com.cn.restyle.mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.cn.restyle.entity.AppUser;
@Repository
public interface AppUserMapper extends JpaRepository<AppUser, Long>{
AppUser findByMobile(String mobile);
AppUser findByMobileAndPass(String mobile,String pass);
@Query("select u from AppUser u where u.mobile = :mobile and u.pass = :pass")
AppUser withMobleAndPassQuery(@Param("mobile")String mobile,@Param("pass")String pass);
}
注意,我在这踩了个坑,以前 @Query(“select u from AppUser u where u.mobile = :mobile and u.pass = :pass”),我是这么写的,后来运行的时候,报错
2017-11-23 15:55:37.519 INFO 11188 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 35 ms
2017-11-23 15:55:37.600 ERROR 11188 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Name for parameter binding must not be null or empty! On JDKs < 8, you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.; nested exception is java.lang.IllegalArgumentException: Name for parameter binding must not be null or empty! On JDKs < 8, you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.] with root cause
java.lang.IllegalArgumentException: Name for parameter binding must not be null or empty! On JDKs < 8, you need to use @Param for named parameters, on JDK 8 or better, be sure to compile with -parameters.
at org.springframework.util.Assert.hasText(Assert.java:181)
at org.springframework.data.jpa.repository.query.StringQuery.getBindingFor(StringQuery.java:105)
at org.springframework.data.jpa.repository.query.StringQueryParameterBinder.getBindingFor(StringQueryParameterBinder.java:75)
at org.springframework.data.jpa.repository.query.StringQueryParameterBinder.bind(StringQueryParameterBinder.java:60)
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:101)
at org.springframework.data.jpa.repository.query.SpelExpressionStringQueryParameterBinder.bind(SpelExpressionStringQueryParameterBinder.java:76)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:161)
at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:152)
at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateQuery(AbstractStringBasedJpaQuery.java:81)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:208)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:87)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
不知道现在是不能这样写了么?于是我改成这样:问题解决:
@Query("select u from AppUser u where u.mobile = ?1 and u.pass = ?2")
Controller中的代码:
package com.cn.restyle.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cn.restyle.entity.AppUser;
import com.cn.restyle.mapper.AppUserMapper;
import com.cn.restyle.unit.Result;
@RestController
@RequestMapping("/v1/spring")
public class Example {
protected static Logger log = LoggerFactory.getLogger(Example.class);
@Autowired
AppUserMapper appUserMapper;
@RequestMapping("/hell")
String home(){
return "Hello Word !";
}
@RequestMapping("/hello/{userName}")
String index(@PathVariable String userName){ // 从路径当中获取值
return "Hello" + userName;
}
@RequestMapping("/showData")
public Result showData(){
String mobile = "15721429352";
AppUser appUser = appUserMapper.findByMobile(mobile);
if (null != appUser) {
log.info(appUser.toString());
}else {
log.info("数据库当中没有此电话号码");
}
return new Result();
}
@RequestMapping("/showDataMobileAndPass")
public Result showDataMobileAndPass(){
String mobile = "15721429352";
String pass = "654321";
AppUser appUser = appUserMapper.findByMobileAndPass(mobile, pass);
if (null != appUser) {
log.info(appUser.toString());
}else {
log.info("数据库当中没有此电话号码");
}
return new Result(appUser);
}
@RequestMapping("/withMobileAndPass")
public Result withMobileAndPass(){
String mobile = "15721429352";
String pass = "654321";
AppUser appUser = appUserMapper.withMobleAndPassQuery(mobile, pass);
if (null != appUser) {
log.info(appUser.toString());
}else {
log.info("数据库当中没有此电话号码");
}
return new Result(appUser);
}
}
代码是测试运行过的。先下班。。。过两天有时间再完善