在上一篇《基于Spring Boot,使用JPA操作Sql Server数据库完成CRUD》中完成了使用JPA对实体数据的CRUD操作。
那么,有些情况,会把一些查询语句写在存储过程中,由存储过程来返回记录集。
在这里就先通过EntityManager创建命名存储过程的方法完成调用。
1.创建SQL存储过程
存储过程返回所有的联系人。
USE [demodb]
GO SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <bobenut>
-- Create date: <2017/9/14>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[proc_get_contacts_like_name]
@name varchar(50)
AS
BEGIN
SET NOCOUNT ON;
SELECT * from contact where name like @name;
END
2.定义命名的存储过程。
在包“com.kxh.example.demo.domain”下的“Contact”实体上编写存储过程的映射。
@NamedStoredProcedureQueries注解表示可以包含多个存储过程的映射。
@NamedStoredProcedureQuery注解就是对一个存储过程的映射。
参数name,给这次映射取一个名字,后续调用时使用。
参数procedureName,是数据库中真实的存储过程的名字。
参数parameters,是对存储过程输入或输出参数的映射定义。
package com.kxh.example.demo.domain; import javax.persistence.Entity;
import javax.persistence.EntityResult;
import javax.persistence.FieldResult;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedStoredProcedureQueries;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.ParameterMode;
import javax.persistence.SqlResultSetMapping;
import javax.persistence.StoredProcedureParameter; @Entity
@NamedStoredProcedureQueries({
@NamedStoredProcedureQuery(
name = "getContactsLikeName",
procedureName = "proc_get_contacts_like_name",
resultClasses = { Contact.class },
parameters = {
@StoredProcedureParameter(
mode = ParameterMode.IN,
name = "name",
type = String.class)
}
)
})
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id; private String name; private String phone; private String mail; public Contact() {
super();
} public Contact(String name, String phone, String mail) {
super(); this.name = name;
this.phone = phone;
this.mail = mail;
} public long getId() {
return this.id;
} public void setId(long value) {
this.id = value;
} public String getName() {
return this.name;
} public void setName(String value) {
this.name = value;
} public String getPhone() {
return phone;
} public void setPhone(String value) {
this.phone = value;
} public String getMail() {
return this.mail;
} public void setMail(String value) {
this.mail = value;
}
}
3.通过业务对象调用
在包“com.kxh.example.demo.service”下创建类“ContactsService”。
在类内,引入“EntityManager”,加上@Autowired注解由框架实例化。
通过"EntityManager"创建命名的存储过程函数,并传入上面定义的映射名进行指定调用。
然后为存储过程设置输入参数,执行并返回结果。
package com.kxh.example.demo.service; import java.util.List; import javax.persistence.EntityManager;
import javax.persistence.StoredProcedureQuery; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import com.kxh.example.demo.domain.Contact; @Component
public class ContactsService {
@Autowired
private EntityManager entityManager; @SuppressWarnings("unchecked")
public List<Contact> findAllViaProc(String name) {
StoredProcedureQuery storedProcedureQuery = this.entityManager.createNamedStoredProcedureQuery("getContactsLikeName");
storedProcedureQuery.setParameter("name", name);
storedProcedureQuery.execute();
return storedProcedureQuery.getResultList();
}
}
4.通过RestController向外提供服务
引入“ContactService”作为成员变量,并Autowired。
增加一个新的访问路径映射,在处理方法中调用contactsService.findAllViaProc(nameWhere)获取查询结果集。
package com.kxh.example.demo.controller; import java.util.ArrayList;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import com.kxh.example.demo.dao.ContactsRepository;
import com.kxh.example.demo.domain.Contact;
import com.kxh.example.demo.service.ContactsService; @RestController
@RequestMapping("/contacts")
public class ContactsController { @Autowired
ContactsService contactsService;
//省略//通过存储过程查
@RequestMapping(value="/query/viaproc/likename", method=RequestMethod.GET)
public List<Contact> findContactsUseProcLikeName(String name) {
System.out.println("kxh1");
String nameWhere = org.apache.commons.lang.StringUtils.join(new String[]{"%", name, "%"}, "");
List<Contact> contacts = contactsService.findAllViaProc(nameWhere);
if(contacts == null) {
return new ArrayList<Contact>();
} else {
return contacts;
}
} //省略
}
End