美文网首页
SpringBoot 数据库连接管理

SpringBoot 数据库连接管理

作者: 小星star | 来源:发表于2020-03-22 15:31 被阅读0次

    文章结构 不使用任何依赖,手写——>使用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
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <p>这里是从数据库查询出来的数据</p>
        <table>
            <tr>
                <td th:text="${User.getId()}">ID</td>
                <td th:text="${User.getUserName()}">用户名</td>
                <td th:text="${User.getPassword()}">密码</td>
            </tr>
        </table>
    </body>
    </html>
    
    
    1. 打开 localhost
      http://localhost:8080/userInfo
      发现可以正常显示数据

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

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

    然后,打开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插件,然后引入下面依赖

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    

    这里只说明一下很简单的用法:
    修改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依赖引入

            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.0.0</version>
            </dependency>
    

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.mydemo6.mapper.UserMapper">
        <resultMap id="BaseResultMap" type="com.example.mydemo6.domain.User">
            <id column="id" property="id" jdbcType="INTEGER"></id>
            <result column="username" property="userName" jdbcType="VARCHAR"></result>
            <result column="password" property="password" jdbcType="VARCHAR"></result>
        </resultMap>
    
        <sql id="Base_Column_List">
            id, username, password
        </sql>
    
        <select id="selectById" parameterType="INTEGER" resultMap="BaseResultMap">
            SELECT
            <include refid="Base_Column_List"></include>
            FROM user
            WHERE id = #{id}
        </select>
    </mapper>
    

    然后去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依赖

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.3.1.tmp</version>
            </dependency>
    

    然后去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后面有一个<User>
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.example.SpringbootMybatisPlus.domain.User;
    
    public interface UserMapper extends BaseMapper<User> {
    }
    
    

    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 数据库连接管理

          本文链接:https://www.haomeiwen.com/subject/coyuyhtx.html