Spring Boot数据库交互

在上篇文件的基础上进行开发,简单实现一下增、查操作,删除和修改类似,作为一个demo就暂时不做重复工作了,实现原理类似

项目结构

新建MySQL数据库相关信息

-- 建数据库
create database if not exists test;

-- 建表
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `password` varchar(30) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

maven中增加配置四个架包

     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- 非常重要,缺少这个架包,会导致html无法正常解析,会产生Whitelabel Error Page错误,并且控制层传值无法正常获取-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

配置文件 application.properties

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=true&allowMultiQueries=true&serverTimezone=Asia/Hong_Kong
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 60000
# 暂时用不到
spring.mvc.view.prefix=/templates/
# 暂时用不到
spring.mvc.view.suffix=.html

建立实体类 User.java

package com.springboot.demo.domain;

import javax.persistence.*;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String password;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

建立持久层接口 UserDao.java

package com.springboot.demo.dao;

import com.springboot.demo.domain.User;

import java.util.List;

public interface UserDao {
    /**
     * 插入一个用户
     * @param user
     * @return
     */
    Long insertUser(User user);

    /**
     * 通过用户名获取用户,用户名唯一
     * @param name
     * @return
     */
    User getUserByName(String name);

    /**
     * 列出所有的用户信息
     * @return
     */
    List<User> getAllUsers();

    /**
     * 删除暂不实现
     * @param user
     */
    void delete(User user);

    /**
     * 修改暂不实现
     * @param user
     */
    void update(User user);
}

实现持久层接口 UserRepository.java

package com.springboot.demo.domain;

import com.springboot.demo.dao.UserDao;
import com.springboot.demo.utils.RowMapperFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class UserRepository implements UserDao {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Override
    public User getUserByName(String name) {
        String sql = "select * from User user where name=:name";
        Map<String, Object> param = new HashMap<>();
        param.put("name", name);
        return jdbcTemplate.queryForObject(sql, param, RowMapperFactory.getInstance(User.class));
    }

    @Override
    public Long insertUser(User user) {
        String sql = "insert into user(name, password) values(:name, :password)";
        Map<String, Object> param = new HashMap<>();
        param.put("name", user.getName());
        param.put("password", user.getPassword());
        return (long) jdbcTemplate.update(sql, param);
    }

    @Override
    public List<User> getAllUsers() {
        String sql = "select * from User user";
        Map<String, Object> param = new HashMap<>();
        return jdbcTemplate.query(sql, param, RowMapperFactory.getInstance(User.class));
    }

    @Override
    public void delete(User user) {

    }

    @Override
    public void update(User user) {

    }
}

建立服务层类 UserService.java

package com.springboot.demo.service;

import com.springboot.demo.dao.UserDao;
import com.springboot.demo.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    /**
     * 通过用户名获取用户,用户名唯一
     * @param name
     * @return
     */
    public User getUserByName(String name) {
       return userDao.getUserByName(name);
    }

    /**
     * 插入一个用户
     * @param user
     * @return
     */
    public Long insertUser(User user) {
        User userDb = getUserByName(user.getName());
        if(Objects.isNull(userDb))
            return userDao.insertUser(user);
        else return userDb.getId();
    }

    /**
     * 列出所有的用户信息
     * @return
     */
    public List<User> getAllUsers() {
        return userDao.getAllUsers();
    }
}

建立控制层类 LoginController.java

package com.springboot.demo.web;

import com.springboot.demo.domain.User;
import com.springboot.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;
import java.util.Objects;

@Controller
@RequestMapping("/admin")
public class LoginController {

    @Autowired
    private UserService userService;

    @RequestMapping(value="/userInfo")
    public String userInfo(Model model) {
        String managerName = "Jef";
        User userDb = userService.getUserByName(managerName);
        if(Objects.isNull(userDb)) {
            userDb = new User();
            userDb.setName(managerName);
            userDb.setPassword("123");
            userService.insertUser(userDb);
        }
        model.addAttribute("manager", managerName);
        List<User> users = userService.getAllUsers();
        model.addAttribute("users", users);
        return "index";
    }
}

工具类 RowMapperFactory.java

package com.springboot.demo.utils;

import org.springframework.jdbc.core.RowMapper;

import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

public class RowMapperFactory {

    public static <K> RowMapper<K> getInstance(Class<K> clazz) {
        return getRowMapper(clazz);
    }

    public static <K> RowMapper<K> getRowMapper(Class<K> clazz) {

        return new RowMapper<K>() {

            private AutoRowMapper<K> rm = new AutoRowMapper(clazz);

            @Override
            public K mapRow(ResultSet rs, int rowNum) throws SQLException {
                try {
                    return rm.mapRow(rs, rowNum, clazz.newInstance());
                }
                catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        };
    }

    /**
     * 这是一个用于简化 rowMapper 的编写辅助类。
     * <p/>
     * 本类会自动跳过 entity 中存在,但是在查询语句中不存在的列。
     *
     * @param <T> entity type
     */
    private static class AutoRowMapper<T> {

        private Map<String, String> colName2SetterMap = new HashMap<>(); // 数据列名到 setter 名称的映射
        private Map<String, Method> setterMap = new HashMap<>();         // setter 名称到 setter 方法的映射
        private Map<String, String> setterParamMap = new HashMap<>();    // setter 名称到 setter 参数类型的映射

        /**
         * 初始化
         *
         * @param t 实体类的类对象
         */
        protected <T> AutoRowMapper(Class<T> t) {
            Method[] ms = t.getMethods();
            for (int i = 0; i < ms.length; i++) {
                String name = ms[i].getName();
                if (name.startsWith("set") && ms[i].getParameterCount() == 1) {
                    setterMap.put(name, ms[i]);
                    setterParamMap.put(name, ms[i].getGenericParameterTypes()[0].getTypeName());
                    colName2SetterMap.put(setterToColName(name), name);
                }
            }
        }

        /**
         * 在子类中,要实现的 RowMapper.mapRow 中掉用此方法。
         *
         * @param rs     结果集
         * @param rowNum 结果集行号
         * @param t      entity 对象,用于装填查询结果行数据
         * @return 传入的 entity 对象
         */
        public T mapRow(ResultSet rs, int rowNum, T t) {

            for (String col : colName2SetterMap.keySet()) {
                try {
                    int index = rs.findColumn(col); // 如果找不到列,就会抛出异常
                    String setterName = colName2SetterMap.get(col);
                    inject(setterMap.get(setterName), setterParamMap.get(setterName), rs, index, t);
                } catch (SQLException ex) {
                    continue;
                }
            }
            return t;
        }

        /**
         * 把 setter 名称转换为列名。如 setCreatedOn --> created_on
         */
        private static String setterToColName(String setterName) {
            String property = setterName.substring(3, setterName.length());
            StringBuilder sb = new StringBuilder().append(property.charAt(0));
            for(int i = 1; i < property.length(); i++) {
                char c = property.charAt(i);
                if(Character.isUpperCase(c)) {
                    sb.append("");
                }
                sb.append(c);
            }
            return sb.toString().toLowerCase();
        }

        /**
         * 把指定列按类型注入 entity.
         * <p/>
         * 目前支持的类字段类型有:
         * <pre>
         * java.lang.Boolean    boolean
         * java.lang.Byte       byte
         * java.lang.Long       long
         * java.lang.Integer    int
         * java.lang.Short      short
         * java.lang.Float      float
         * java.lang.Double     double
         * java.lang.Date
         * java.lang.String
         * java.sql.Blob
         * java.math.BigDecimal
         * </pre>
         */
        private void inject(Method getter, String fieldType, ResultSet rs, int index, T t) {
            try {

                switch (fieldType) {
                    case "java.lang.Boolean":  // 布尔值
                    case "boolean":
                        getter.invoke(t, rs.getBoolean(index));
                        break;
                    case "java.lang.Byte":     // 字节
                    case "byte":
                        getter.invoke(t, rs.getByte(index));
                        break;
                    case "java.lang.Long":     // Long
                    case "long":
                        getter.invoke(t, rs.getLong(index));
                        break;
                    case "java.lang.Integer":  // Int
                    case "int":
                        getter.invoke(t, rs.getInt(index));
                        break;
                    case "java.lang.Short":    // Short
                    case "short":
                        getter.invoke(t, rs.getShort(index));
                        break;
                    case "java.lang.Float":    // Float
                    case "float":
                        getter.invoke(t, rs.getFloat(index));
                        break;
                    case "java.lang.Double":   // Double
                    case "double":
                        getter.invoke(t, rs.getDouble(index));
                        break;
                    case "java.lang.Date":
                        getter.invoke(t, rs.getDate(index));
                        break;
                    case "java.lang.String":
                        getter.invoke(t, rs.getString(index));
                        break;
                    case "java.sql.Blob":
                        getter.invoke(t, rs.getBlob(index));
                        break;
                    case "java.math.BigDecimal":
                        getter.invoke(t, rs.getBigDecimal(index));
                        break;
                    default:
                        getter.invoke(t, rs.getObject(index));
                        break;
                }
            }
            catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

页面展示文件 index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html">
    <title>Spring Boot User</title>
    <link rel="stylesheet" type="text/css" media="all" href="/css/bootstrap.min.css">
</head>
<body>
<!-- Thymeleaf 常用属性进行取值 -->
<h1>取控制层传过来的值</h1>
<h1>Manager = </h1>
<td class="text" th:text="${manager}" ></td>
<h1>测试JS是否有效</h1>
<p id="testId"></p>
<h1>把所有用户信息列出来</h1>
<ul class="timeline">
    <div th:each="entry, status : ${users}">
        <li th:attr="class=${status.odd} ? ‘timeline-inverted‘ : ‘‘">
            <div class="tl-circ"></div>
            <div class="timeline-panel">
                <div class="tl-heading">
                    <h4><span th:text="${entry.name}">TITLE</span></h4>
                </div>
            </div>
        </li>
    </div>
</ul>
<script src="/js/jquery-3.1.1.js"></script>
<script>
    $(document).ready(function () {
        $( "#testId" ).text( "Test Id" );
    });
</script>
</body>
</html>

其中css、js文件,拷贝文件名去搜索可以直接进入他们的官网下载

启动Spring Boot项目的类 DemoApplication.java

package com.springboot.demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@EnableAutoConfiguration
@SpringBootApplication
// 自动扫描下面配置的包
@ComponentScan({"com.springboot.demo"})
public class DemoApplication {
    private static final Logger log = LoggerFactory.getLogger(DemoApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

运行结果

http://localhost:8080/admin/userInfo

原文地址:https://www.cnblogs.com/tufujie/p/8952819.html

时间: 2024-08-30 13:13:44

Spring Boot数据库交互的相关文章

Spring Boot 数据库操作

# Spring Boot 数据库操作 数据源配置 Oracle 数据源配置 参考<搭建Spring Boot项目-六> MySQL 数据源配置 在pom中添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <d

spring boot数据库操作汇总

1 关于orm orm即object relational mapping,对象关系映射,即将数据库中的表映射成对象. 常用的orm有以下: mybatis spring jdbc template hibernate spring data jpa 如果在spring boot项目中用的是mybatis的话,引入依赖mybatis-spring-boot-starter: 如果在spring boot项目中用的是spring jdbc template的话,引入的依赖spring-boot-s

spring boot +mybatis 操作sqlite数据库

前言 第一次写博客,以前遇到技术问题都是百度,google搜索也解决了我不少问题,需要搜索老半天七拼八凑才能找到解决方案,一直使用从不生产对学习的过程总结也没记录. 今天写该博客主要是让自己更学入了解spring boot里面的机制,同时让新人少走弯路. 环境 java8+spring boot 数据库:sqlite ORM框架:mybatis sqlite 不多介绍了,基于文件格式的数据库,无需安装数据库执行引擎,方便部署. 主要依赖与版本 <groupId>org.mybatis.spri

最全spring boot视频系列,你值得拥有

================================== 从零开始学Spring Boot视频 ================================== àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share [截止到201

spring boot之从零开始开发自己的网站

概述 首先要感谢两位大神,该项目的想法来源自tale和MyBlog,本项目的想法. 做了一些改造,增加了一些功能和一些代码的重构,并且更换了博客主题. 关于项目,对于开发的练手项目,能够工程化,严谨一些. 关于文档,本文主要中从项目需求,项目设计的方式来阐述. 如何从零开始,使用springboot开发项目. 记录一些在开发过程中遇到的一些问题,总结开发技巧 接下来,会以需求和设计方式来阐述 效果图 首页展示 文章编辑 文章管理 项目需求 项目背景 对于刚学习springboot的同学,最好的就

43. Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】

[视频&交流平台] àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share à SpringCloud视频 http://study.163.com/course/introduction.htm?courseId=1004638001&a

spring boot 多数据源配置(多种数据库)

最近一段时间在使用spring boot开发项目,其中有一个项目用到了多数据源的配置,网上的资料还是不太多,走了好多才找到一个合适的,把自己写的分享一下,做个笔记,以后也许有用,第一次写博客,不好勿喷!! 首先介绍下我的业务场景,此项目用到了两种数据库,一个是mysql,另一个是sqlserver, 首先第一步需要在application.yml中将多数据源的配置信息进行配置, mysql数据源: spring: datasource: driverClassName: com.mysql.jd

spring boot 登录注册 demo (二) -- 数据库访问

通过data-jpa来访问数据库 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mys

Spring Boot 连接MySql数据库

Spring Boot 以后也许会成为入门Spring的首选! 记一下Spring Boot 成功连接Mysql数据库的方法步骤! 一.新建Maven工程,不全Maven所需文件夹,在pom.xml引入SpringBoot的依赖包!可以参照:http://www.cnblogs.com/liangblog/p/5207855.html 二.有两种方法与数据库建立连接,一种是集成Mybatis,另一种用JdbcTemplate (1).用JdbcTemplate <dependency> <