文章目錄
- 1 簡單SQL語句
- 1.1 查詢
- 1.2 新增
- 1.3 修改
- 1.4 刪除
- 1.5 多表查詢
- 2 JDBC
- 2.1 什么是JDBC
- 2.2 什么是jar和maven
- 2.3 JDBC的使用
- 2.4 JDBC總結
- 3 mybatis
- 3.1 什么是ORM?為什么是ORM不是JDBC?
- 3.2 mybatis的使用
- 3.3 mybatis總結
- 4 mybatis與jdbc的邏輯相同處
環境配置
- jdk
- 視頻:https://b23.tv/WN28YAm
- 博客:只需四步完成java JDK1.8的下載安裝與配置【圖文詳解】
- maven
- 視頻:https://b23.tv/Lmo8rWl
- 博客:只需五步學會Maven 3.6.1的下載安裝與配置【圖文詳解】
- idea
- 公眾號:關注軟件科技管家回復idea2019
- idea配置jdk和maven
正文開始之前
問題:大家有沒有學習過這兩本書?
??為了開發時的層次清晰和分工明確,現如今基本上都將web應用的開發分成了五個層級結構,分別是表示層(Presentation)、控制/中介層(Controller/Mediator)、領域層(Domain)、數據持久層(Data Persistence)和數據源層(Data Source)。
??我們都知道,為了方便數據的存儲和查詢一般都是將數據存儲在數據庫中,我們我可以通過SQL的增刪改查語句來操作數據庫的所有記錄。以我的理解,數據持久化就是將程序代碼中對數據記錄的各種操作體現在數據庫中,下一次再去查詢數據庫的時候不會說查到的還是操作之前的數據。學習數據持久層之前,我們需要先來復習一下SQL語句。
1 簡單SQL語句
1.1 查詢
??講解SQL語句之前先演示如何使用Navicat導入SQL文件,創建表并添加記錄。如果沒有圖形化操作軟件的話可以使用dos窗口的命令導入https://blog.csdn.net/qq_37918817/article/details/81107433
SELECT 列名稱 FROM 表名稱;
查詢所有的記錄
SELECT * FROM singer;
倒序查詢所有的記錄
SELECT * FROM singer ORDER BY id DESC;
1.2 新增
INSERT INTO 表名稱 [列名稱…]
??VALUES (值…);
插入一條記錄
INSERT INTO singerVALUES(64,'張三',1,'/img/singerPic/1586091210109Sanna Nielsen.jpg','1984-11-27 00:00:00','平頂山','五音不全');
1.3 修改
UPDATE 表名稱
??SET 列名稱 = 新值 [,列名稱 = 新值,…]
??[WHERE <條件>];
修改id為64的introduction為歌聲甜美
UPDATE singerSET introduction='歌聲甜美'WHERE id=64;
1.4 刪除
DELETE FROM 表名稱
??[WHERE <條件>];
按照id刪除一條記錄
DELETE FROM singerWHERE id=64;
1.5 多表查詢
SELECT * FROM singer sr INNER JOIN song sg ON sr.id = sg.singer_idWHERE sr.name LIKE '王%'ORDER BY sr.id DESC;
工程創建
創建一個project
創建兩個maven的module分別是jdbc_test和mybatis_test
創建一個Spring Initializr模塊
2 JDBC
??為什么需要數據持久化技術?每次修改數據庫的時候直接使用SQL語句不就可以了?想象一下數據庫就像是一臺老式按鍵電視機,你家的沙發離這臺電視機的距離不近(當然距離取決于個人家庭情況)。各種CRUD操作就像是你父母的節目需求,你正在看《巴啦啦小魔仙》,你家父皇來了想看《譚談交通》,你家母后來了想要看《愛情保衛戰》,過了一會你家父皇又想看《金牌調解》……你是不是就需要來回跑到電視前面使用按鈕換臺,這時候有人問你有個東西叫遙控器,他可以在十米范圍內隨意換臺,你說你用不用?
2.1 什么是JDBC
??JDBC就是Java數據庫連接(Java Database Connectivity)是Java語言中用來規范客戶端程序如何來訪問數據庫的應用程序接口,提供了諸如查詢和更新數據庫中數據的方法。jdbc是sun公司為了在Java語言中提供對數據庫訪問的支持,而提供的一套用于訪問數據庫的標準Java類庫。我們通常說的JDBC是面向關系型數據庫的,今天講解的所有持久層框架也是以關型數據庫為例
2.2 什么是jar和maven
??之前java web的學習涉及到jar包也就是 Java Archive File文件,jar包其實是一種zip格式的文件,也就是壓縮包它里面的內容就是Java代碼,在項目的編寫階段導入jar包就可以使用里面提供的方法。不要認為jar包很是神秘,其實自己也可以創建一個jar包,只需要將寫好的Java代碼打成jar包再導入即可使用里面定義的方法。就好比你把一首歌的MP3文件放在壓縮包發給你的朋友,他解壓縮之后就可以聽了。jar包參考博客
??maven風格的項目,把所有的jar包都放在了本地"倉庫“ 里,然后哪個項目需要用到這個jar包,只需要給出jar包的名稱和版本號就行了(也就是常說的坐標),這樣就實現了jar包共享,避免每一個項目都單獨引入jar包帶來的麻煩。使用maven管理就相當于,直接發給你的朋友這首歌的鏈接。maven參考博客
??查詢依賴的網站:https://mvnrepository.com/
2.3 JDBC的使用
??首先需要導入數據庫連接依賴,這樣才能將Java代碼連接到數據庫
<!--數據庫連接依賴-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.32</version><scope>runtime</scope>
</dependency>
然后創建實體類,實體類中的字段與數據庫中的列名一一對應,數據類型也是相對應的
private Integer id;
private String name;
private Integer sex;
private String pic;
private Date birth;
private String location;
private String introduction;
public Singer() {
}public Singer(Integer id, String name, Integer sex, String pic, Date birth, String location, String introduction) {this.id = id;this.name = name;this.sex = sex;this.pic = pic;this.birth = birth;this.location = location;this.introduction = introduction;
}public Integer getId() {return id;
}public void setId(Integer id) {this.id = id;
}public String getName() {return name;
}public void setName(String name) {this.name = name;
}public Integer getSex() {return sex;
}public void setSex(Integer sex) {this.sex = sex;
}public String getPic() {return pic;
}public void setPic(String pic) {this.pic = pic;
}public Date getBirth() {return birth;
}public void setBirth(Date birth) {this.birth = birth;
}public String getLocation() {return location;
}public void setLocation(String location) {this.location = location;
}public String getIntroduction() {return introduction;
}public void setIntroduction(String introduction) {this.introduction = introduction;
}@Override
public String toString() {return "Singer{" +"id=" + id +", name='" + name + '\'' +", sex=" + sex +", pic='" + pic + '\'' +", birth=" + birth +", location='" + location + '\'' +", introduction='" + introduction + '\'' +'}';
}
因為后面使用jdbc操作會頻繁的連接數據庫,關閉數據庫釋放資源,于是將這兩個部分抽取成工具類中的靜態方法,直接調用
// 加載驅動并建立數據庫驅動
public static Connection getConnection() throws ClassNotFoundException, SQLException {String url = "jdbc:mysql://localhost:3306/music";String username = "root";String password = "123456";String driver = "com.mysql.jdbc.Driver";Class.forName(driver);return DriverManager.getConnection(url, username, password);
}// 關閉數據庫連接,釋放資源
public static void release(Statement statement, Connection conn) {if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}statement = null;}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}conn = null;}
}public static void release(ResultSet resultSet, Statement statement, Connection conn) {if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}resultSet = null;}release(statement, conn);
}
持久層CRUD的方法api和測試方法的測試
查詢所有記錄
/*** 查詢所有方法* @return*/
public ArrayList<Singer> selectAll() {Connection conn = null;Statement statement = null;ResultSet resultSet = null;ArrayList<Singer> singers = new ArrayList<Singer>();try {// 獲取數據庫連接conn = JDBCUtil.getConnection();// 獲得statement對象statement = conn.createStatement();//發送SQL語句String sql = "select * from singer;";System.out.println(sql);resultSet = statement.executeQuery(sql);// 處理查詢結果while (resultSet.next()) {Singer singer = new Singer();singer.setId(resultSet.getInt("id"));singer.setName(resultSet.getString("name"));singer.setSex(resultSet.getInt("sex"));singer.setPic(resultSet.getString("pic"));singer.setBirth(resultSet.getDate("birth"));singer.setLocation(resultSet.getString("location"));singer.setIntroduction(resultSet.getString("introduction"));singers.add(singer);return singers;}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {JDBCUtil.release(statement, conn);}return null;
}
// 查詢所有的
SingerDao singerDao = new SingerDao();
ArrayList<Singer> singers = singerDao.selectAll();
for (Singer singer : singers) {System.out.println(singer);
}
按照id查詢
/*** 按id查詢方法* @return*/
public Singer selectById(Integer id) {Connection conn = null;Statement statement = null;ResultSet resultSet = null;try {// 獲取數據庫連接conn = JDBCUtil.getConnection();// 獲得statement對象statement = conn.createStatement();//發送SQL語句String sql = "select * from singer where id=" + id +";";System.out.println(sql);resultSet = statement.executeQuery(sql);// 處理查詢結果while (resultSet.next()) {Singer singer = new Singer();singer.setId(resultSet.getInt("id"));singer.setName(resultSet.getString("name"));singer.setSex(resultSet.getInt("sex"));singer.setPic(resultSet.getString("pic"));singer.setBirth(resultSet.getDate("birth"));singer.setLocation(resultSet.getString("location"));singer.setIntroduction(resultSet.getString("introduction"));return singer;}return null;} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {JDBCUtil.release(statement, conn);}return null;
}
// 按照id查詢
SingerDao singerDao = new SingerDao();
Singer singer = singerDao.selectById(63);
System.out.println(singer);
新增
/*** insert操作* @param singer* @return*/
public boolean insert(Singer singer) {Connection conn = null;Statement statement = null;try {// 獲取數據庫連接conn = JDBCUtil.getConnection();// 獲得statement對象statement = conn.createStatement();//發送SQL語句SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String birth = sdf.format(singer.getBirth());String sql = "INSERT INTO singer" +" VALUES("+ singer.getId() + ",'"+ singer.getName() + "',"+ singer.getSex() + ",'"+ singer.getPic() + "','"+ birth + "','"+ singer.getLocation() + "','"+ singer.getIntroduction()+ "');";System.out.println(sql);int num = statement.executeUpdate(sql);if (num > 0) {return true;}return false;} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {JDBCUtil.release(statement, conn);}return false;
}
// 插入語句測試
// 先創建一個singer對象
Singer singer = new Singer();
singer.setId(64);
singer.setName("張三");
singer.setSex(1);
singer.setPic("/img/singerPic/1586091210109Sanna Nielsen.jpg");
singer.setBirth(new Date());
singer.setLocation("平頂山");
singer.setIntroduction("五音不全");
// 調用業務方法
SingerDao singerDao = new SingerDao();
boolean insert = singerDao.insert(singer);
System.out.println(insert);
修改
/*** update方法* @param singer* @return*/
public boolean update(Singer singer) {Connection conn = null;Statement statement = null;try {// 獲取數據庫連接conn = JDBCUtil.getConnection();// 獲得statement對象statement = conn.createStatement();//發送SQL語句String sql = "update singer set introduction='"+ singer.getIntroduction() + "' where id="+ singer.getId() + ";";System.out.println(sql);int num = statement.executeUpdate(sql);if (num > 0) {return true;}return false;} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {JDBCUtil.release(statement, conn);}return false;
}
// 修改
Singer singer1 = new Singer();
singer1.setId(64);
singer1.setIntroduction("歌聲甜美");
SingerDao singerDao = new SingerDao();
boolean update = singerDao.update(singer1);
System.out.println(update);
按照id刪除
/*** delete方法* @param id* @return*/
public boolean delete(Integer id) {Connection conn = null;Statement statement = null;try {// 獲取數據庫連接conn = JDBCUtil.getConnection();// 獲得statement對象statement = conn.createStatement();//發送SQL語句String sql = "delete from singer where id=" + id +";";System.out.println(sql);int num = statement.executeUpdate(sql);if (num > 0) {return true;}return false;} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {JDBCUtil.release(statement, conn);}return false;
}
// 刪除
SingerDao singerDao = new SingerDao();
boolean delete = singerDao.delete(64);
System.out.println(delete);
2.4 JDBC總結
使用JDBC進行CRUD的步驟:
- 導入數據庫連接依賴(jar包)
- 創建實體類
- 創建工具類(連接數據庫,釋放資源)
- 接口api方法(crud方法)
- 測試,創建方法類的對象,使用對象調用方法完成數據持久化操作
3 mybatis
??還以遙控器為例,假如說你家的客廳100平,之前的遙控的范圍不夠,你還是要走幾步,現在人家又說了,最新款的遙控器可以支持15米,你說你換不換?
mybatis是一種優秀的ORM框架
3.1 什么是ORM?為什么是ORM不是JDBC?
??ORM(Object Relational Mapping)即對象關系映射,是一種開發規范。將簡單的java對象(pojo)和數據庫表記錄進行映射,使得表中的記錄能和POJO一一對應。
??JDBC的劣勢:代碼繁瑣(sql語句的拼接發送接收),SQL拼接復雜且容易出錯,耦合度太高(SQL語句硬編碼到java程序,不利于后期的維護),性能問題。基于以上諸多問題,企業中的開發慢慢過度到了ORM框架,下面講到的mybatis框架就是一個十分優秀的ORM框架
3.2 mybatis的使用
maven項目的第一步,導依賴
<!--mybatis的依賴-->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version>
</dependency>
<!--數據庫連接依賴-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.32</version>
</dependency>
創建POJO類Singer
private Integer id;
private String name;
private Integer sex;
private String pic;
private Date birth;
private String location;
private String introduction;
使用lombok簡化開發
<!--lombok簡化實體類開發,如果之前沒有下載過依賴的同名插件的話需要下載安裝,然后重啟一下idea-->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version><optional>true</optional>
</dependency>
創建jdbc.properties數據庫連接配置
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/music
jdbc.username=root
jdbc.password=123456
創建mybatis.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!--加載配置文件--><properties resource="jdbc.properties"/><typeAliases><typeAlias type="com.xiaochen.domain.Singer" alias="singer"/></typeAliases><!--數據源環境--><environments default="development"><environment id="development"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!--加載映射文件--><mappers><mapper resource="mapper/SingerMapper.xml"/></mappers>
</configuration>
創建mapper接口
/*** 查詢全部* @Param void* @return ArraryList<Singer>*/
public ArraryList<Singer> queryAll();/*** 按id查* @param id* @return Singer */
public Singer queryById(Integer id);/*** 增* @param singer* @return boolean*/
public boolean save(Singer singer);/*** 改* @param singer* @return boolean*/
public boolean update(Singer singer);/*** 刪* @param id* @return boolean*/
public boolean delete(Integer id);
使用Spring整合mybatis先導入依賴
<!--spring整合mybatis-->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version>
</dependency>
spring框架整合mybatis需要滿足的四個條件
- mapper標簽的namespace = 接口全限定名
- 接口方法名 = mapper字標簽的id
- 接口方法參數類型 = mapper字標簽的parameterType
- 接口方法返回值類型 = mapper字標簽的resultType
滿足條件即可使用框架底層邏輯完成之前JDBC的數據庫連接,SQL語句發送等過程。現在按照四個條件構建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.xiaochen.mapper.SingerMapper"><!--查所有--><select id="queryAll" resultType="singer">select * from singer order by id desc ;</select><!--條件查--><select id="queryById" parameterType="int" resultType="singer">select * from singer where id = #{id};</select><!--增--><insert id="save" parameterType="singer">insert into singer values (#{id},#{name},#{sex},#{pic},#{birth},#{location},#{introduction});</insert><!--改--><insert id="update" parameterType="singer">update singer set introduction = #{introduction} where id = #{id};</insert><!--刪--><insert id="delete" parameterType="int">delete from singer where id = #{id};</insert>
</mapper>
測試類使用Junit進行測試
導依賴
<!--Junit測試依賴-->
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope>
</dependency>
/*** 查詢操作* @Param void* @return*/
@Test
public void queryTest() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);SqlSession session = sqlSessionFactory.openSession(true);SingerMapper mapper = session.getMapper(SingerMapper.class);ArrayList<Singer> singers = mapper.queryAll();for (Singer singer : singers) {System.out.println(singer);}session.close();
}
/*** 條件查詢操作* @Param void* @return*/
@Test
public void queryByIdTest() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);SqlSession session = sqlSessionFactory.openSession(true);SingerMapper mapper = session.getMapper(SingerMapper.class);Singer singer = mapper.queryById(63);System.out.println(singer);session.close();
}
/*** 插入操作* @Param void* @return*/
@Test
public void saveTest() throws IOException {Singer singer = new Singer();singer.setId(64);singer.setName("張三");singer.setSex(1);singer.setPic("/img/singerPic/1586091210109Sanna Nielsen.jpg");singer.setBirth(new Date());singer.setLocation("平頂山");singer.setIntroduction("五音不全");InputStream in = Resources.getResourceAsStream("mybatis.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);SqlSession session = sqlSessionFactory.openSession(true);SingerMapper mapper = session.getMapper(SingerMapper.class);boolean result = mapper.save(singer);System.out.println(result);queryTest();session.close();
}
/*** 更新操作* @Param void* @return*/
@Test
public void updateTest() throws IOException {Singer singer = new Singer();singer.setId(64);singer.setIntroduction("歌聲甜美");InputStream in = Resources.getResourceAsStream("mybatis.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);SqlSession session = sqlSessionFactory.openSession(true);SingerMapper mapper = session.getMapper(SingerMapper.class);boolean update = mapper.update(singer);System.out.println(update);queryTest();session.close();
}
/*** 刪除操作* @Param void* @return*/
@Test
public void deleteTest() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);SqlSession session = sqlSessionFactory.openSession(true);SingerMapper mapper = session.getMapper(SingerMapper.class);boolean result = mapper.delete(64);System.out.println(result);queryTest();session.close();
}
3.3 mybatis總結
mybatis開發步驟:
- 導依賴
- 創建實體類
- 配置文件
- spring框架整合mybatis需要滿足的四個條件
- mapper標簽的namespace = 接口全限定名
- 接口方法名 = mapper字標簽的id
- 接口方法參數類型 = mapper字標簽的parameterType
- 接口方法返回值類型 = mapper字標簽的resultType
- 按照條件創建接口和映射文件
- 測試類讀取配置文件創建mapper對象,調用方法
4 mybatis與jdbc的邏輯相同處
??將mybatis對標jdbc可以發現,使用流程大體上是一樣的,導入數據庫連接依賴,創建實體類,創建持久層api方法供測試調用(mybatis將SQL抽取成了映射文件),測試類調用api并完成相應的操作。