文章結(jié)構(gòu) 不使用任何依賴(lài)榕吼,手寫(xiě)——>使用springboot的jdbc——>使用lomok——>使用mybatis——>使用mybtis plus
一佑惠、不適用任何依賴(lài)砚哆,原生手寫(xiě)
建立一個(gè)demo數(shù)據(jù)庫(kù)
并運(yùn)行下面腳本建立一個(gè)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;
目錄結(jié)構(gòu)
此時(shí)我們引入的依賴(lài)只有:
spring-boot-starter-web
spring-boot-starter-test
這個(gè)是thymeleaf模板引擎,上面兩個(gè)是springboot web自帶的
spring-boot-starter-thymeleaf
這個(gè)是連接jar包
mysql-connector-java
application.propertites里面的配置
server.port=8080
以下是thymeleaf配置
spring.thymeleaf.cache=false
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.enabled=true
- 首先,我們需要在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)表user鲁森,包含id,userName,Password
- 建立domain文件夾振惰,里面放實(shí)體類(lèi)User,對(duì)應(yīng)數(shù)據(jù)庫(kù)中的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類(lèi)骑晶,這個(gè)類(lèi)作為連接數(shù)據(jù)庫(kù)的類(lèi)
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();
}
}
- 建立一個(gè)dao文件夾,里面放接口UserDao和它的實(shí)現(xiàn)類(lèi)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; } }
- 建立一個(gè)controller文件夾草慧,建立UserController類(lèi)
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>這里是從數(shù)據(jù)庫(kù)查詢(xún)出來(lái)的數(shù)據(jù)</p>
<table>
<tr>
<td th:text="${User.getId()}">ID</td>
<td th:text="${User.getUserName()}">用戶(hù)名</td>
<td th:text="${User.getPassword()}">密碼</td>
</tr>
</table>
</body>
</html>
- 打開(kāi) localhost
http://localhost:8080/userInfo
發(fā)現(xiàn)可以正常顯示數(shù)據(jù)
二、進(jìn)化之不寫(xiě)DBConnetion漫谷,以及一大堆麻煩的prepareStatement(上面的例子)
我們加入依賴(lài) spring-boot-starter-jdbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
然后仔雷,打開(kāi)application.properties文件,增加配置如下
目錄結(jié)構(gòu)
domain里面的User類(lèi)不變
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;
//注意這里加上的這個(gè)注解L蚴尽5拧!惕稻,只有加上這個(gè)注解竖共,才能被Spring管理bean包
//我們也就不需要像之前一樣在controller里面:UserDao userDao = new UserDaoImpl()
@Repository
public class UserDaoImpl implements UserDao {
//下面的這個(gè)步驟,其實(shí)就相當(dāng)于咱們之前新建一個(gè)DBConnection俺祠,建立連接公给。不同的是,他還包裝了一些方法
//這個(gè)JdbcTemplate不要new蜘渣,而是注入淌铐,相當(dāng)于,你告訴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類(lèi)
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.我們發(fā)現(xiàn)腿准,增加jdbc依賴(lài),使得我們不用寫(xiě)DBConnection類(lèi)了捂龄,且 查詢(xún)的時(shí)候释涛,直接寫(xiě)sql語(yǔ)句就行,不用像之前一樣寫(xiě)半年P(guān)reparedStatement 的處理倦沧。
2.注意的踩坑點(diǎn):bean的注入唇撬,我之前沒(méi)這個(gè)概念,不過(guò)大致理解了展融。首先窖认,我們先需要把一個(gè)類(lèi)聲明為bean(@Repository
),然后,我們@Autowired直接注入扑浸,免去了 new這個(gè)過(guò)程
三烧给、加入lombok依賴(lài)
在IDEA中添加lombok插件,然后引入下面依賴(lài)
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
這里只說(shuō)明一下很簡(jiǎn)單的用法:
修改domain文件夾下的User類(lèi)喝噪,把之前的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;
// }
}
然后重新運(yùn)行础嫡,我們會(huì)發(fā)現(xiàn)http://localhost:8080/userInfo出現(xiàn)了
其實(shí)就是找不到getter方法了。
然后我們使用lombok來(lái)解決
將User類(lèi)改為下面的酝惧,也就是加上幾個(gè)注解榴鼎。然后我們又發(fā)現(xiàn)網(wǎng)頁(yè)能沒(méi)有報(bào)錯(cuò)了。
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 幫我們省去了寫(xiě)setter晚唇,getter巫财,toString,等等哩陕,但我不喜歡用平项,因?yàn)橹灰诖a編寫(xiě)區(qū)域 右鍵->生成 ,就能生成這些方法悍及。闽瓢。很快,不費(fèi)力氣的并鸵。鸳粉。而且,你說(shuō)要是為了美觀园担,不要看起來(lái)一大堆的話(huà)届谈,那完全可以把這些方法折疊起來(lái)顯示,你看不到弯汰,心里也平靜艰山。。
四咏闪、Mybatis依賴(lài)引入
<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注解會(huì)提示Springboot這是一個(gè)bean(就像之前的 @service等等一樣)
//這里加上一個(gè)Component是因?yàn)镮DEA無(wú)法識(shí)別Mapper鸽嫂,
//所以纵装,它會(huì)在下面那一個(gè)步驟中報(bào)錯(cuò)——提示無(wú)法找找UserMapper 這個(gè)bean,但是實(shí)際上是能正常工作的据某!
@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類(lèi)里面修改為
@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無(wú)法識(shí)別導(dǎo)致的報(bào)錯(cuò)
@Mapper和@MapperScan 這兩個(gè)注解選一個(gè)就行,用了MapperScan之后,就不需要再UserMapper類(lèi)上加注解@Mapper了
在上面這步癣籽,我們看到其實(shí)這個(gè)Mapper就是取代了Dao挽唉,所以我們?cè)谑褂肕ybatis之后滤祖,就不需要建立Dao層了,取而代之的是Mapper層瓶籽,所以我們刪除Dao包匠童。或者我們把UserMapper放到Dao包里 放到dao包里
-基于XML格式
首先去掉UserMapper中的@insert等等類(lèi)似的注解
然后塑顺,在Resource下新建mapper文件夾汤求,在里面新建UserMapper.xml
<?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對(duì).xml的映射
#mybatis配置
mybatis.type-aliases-package=com.example.mydemo6.domain
mybatis.mapper-locations=classpath:mapper/*.xml 這一行是新增的
然后就可以運(yùn)行了
五、MybatisPlus的引入
這里僅僅是一個(gè)MybatisPlus的小例子严拒,我建議去官網(wǎng)學(xué)習(xí)中文的首昔,比我寫(xiě)的簡(jiǎn)單易懂
首先,先說(shuō)明一下MybatisPlus的作用糙俗,官網(wǎng)上又一大堆介紹,但目前我只用到幾點(diǎn) 以下摘自官網(wǎng)
無(wú)侵入:只做增強(qiáng)不做改變预鬓,引入它不會(huì)對(duì)現(xiàn)有工程產(chǎn)生影響巧骚,如絲般順滑
損耗小:?jiǎn)?dòng)即會(huì)自動(dòng)注入基本 CURD格二,性能基本無(wú)損耗劈彪,直接面向?qū)ο蟛僮?br> 強(qiáng)大的 CRUD 操作:內(nèi)置通用 Mapper、通用 Service顶猜,僅僅通過(guò)少量配置即可實(shí)現(xiàn)單表大部分 CRUD 操作沧奴,更有強(qiáng)大的條件構(gòu)造器,滿(mǎn)足各類(lèi)使用需求
通過(guò)官網(wǎng)的描述长窄,我們大概可以知道滔吠,MybatisPlus幫我們實(shí)現(xiàn)了最基礎(chǔ)的增刪查改,我們現(xiàn)在不需要寫(xiě)insert的sql語(yǔ)句了挠日。
好疮绷,我們用一下MybatisPlus
數(shù)據(jù)庫(kù)腳本 建立一個(gè)demo_mybatisPlus數(shù)據(jù)庫(kù)
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依賴(lài)
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
然后去Application.properties里面寫(xiě)
#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啟動(dòng)類(lèi)里面添加MapperScan
如下目錄結(jié)構(gòu)
其中,UserMapper接口代碼
//可以在這里添加@Component注解來(lái)消除IDEA報(bào)錯(cuò)
//注意下面繼承的BaseMapper后面有一個(gè)<User>
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.SpringbootMybatisPlus.domain.User;
public interface UserMapper extends BaseMapper<User> {
}
UserController類(lèi)中代碼
@Controller
public class UserController {
//這里可能會(huì)提示紅色下劃線報(bào)錯(cuò)嚣潜,咱們先不管這個(gè)冬骚!
//非要解決,就在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類(lèi)和user.html不變懂算。
通過(guò)這個(gè)例子我們可以發(fā)現(xiàn)只冻,MybatisPlus把對(duì)表的簡(jiǎn)單操作都封裝到了BaseMapper中了,我們繼承一下就ok了,我們不需要寫(xiě)一句sql語(yǔ)句
注意计技,此時(shí)我們使用的數(shù)據(jù)庫(kù)和之前的不一樣喜德,這是因?yàn)镸ybatisPlus它幫我們完成數(shù)據(jù)庫(kù)user表中 列 與實(shí)體類(lèi)User 私有屬性 建立一個(gè)映射,我們User類(lèi)里有id, userName, password酸役。
它自動(dòng)幫我們映射到id, user_name, password住诸,注意驾胆,如果數(shù)據(jù)庫(kù)的列名假如說(shuō)是username而不是user_name,那么會(huì)報(bào)錯(cuò)贱呐,提示找不到列名
好了丧诺,以上就是從不使用任何依賴(lài)最終到使用MybatisPlus的過(guò)程了。