Prefácio
O JDBC Templet da Spring é um encapsulamento básico que a primavera usa para o JDBC. Ajuda principalmente aos programadores a gerenciar conexões de banco de dados, e o restante dos métodos de uso não é uma grande diferença ao usar o JDBC diretamente.
Requisitos de negócios
Todo mundo está familiarizado com o uso do JDBC. Isso é principalmente para demonstrar as etapas para usar o Spring JDBC Templet no Springboot, por isso projetamos um requisito simples. Uma operação coalhada de um objeto de usuário. Um objeto tem duas propriedades, uma é ID e o outro é o nome. Armazenado na tabela auth_user em MySQL.
Crie novos projetos e adicione dependências
Crie um projeto vazio de trampolim em Intellij Idea. Referência de etapas específicas
O tutorial gráfico da Intellij Idea para criar projetos de botas de primavera. De acordo com os requisitos deste exemplo, precisamos adicionar as três dependências a seguir
<Depencency> <GroupId> org.springframework.boot </frugiD> <ArtifactId> Spring-boot-starter-web </artifactId> </dependency> <pendesency> <puperid> org.springframework.boot </groupid> <Artifactid> Spring-Boot-Starter-Jdbwwork.Boot </groupid> <Artifactid> Spring-Boot-Starter-jdbcbc. <GrupidId> mysql </foupiD> <stifactId> mysql-conector-java </artifactId> <versão> 6.0.6 </sisters> </dependency>
Como queremos publicar o serviço HTTP REST, adicionamos a dependência da Spring-Boot-Starter-Web. Aqui, queremos usar o método JDBC TEMpet para acessar o banco de dados, por isso adicionamos a dependência de Spring-Boot-Starter-JDBC para acessar o banco de dados MySQL, por isso adicionamos a versão mais recente do driver JDBC do MySQL.
Prepare o ambiente do banco de dados
Suponha que o MySQL 5.7 já esteja instalado no sistema operacional Linux. As seguintes operações são executadas na linha de comando do sistema operacional, conectadas ao cliente da linha de comando do MySQL através do usuário root.
Crie banco de dados e tabela
Criar banco de dados Springboot_jdbc; crie tabela auth_user (uuid bigint não nulo, nome varchar (32), chave primária (uuid)) padrão de charset = utf8mb4;
Defina permissões de usuário
Conceda todos os privilégios em Springboot_jdbc.
Configurar a fonte de dados (pool de conexão)
A fonte de dados do Springboot é configurada automaticamente. No SpringBoot 2.0, existem várias configurações de fonte de dados disponíveis e elas escolhem qual fonte de dados realmente usar na última ordem do hikaricp -> tomcat pooling -> commons dbcp2.
Quando o projeto adiciona a dependência de Spring-Boot-Starter-JDBC, a dependência da fonte de dados Hikaricp já está incluída, portanto a fonte de dados do pool de conexão Hikaricp é configurada automaticamente aqui.
Adicione a seguinte configuração em appplications.properties
#Configuração da fonte de dados geral spring.dataSource.driver-class-name = com.mysql.cj.jdbc.driverspring.dataSource.url = jdbc: mysql: //10.110.2.5: 3306/spri ng-boot-jdbc? charset = utf8mb4 & usessl = FalsSpring.datasource.username = springbootspring.dataSource.password = Springboot# Fonte de dados hikari Configuração específica Spring.dataSource.hikari.Maximum-Pool-size = 20spring.datasource.hikari.minimum-Idle = 5
Entre eles, a maioria das configurações da fonte de dados hikari é mostrada na figura abaixo. Você pode verificar o significado de cada configuração
Desenvolvimento de programas
Entidade do banco de dados do usuário
De acordo com os requisitos, a entidade de dados do usuário correspondente possui dois atributos, um é ID e o outro é o nome. Este é um objeto Pojo puro.
pacote com.yanggaochao.springboot.learn.springbootjdbclearn.domain.dao;/*** Objeto de entidade do usuário** @author yang gaochao* @since 2018-03-09*/public class Userdo {private Long id; nome de string privado; public Long getId () {return id; } public void setId (longo id) {this.id = id; } public string getName () {return name; } public void setName (nome da string) {this.name = name; }} Objeto de retorno de Rest Rest Http geral
Geralmente, na interface HTTP REST, não apenas queremos retornar diretamente o conteúdo do objeto de negócios, mas também retornará algumas informações comuns, como o resultado da chamada da interface, a mensagem de texto personalizada retornou quando a chamada falha etc., precisamos estabelecer dois objetos de retorno de REST comuns, além de devolver a interface comuns e os resultados de texto em relação aos negócios. A definição específica é a seguinte
Retornar objeto para conteúdo comercial separado
pacote com.yanggaochao.springboot.learn.springbootjdbclearn.domain.bo;/*** O único objeto retorna o resultado** @author yang gaochao* @since 2018-03-09*/public class RestitemResult <T> {Private String; mensagem de string privada; item T privado; public string getResult () {return resultado; } public void setResult (resultado da string) {this.Result = resultado; } public string getMessage () {return message; } public void setMessage (string message) {this.message = message; } public t getItem () {return item; } public void setItem (item t) {this.item = item; }} Coleção de objeto de devolução de conteúdo de negócios
pacote com.yanggaochao.springboot.learn.springbootjdbclearn.domain.bo; importar java.util.Collection;/*** RETORNO DE RETORNO DE RETORNOS DE RETORNOS** @Author Yang Gaochao* @Since 2018-09*/Public Class RestcollectionRes- mensagem de string privada; Coleção particular <T> itens; public string getResult () {return resultado; } public void setResult (resultado da string) {this.Result = resultado; } public string getMessage () {return message; } public void setMessage (string message) {this.message = message; } coleção pública <T> getItems () {retornar itens; } public void setItems (coleção <t> itens) {this.items = itens; }} Desenvolvimento da camada de persistência de dados
Definição de interface da camada de persistência dos dados do usuário
pacote com.yanggaochao.springboot.learn.springbootjdbclearn.dao; importação com.yanggaochao.springboot.learn.springbootjdbclearn.domain.dao.userdo; importa java.util.list;/** ** ** ** ** ** ** ** Layer Datao. 2018-03-09*/interface pública Userdao {/*** salve um novo usuário no banco de dados** @param objeto de usuário para salvar* @return se o ganho muscular é bem-sucedido*/boolean add (usuário userdo); / *** Atualize um usuário no banco de dados** @param Usuário do usuário para atualizar* @return se a atualização é bem -sucedida*/ boolean update (usuário userdo); / *** Exclua um usuário especificado** @param ID A identidade do usuário para excluir* @return se o excluir é bem -sucedido*/ boolean excluir (longo id); / *** Consulta exata de um usuário especificado** @param id a identidade do usuário para consultar* @return Se ele puder ser consultado, retorne as informações do usuário, caso contrário, retorne o local nulo*/ userdo (id); / *** Consulte o usuário pelo nome** @param nome o nome a ser difuso* @return Lista de usuários para consultar*/ list <ustivedo> MatchName (nome da string);} Implementação da camada de persistência de dados do usuário
pacote com.yanggaochao.springboot.learn.springbootjdbclearn.dao.impl; import com.yanggaochao.springboot.learn.springbootjdbclearn.dao.userdao; importação com.yanggaochao.springboot.learn.springbootjdbclearn.domain.dao.userdo; importar org.springframework.beans.factory.annotation.aUtowired; importação org.springframework.jdbc.core.jdbctemplate; Import org.springframework.jdbc.support.rowset.sqlrowset; importar org.springframework.tereotype.repository; importar java.util.arraylist; importação java.util.list;/** ** ** Objeto do usuário Database Class *-Athor @Athor yka.list; */@Repositorypublic class UserDaojdbcTempleTImpl implementa Userdao {private final jdbcTemplate jdbctemplate; @AUTOWIRED Public UserDAOJDBCTEMPLETIMPL (JDBCTEMPLATE JDBCTEMPLATE) {this.jdbcTemplate = JDBCTemplate; } @Override public boolean add (usuário userdo) {string sql = "inserir em auth_user (uuid, nome) valores (?,?)"; Retorne jdbctemplate.update (sql, user.getId (), user.getName ())> 0; } @Override public boolean update (usuário userdo) {string sql = "update auth_user set nome =? Onde uuid =?"; Retorne jdbctemplate.update (sql, user.getName (), user.getId ())> 0; } @Override public boolean Delete (longo id) {string sql = "exclua de auth_user onde uuid =?"; retornar jdbctemplate.update (sql, id)> 0; } @Override public userdo Locate (longo id) {string sql = "selecione * de auth_user onde uuid =?"; SQLROWSET RS = JDBCTemplate.QueryForrowSet (SQL, ID); if (rs.Next ()) {return generateEntity (rs); } retornar nulo; } @Override Public List <Suserdo> MatchName (Nome da String) {String sql = "Selecione * de auth_user onde o nome como?"; SQLROWSET RS = JDBCTemplate.QueryForrowset (SQL, "%" + Name + "%"); List <astardo> usuários = new ArrayList <> (); while (rs.Next ()) {users.add (generateEntity (rs)); } retornar usuários; } USERDO PRIVADO GERATEENTITY (SQLROWSET RS) {userdo wechatpay = new userdo (); wechatpay.setId (rs.getlong ("uuid")); wechatpay.setName (rs.getString ("nome")); retornar wechatpay; }} Aqui, usamos primeiro a anotação @repository para indicar que esta é uma classe da camada de persistência de dados, e o Springboot instanciará automaticamente essa classe. Em seguida, adicione um @Autowired ao construtor. Quando o Springboot instancia essa classe, ele injetará automaticamente a instância do JDBCTEMPT nessa classe. Aqui, a instância do JDBCTemplet é configurada automaticamente pelo Springboot com base na configuração relacionada à fonte de dados em aplicativos.properties. De acordo com o algoritmo do Springboot para configurar automaticamente as fontes de dados, a fonte de dados a ser configurada aqui é o Hikaricp.
O restante é como o desenvolvimento comum de Spring JDBCTemplet. Ao converter manualmente entre objetos e sql de banco de dados por programadores, os usuários podem ser adicionados, modificados, excluídos, correspondentes difusos, consulta precisa e outras funções.
Desenvolvimento da camada de negócios de dados
Definição de interface da camada de serviço de dados
pacote com.yanggaochao.springboot.learn.springbootjdbclearn.service; import com.yanggaochao.springboot.learn.springbootjdbclearn.domain.dao.userdo; importa java.util.LANG;/** ** ** ** ** **s service Layer 2018-03-09 */interface pública UserService {userdo add (usuário userdo); Userdo update (usuário userdo); Excluir booleano (Long ID); UserDo Locate (ID longo); Lista <SuperDo> MatchName (Nome da String);} Implementação da camada de serviço de dados
pacote com.yanggaochao.springboot.learn.springbootjdbclearn.service.impl; import com.yanggaochao.springboot.learn.springbootjdbclearn.dao.userdao; importação com.yanggaochao.springboot.learn.springbootjdbclearn.domain.dao.userdo; importar com.yanggaochao.springboot.learn.springbootjdbclearn.service.userService; importação.springframeswanwan.bean.bean.Bean.Bean.Blearn.service.uservice; org.springframework.stereotype.service; importar java.util.date; importar java.util.list;/*** Classe de implementação de camadas de negócios do usuário** @author yang gaochao* @since 2018-03-09*/ @servicePublic Class UserViceImPlemmentsMplements @AUTowired Public UserServiceImpl (UserDao UserDao) {this.UserDao = Userdao; } @Override public userdo add (userdo user) {user.setId (new date (). Gettime ()); if (userdao.add (usuário)) {return user; } retornar nulo; } @Override public userdo update (usuário userdo) {if (userdao.update (user)) {return location (user.getId ()); } retornar nulo; } @Override public boolean Delete (longo id) {return userdao.delete (id); } @Override Public Userdo Localização (ID longo) {return userdao.locate (id); } @Override Public List <Suserdo> MatchName (Nome da String) {return userdao.matchname (nome); }} Aqui, esta classe de implementação é declarada como uma classe de nível comercial por meio de uma anotação @Service. O Userdao da camada de persistência permite que o Springboot instancie esta classe de camada de negócios através do @Autowired e injete automaticamente a classe de camada de persistência correspondente nessa classe executiva.
Aqui, ao adicionar objetos do usuário, ao definir a identificação para o usuário, um número de milissegundos de tempo atual é simplesmente usado como identificação. Durante o processo de desenvolvimento real, este local precisa usar um mecanismo globalmente único para garantir que esse logotipo não possa ser repetido.
Desenvolvimento da camada de serviço externo
pacote com.yanggaochao.springboot.learn.springbootjdbclearn.web; import com.yanggaochao.springboot.learn.springbootjdbclearn.domain.bo.restCollectionResult; importação com.yanggaochao.springboot.learn.springbootjdbclearn.domain.dao.userdo; importar com.yanggaochao.springboot.learn.springbootjdbclearn.service.userService; importação.springframeswanwan.bean.bean.Bean.Bean.Blearn.service.uservice; org.springframework.web.bind.annotation.*; importar java.util.list;/*** interface de restos http do usuário** @author yang gaochao* @since 2018-03-09*/ @reestcontring @requestmapping ("API/V1/usuário) @RequestMapping (value = "/add", método = requestMethod.post) public RestItemResult <userdo> add (@RequestBody userdo Userdo) {RestItemResult <userdo> Result = new RestItemResult <> (); usuário = userservice.add (usuário); if (usuário! = null) {resultado.setItem (usuário); resultado.SetResult ("Sucesso"); } else {resultado.setMessage ("novo usuário falhou"); resultado.SetResult ("Falha"); } resultado de retorno; } @ReQuestMapping (value = "/update", método = requestMethod.post) public RestImResult <userdo> update (@RequestBody Userdo Userdo) {RestItemResult <userdo> result = new RestImResult <> (); usuário = userservice.update (usuário); if (usuário! = null) {resultado.setItem (usuário); resultado.SetResult ("Sucesso"); } else {resultado.setMessage ("Userdo não conseguiu modificar o usuário"); resultado.SetResult ("Falha"); } resultado de retorno; } @RequestMapping (value = "/Delete/{uuid}", Method = requestMethod.get) public RestItemResult <userdo> DELETE (@PathVariable Long uuid) {RestItemResult <Suserdo> Result = new RestItemResult <> (); if (userservice.delete (uuid)) {result.setResult ("sucessor"); } else {resultado.setMessage ("excluir o usuário falhado"); resultado.SetResult ("Falha"); } resultado de retorno; } @RequestMapping (value = "/locate/{uuid}", método = requestmethod.get) public RestItemResult <userdo> locate (@PathVariable long uuid) {RestItemResult <suserdo> resultado = new RestItemResult <> (); Userdo user = userservice.locate (uuid); if (usuário! = null) {resultado.setItem (usuário); resultado.SetResult ("Sucesso"); } else {resultado.setMessage ("Falha no usuário da consulta"); resultado.SetResult ("Falha"); } resultado de retorno; } @ReQuestMapping (value = "/match/{name}", método = requestMethod.get) public RestCollectionResult <Userdo> corresponde (@PathVariable String Name) {RestCollectionResult <userdo> result = new RestCollectionResult <> (); List <aseserDo> usuários = userservice.matchname (nome); resultado.setItems (usuários); resultado.SetResult ("Sucesso"); resultado de retorno; }} Aqui @RestController é usado para declarar que esta é uma classe de interface REST HTTP. A rota de chamada para cada interface é formada combinando @RequestMapping na classe e @RequestMapping no método. A propriedade do método em @RequestMapping no método declara o método chamado pelo HTTP. @RequestBody Anotation converte automaticamente o objeto JSON nos dados postais em um objeto Pojo. @PathVariable converte automaticamente dados no caminho da URL HTTP em parâmetros do método de serviço.
Teste de interface de repouso http
Teste o serviço HTTP REST é chamado através do httpclient do Apache Commons.
HTTP Resst chama classes auxiliares
package com.yanggaochao.springboot.learn.springbootjdbclearn;import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.httpclient.methods.getmethod; importar org.apache.commons.httpclient.methods.stringRequestentity; importação org.apache.commons.httpclient.params.httrpmethethreads; import.io.io.io. java.io.InputStreamReader; importar java.io.reader; importar java.util.map;/*** @author yang gaochao* @since 2018-03-09*/public classe htttpcientHelper {/*** use o método de obtenção para iniciar um htttp request***** O texto de resposta obtido após */ public string httpgetRequest (String url, map <string, string> cabeçalhos) {try {httpclient httppclient = new httpClient (); GetMethod método = new getMethod (URL); Method.SetRequestHeader ("Content-Type", "Application/JSON; Charset = UTF-8"); Method.getParams (). SetParameter (httpmethodparams.retry_handler, new DefaultTtpMethodretryHandler (3, false)); if (cabeçalhos! = null) {for (string key: headers.keyset ()) {method.setRequestHeader (chave, headers.get (key)); }} int statusCode = httpclient.executemethod (método); if (statusCode == 200) {return parseInputStream (métod.getResponseBodyasstream ()); } else {System.out.println (url + "status =" + statusCode); }} catch (Exceção e) {e.printStackTrace (); } retornar nulo; } /** * Use the post method to initiate an http request* * @param url The url of http to be accessed * @param data data in the request* @return The response text obtained after accessing http*/ public String httpPostRequest(String url, String data, Map<String, String> headers) { try { HttpClient httppclient = new HttpClient (); Método post -method = novo pós -método (URL); Method.SetRequestHeader ("Content-Type", "Application/JSON; Charset = UTF-8"); Method.SetRequestHeader ("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Wow64) Applewebkit/537.36 (KHTML, como Gecko) Chrome/34.0.1847.131 Safari/537.36"); if (cabeçalhos! = null) {for (string key: headers.keyset ()) {method.setRequestHeader (chave, headers.get (key)); }} Method.SetRequestEntity (new StringRequestEntity (Data, "JSON", "UTF-8")); int statuscode = httpclient.executemethod (método); if (statusCode == 200) {return parseInputStream (métod.getResponseBodyasstream ()); } else {System.out.println (url + "status =" + statusCode + parseInputStream (Method.getResponsoSabodyAssTream ())); }} catch (Exceção e) {e.printStackTrace (); } retornar nulo; } / *** Analisando os dados de texto de java.io.Reader** @param rd java.io.reader objeto* @throws A exceção lança um erro quando ocorre um erro* / private string parseReader (leitor rd) lança a exceção {buffaredreader Brd = new BufferReader (rd); Linha de string; StringBuilder respondeContext = new StringBuilder (); while ((line = Brd.ReadLine ())! = NULL) {RespondeSeSeContext.Append (Line) .Append ("/N"); } //rd.close (); if (responseContext.Length ()> 0) {ResponseseContext.deleteCharat (Responsecontext.Length () - 1); } return respondSeContext.toString (); } / *** Analisando os dados de texto do fluxo de entrada** @param é fluxo de entrada* @throws A exceção lança uma exceção quando ocorre um erro* / private string parseInputStream (InputStream) lança exceção {return parseReader (new buffarredreader (novo inputStreamReader (IS))); }} Aqui, implementamos principalmente o método de chamar o serviço HTTP REST usando métodos GET e POST.
Casos de teste
Use JUNIT para executar casos de teste. Para implementar o teste, adicionamos a seguinte dependência do Maven
<Depencency> <PuerpId> Commons-httpclient </roupidId> <TRAFACTID> commons-httpclient </stifactId> <versão> 3.1 </version> <cope> teste </scope> </dependency> <pendence> <puriid> org.codehaus. <cope> Teste </cope> </pendence>
pacote com.yanggaochao.springboot.learn.springbootjdbclearn; importar org.codehaus.jettison.json.jsonObject; importar org.junit.after; import org.junit.fore; import org.junit.test; import java.net.urlanc. java.util.list;/** * Descrição: * * @author yang gaochao * @since 2018-03-09 */classe pública userApitest {private string userAddurl = "http: // localhost: 3030/segurança/api/v1/user/add"; private string userlocateurl = "http: // localhost: 3030/segurança/api/v1/user/locate/"; private string userDeleteurl = "http: // localhost: 3030/segurança/api/v1/user/delete/"; private string userUpdateurl = "http: // localhost: 3030/segurança/api/v1/user/update"; private string usermatchurl = "http: // localhost: 3030/segurança/api/v1/user/match/"; JsonObject addUser = new jsonObject (); AddUserID longo = nulo; List <long> userIDs = new ArrayList <> (); @EBefore public void antes () lança exceção {addUser.put ("Nome", "Beautiful Sheep"); JsonObject addResultjson = novo JsonObject (novo httpclientHelper (). HttppoStReCest (userAddurl, addUser.toString (), null)); assert ("Sucesso" .Equals (addResultjson.getString ("resultado"))); addUserID = addResultjson.getjsonObject ("item"). getlong ("id"); JsonObject User = new JsonObject (); user.put ("Nome", "Pleasant Goat"); addResultjson = novo JsonObject (novo httpclientHelper (). httppoStReCest (userAddurl, user.toString (), null)); assert ("Sucesso" .Equals (addResultjson.getString ("resultado"))); userIDs.add (addResultjson.getjsonObject ("item"). getlong ("id")); user.put ("nome", "lobo cinza"); addResultjson = novo JsonObject (novo httpclientHelper (). httppoStReCest (userAddurl, user.toString (), null)); assert ("Sucesso" .Equals (addResultjson.getString ("resultado"))); userIDs.add (addResultjson.getjsonObject ("item"). getlong ("id")); } @Test public void testUpDateUser () lança exceção {jsonObject user = new jsonObject (); user.put ("Nome", "Smad Sheep"); user.put ("id", adduserID); novo httpclientHelper (). httpPosTReCest (userUpdateurl, user.toString (), null); JsonObject LocateresultJson = novo JsonObject (novo httpclientHelper (). HttpgetRequest (userlocateurl + adduserID, null)); assert (user.getString ("name"). igual a (locateresultjson.getjsonObject ("item"). getString ("nome"))); } @Test public void testMatchUser () lança exceção {JsonObject MatchResultJson = new JsonObject (novo httpclientHelper (). HttpgetRequest (usermatchurl + urlencoder.encode ("sheep", "utf-8"), Null); assert (matchResultjson.has ("itens") && matchResultjson.getjsonArray ("itens"). comprimento () == 2); MatchResultjson = novo JsonObject (novo httpclientHelper (). httpgetRequest (Usermatchurl + urlencoder.encode ("Wolf", "UTF-8"), nulo)); assert (matchResultjson.has ("itens") && matchResultjson.getjsonArray ("itens"). comprimento () == 1); } @After public void após () lança a exceção {if (addUserID! = Null) {jsonObject deleTeResultjson = new jsonObject (new httpclientHelper (). HttpgetRequest (userDeleteurl + addUserId, null); assert ("Sucesso" .Equals (deleTeSultjson.getString ("resultado"))); } para (Long UserID: UserIDS) {JsonObject DELETERESULTJSON = novo JsonObject (novo httpclientHelper (). httpgetRequest (userDeleteurl + userID, nulo)); assert ("Sucesso" .Equals (deleTeSultjson.getString ("resultado"))); }}} Aqui, dois casos de teste são declarados no @Test, um testa a função de modificação do usuário e o outro teste a função de consulta difusa do usuário. @Before declara os preparativos a serem feitos antes de executar cada caso de teste. Aqui, primeiro inserimos três dados no banco de dados e, ao mesmo tempo, também testamos a função de adicionar dados e consulta precisa. @After declara a limpeza após a execução de cada caso de teste. Aqui, excluímos principalmente os dados inseridos anteriormente. A função da exclusão do usuário é testada de maneira síncrona aqui.
PostScript
Aqui está um exemplo completo de trampolim usando o JDBC Templet. Se você tem experiência no uso do JDBC Templet na primavera, o principal objetivo de reduzir muito trabalho de configuração na primavera.
O código envolvido neste artigo foi enviado para o GitHub e você também pode baixá -lo localmente
Resumir
O acima é o conteúdo inteiro deste artigo. Espero que o conteúdo deste artigo tenha certo valor de referência para o estudo ou trabalho de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar. Obrigado pelo seu apoio ao wulin.com.