文章结构 不使用任何依赖,手写——>使用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
- 首先,我们需要在数据库中创建一个表user,包含id,userName,Password
- 建立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
- 在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();
}
}
- 建立一个dao文件夹,里面放接口UserDao和它的实现类UserDaoImpl
UserDao
UserDaoImplimport com.example.fictionsystem.domain.User; import java.sql.SQLException; public interface UserDao { public User getUserById(Integer id) throws SQLException; }
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; } }
- 建立一个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了
}
}
- 在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>
- 打开 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出现了
其实就是找不到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;
}
image.png我的理解是lombok 帮我们省去了写setter,getter,toString,等等,但我不喜欢用,因为只要在代码编写区域 右键->生成 ,就能生成这些方法。。很快,不费力气的。。而且,你说要是为了美观,不要看起来一大堆的话,那完全可以把这些方法折叠起来显示,你看不到,心里也平静。。
四、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的过程了。
网友评论