SpringBoot 数据库连接管理

文章结构 不使用任何依赖,手写——>使用springboot的jdbc——>使用lomok——>使用mybatis——>使用mybtis plus

一、不适用任何依赖,原生手写
建立一个demo数据库
并运行下面脚本建立一个user表

CREATE TABLE `user`  (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

目录结构


image.png

此时我们引入的依赖只有:

spring-boot-starter-web
spring-boot-starter-test
这个是thymeleaf模板引擎,上面两个是springboot web自带的
spring-boot-starter-thymeleaf
这个是连接jar包
mysql-connector-java

application.propertites里面的配置

server.port=8080
以下是thymeleaf配置
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.enabled=true

  1. 首先,我们需要在数据库中创建一个表user,包含id,userName,Password
  2. 建立domain文件夹,里面放实体类User,对应数据库中的user表。
public class User {
    private Integer id;
    private String userName;
    private String password;

    public Integer getId() {
        return id;
    }

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

    等setter 和 getter
  1. 在util里面建立DBConnection类,这个类作为连接数据库的类
public class DBConnection {
    private String driver = "com.mysql.cj.jdbc.Driver";
    private String url = "jdbc:mysql://localhost/demo?useSSL=false&serverTimezone=UTC";
    private Connection conn = null;

    public DBConnection() {
        try{
            System.setProperty("jdbc.drivers", driver);
            this.conn = DriverManager.getConnection(url, "root", "justTest");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public Connection getConn() {
        return this.conn;
    }

    public void closeConn() throws SQLException {
        this.conn.close();
    }
}
  1. 建立一个dao文件夹,里面放接口UserDao和它的实现类UserDaoImpl
    UserDao
    import com.example.fictionsystem.domain.User;
    
    import java.sql.SQLException;
    
    public interface UserDao {
        public User getUserById(Integer id) throws SQLException;
    
    }
    
    UserDaoImpl
    import com.example.fictionsystem.dao.UserDao;
    import com.example.fictionsystem.domain.User;
    import com.example.fictionsystem.util.DBConnection;
    
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class UserDaoImpl implements UserDao {
    
        @Override
        public User getUserById(Integer id) throws SQLException {
            User user = new User();
    
            DBConnection conn = null;
            PreparedStatement pstm = null;
            ResultSet rs = null;
            String sql = "Select * from user where id = ?";
    
            try{
                conn = new DBConnection();
                pstm = conn.getConn().prepareStatement(sql);
                pstm.setInt(1, id);
                rs = pstm.executeQuery();
    
                while (rs.next()){
                    user.setId(rs.getInt(1));
                    user.setUserName(rs.getString(2));
                    user.setPassword(rs.getString(3));
                }
                if(pstm != null) {
                    pstm.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
        return user;
        }
    }
    
  2. 建立一个controller文件夹,建立UserController类
import com.example.fictionsystem.dao.UserDao;
import com.example.fictionsystem.dao.impl.UserDaoImpl;
import com.example.fictionsystem.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.sql.SQLException;

@Controller
public class UserController {

    @RequestMapping("/userInfo")
    public String UserInfo(Model model) throws SQLException {
        UserDao userDao = new UserDaoImpl();
        User user = userDao.getUserById(1);
        model.addAttribute("User", user);
        return "user";  //这意味着,把model的信息也传给了templates文件夹下的user.html了
    }
}
  1. 在templates文件夹下建立user.html



    
    Title


    

这里是从数据库查询出来的数据

ID 用户名 密码
  1. 打开 localhost
    http://localhost:8080/userInfo
    发现可以正常显示数据

二、进化之不写DBConnetion,以及一大堆麻烦的prepareStatement(上面的例子)
我们加入依赖 spring-boot-starter-jdbc

        
            org.springframework.boot
            spring-boot-starter-jdbc
        

然后,打开application.properties文件,增加配置如下


image.png

目录结构


image.png

domain里面的User类不变
dao里面的UserDao接口

import com.example.mydemo2.domain.User;

import java.sql.SQLException;

public interface UserDao {

    User getUserById(Integer id) throws SQLException;
}

dao里面的impl文件夹下的UserDaoImpl

import com.example.mydemo2.dao.UserDao;
import com.example.mydemo2.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

//注意这里加上的这个注解!!!,只有加上这个注解,才能被Spring管理bean包
//我们也就不需要像之前一样在controller里面:UserDao userDao = new UserDaoImpl() 
@Repository
public class UserDaoImpl implements UserDao {

    //下面的这个步骤,其实就相当于咱们之前新建一个DBConnection,建立连接。不同的是,他还包装了一些方法
    //这个JdbcTemplate不要new,而是注入,相当于,你告诉spring我要用JdbcTemplate,你帮我new一下
    private final JdbcTemplate jdbcTemplate;
    @Autowired
    public UserDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate =jdbcTemplate;
    }

    @Override
    public User getUserById(Integer id) {
        return (User) jdbcTemplate.queryForObject("Select * from user where id =" + id, new BeanPropertyRowMapper(User.class));
    }

}

controller包下的UserController类

import com.example.mydemo2.dao.UserDao;
import com.example.mydemo2.domain.User;
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.sql.SQLException;

@Controller
public class UserController {

    //这是不推荐的注入方式
    //@Autowired
    //private UserDao userDao;

    //这是推荐的注入方式
    private UserDao userDao;
    @Autowired
    public UserController(UserDao userDao) {
        this.userDao = userDao;
    }


    @RequestMapping("/userInfo")
    public String queryById(Model model) throws SQLException {
        User user = userDao.getUserById(1);
        model.addAttribute("User", user);

        return "user";
    }
}

1.我们发现,增加jdbc依赖,使得我们不用写DBConnection类了,且 查询的时候,直接写sql语句就行,不用像之前一样写半年PreparedStatement 的处理。
2.注意的踩坑点:bean的注入,我之前没这个概念,不过大致理解了。首先,我们先需要把一个类声明为bean(@Repository
),然后,我们@Autowired直接注入,免去了 new这个过程

三、加入lombok依赖
在IDEA中添加lombok插件,然后引入下面依赖

        
            org.projectlombok
            lombok
            true
        

这里只说明一下很简单的用法:
修改domain文件夹下的User类,把之前的setter和getter注释掉

public class User {
    private Integer id;
    private String userName;
    private String password;

//    public Integer getId() {
//        return id;
//    }
//
//    public void setId(Integer 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;
//    }
}

然后重新运行,我们会发现http://localhost:8080/userInfo出现了

image.png

其实就是找不到getter方法了。

然后我们使用lombok来解决
将User类改为下面的,也就是加上几个注解。然后我们又发现网页能没有报错了。

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@NoArgsConstructor
public class User {
    private Integer id;
    private String userName;
    private String password;
}

我的理解是lombok 帮我们省去了写setter,getter,toString,等等,但我不喜欢用,因为只要在代码编写区域 右键->生成 ,就能生成这些方法。。很快,不费力气的。。而且,你说要是为了美观,不要看起来一大堆的话,那完全可以把这些方法折叠起来显示,你看不到,心里也平静。。

image.png

四、Mybatis依赖引入

        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.0.0
        

Application.properties 增加一行

#mybatis配置
mybatis.type-aliases-package=com.example.mydemo6.domain

Mybatis有两种方式:基于注解;基于XML
新建mapper包->UserMapper接口
-基于注解

import com.example.mydemo6.domain.User;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Component;

//注意这里的注解,Mapper注解会提示Springboot这是一个bean(就像之前的 @service等等一样)
//这里加上一个Component是因为IDEA无法识别Mapper,
//所以,它会在下面那一个步骤中报错——提示无法找找UserMapper 这个bean,但是实际上是能正常工作的!
@Mapper
@Component
public interface UserMapper{

    @Select("select * from user where id = #{id}")
    User selectById(Integer id);

    @Insert("insert into user(username, password) values(#{userName}, #{password})")
    int insert(User user);

    @Delete("delete from user where id = #{id}")
    int deleteById(Integer id);

    @Update("update user set username = #{userName}, password = #{password} where id = #{id}")
    int update(User user);

}

UserController类里面修改为

@Controller
public class UserController {

//    private UserDao userDao;
//    @Autowired
//    public UserController(UserDao userDao) {
//        this.userDao = userDao;
//    }

    private UserMapper userMapper;
    @Autowired
    public UserController(UserMapper userMapper) {
        this.userMapper = userMapper;
    }


    @RequestMapping("/userInfo")
    public String queryById(Model model) throws SQLException {
        //User user = userDao.getUserById(1);
        User user = userMapper.selectById(1);
        model.addAttribute("User", user);

        return "user";
    }
}

注意在UserMapper力添加@Component注解,防止IDEA无法识别导致的报错
@Mapper和@MapperScan 这两个注解选一个就行,用了MapperScan之后,就不需要再UserMapper类上加注解@Mapper了
在上面这步,我们看到其实这个Mapper就是取代了Dao,所以我们在使用Mybatis之后,就不需要建立Dao层了,取而代之的是Mapper层,所以我们删除Dao包。或者我们把UserMapper放到Dao包里 放到dao包里

-基于XML格式
首先去掉UserMapper中的@insert等等类似的注解
然后,在Resource下新建mapper文件夹,在里面新建UserMapper.xml


image.png



    
        
        
        
    

    
        id, username, password
    

    

然后去Application.properties里面增加Mybatis对.xml的映射

#mybatis配置
mybatis.type-aliases-package=com.example.mydemo6.domain
mybatis.mapper-locations=classpath:mapper/*.xml  这一行是新增的

然后就可以运行了
五、MybatisPlus的引入
这里仅仅是一个MybatisPlus的小例子,我建议去官网学习中文的,比我写的简单易懂

首先,先说明一下MybatisPlus的作用,官网上又一大堆介绍,但目前我只用到几点 以下摘自官网
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求

通过官网的描述,我们大概可以知道,MybatisPlus帮我们实现了最基础的增删查改,我们现在不需要写insert的sql语句了。
好,我们用一下MybatisPlus
数据库脚本 建立一个demo_mybatisPlus数据库

CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

首先引入MybatisPlus依赖

        
            com.baomidou
            mybatis-plus-boot-starter
            3.3.1.tmp
        

然后去Application.properties里面写

#jdbc配置
spring.datasource.url=jdbc:mysql://localhost/demo_mybatisPlus?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=justTest
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

然后去Springboot启动类里面添加MapperScan


image.png

如下目录结构


image.png

其中,UserMapper接口代码

//可以在这里添加@Component注解来消除IDEA报错
//注意下面继承的BaseMapper后面有一个
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.SpringbootMybatisPlus.domain.User;

public interface UserMapper extends BaseMapper {
}

UserController类中代码

@Controller
public class UserController {

    //这里可能会提示红色下划线报错,咱们先不管这个!
    //非要解决,就在UserMapper的接口上面添加@Component注解
    @Autowired
    private UserMapper userMapper;

    @RequestMapping("/userInfo")
    public String queryById(Model model) {
        User user = userMapper.selectById(1);
        model.addAttribute("User", user);

        return "user";
    }
}

User类和user.html不变。

通过这个例子我们可以发现,MybatisPlus把对表的简单操作都封装到了BaseMapper中了,我们继承一下就ok了,我们不需要写一句sql语句
注意,此时我们使用的数据库和之前的不一样,这是因为MybatisPlus它帮我们完成数据库user表中 列 与实体类User 私有属性 建立一个映射,我们User类里有id, userName, password。
它自动帮我们映射到id, user_name, password,注意,如果数据库的列名假如说是username而不是user_name,那么会报错,提示找不到列名

好了,以上就是从不使用任何依赖最终到使用MybatisPlus的过程了。

你可能感兴趣的:(SpringBoot 数据库连接管理)