MyBatis 學習(一)
一、MyBatis
1、MyBatis 介紹(百度)
MyBatis 是一款優秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。
2、MyBatis 歷史(百度)
MyBatis前世今生:MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis ,2013年11月遷移到Github。
iBATIS一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAOs)。
3、MyBatis的優勢:
1、MyBatis 是支持普通 SQL查詢,存儲過程和高級映射的優秀持久層框架。
2、MyBatis 消除了幾乎所有的JDBC代碼和參數的手工設置以及結果集的檢索。
3、MyBatis 使用簡單的XML或註解用於配置和映射,將接口和 Java 的POJOs(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。
二、ORM
1、ORM介紹
對象關系映射(Object Relational Mapping,簡稱ORM/OR Mapping):是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術。 簡單的說,ORM是通過使用描述對象和數據庫之間映射的元數據,將java程序中的對象自動持久化到關系數據庫中。避免直接使用SQL語句對關系型數據庫中的數據進行操作。減少代碼編寫量,提高產品質量。
2、ORM 主要解決對象-關系的映射
面向對象概念 面向關系概念
類 表
對象 表的行(記錄)
屬性 表的列(字段)
3、ORM 的實現思想
將關系數據庫中表中的記錄映射成為對象,以對象的形式展現,程序員可以把對數據庫的操作轉化為對對象的操作。因此ORM的目的是為了方便開發人員以面向對象的思想來實現對數據庫的操作。
ORM 采用元數據來描述對象-關系映射細節:元數據通常采用 XML 格式,並且存放在專門的對象-關系映射文件中。
4、目前流行的ORM框架
1、JPA:本身是一種ORM規範,不是ORM框架,由各大ORM框架提供實現。
2、Hibernate:目前最流行的ORM框架,設計靈巧,性能優秀,文檔豐富。
3、MyBatis:本是apache的一個開源項目iBatis,提供的持久層框架包括SQL Maps和DAO,允許開發人員直接編寫SQL。
三、MyBatis 完成 CRUD(增刪改查)
1、使用框架第一步:拷貝jar包
a:MySQL驅動:mysql-connector-java-5.1.22-bin.jar
b:MyBatis的核心jar:mybatis-3.2.1.jar
c:MyBatis的依賴jar:MyBatis目錄\lib中所有jar
2、MyBatis的主配置文件:
MyBatis-config.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <!--配置別名--> 7 <typeAliases> 8 <package name="com.mybatis.pojo"/> 9 </typeAliases> 10 <environments default="development"> 11 <environment id="development"> 12 <!--事務管理:JDBC的事務管理機制--> 13 <transactionManager type="JDBC"/> 14 <!--配置鏈接池:數據源--> 15 <dataSource type="POOLED"> 16 <property name="driver" value="com.mysql.jdbc.Driver"/> 17 <property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8"/> 18 <property name="username" value="root"/> 19 <property name="password" value="admin"/> 20 </dataSource> 21 </environment> 22 </environments> 23 <!--關系映射文件--> 24 <mappers> 25 <mapper resource="com/mybatis/pojo/Product.xml"/> 26 </mappers> 27 </configuration>
3、映射文件(寫sql語句的文件)
Product 類:
1 package com.mybatis.pojo; 2 3 public class Product { 4 private Integer id; 5 private String name; 6 private float price; 7 8 public Integer getId() { 9 return id; 10 } 11 12 public void setId(Integer id) { 13 this.id = id; 14 } 15 16 public String getName() { 17 return name; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public float getPrice() { 25 return price; 26 } 27 28 public void setPrice(float price) { 29 this.price = price; 30 } 31 32 @Override 33 public String toString() { 34 return "Product{" + 35 "id=" + id + 36 ", name=‘" + name + ‘\‘‘ + 37 ", price=" + price + 38 ‘}‘; 39 } 40 }
mapper接口:
1 import com.mybatis.pojo.Product; 2 3 import java.util.List; 4 5 public interface ProductMapper { 6 7 /** 8 * 添加產品 9 * @param product 10 * @return 11 */ 12 int addProduct(Product product); 13 14 /** 15 * 根據id刪除產品 16 * @param id 17 */ 18 void deleteProduct(int id); 19 20 /** 21 * 更新產品信息 22 * @param product 23 * @return 24 */ 25 int updateProduct(Product product); 26 27 /** 28 * 獲取產品列表 29 * @return 30 */ 31 List<Product> listProduct(); 32 }
映射文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper 3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 6 <mapper namespace="com.mybatis.mapper.ProductMapper"> 7 <insert id="addProduct" parameterType="Product"> 8 INSERT INTO product (name, price) VALUES (#{name}, #{price}) 9 </insert> 10 11 <delete id="deleteProduct" parameterType="Product"> 12 DELETE FROM product WHERE id=#{id} 13 </delete> 14 15 <update id="updateProduct" parameterType="Product"> 16 UPDATE product SET name=#{name}, price=#{price} WHERE id=#{id} 17 </update> 18 19 <select id="listProduct" resultType="Product"> 20 SELECT * FROM product 21 </select> 22 </mapper>
4、創建鏈接(dao層實現)
無論是用 Hibernate 還是 MyBatis,通用的操作步驟:
1、 從配置文件(通常是XML配置文件中)得到 sessionfactory(相當於DataSource)。
2、由sessionfactory 產生 session(相當於Connection)。
3、在session 中完成對數據的增刪改查和事務提交等。
4、在用完之後關閉session 。
1 import com.mybatis.pojo.Product; 2 import org.apache.ibatis.io.Resources; 3 import org.apache.ibatis.session.SqlSession; 4 import org.apache.ibatis.session.SqlSessionFactory; 5 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 6 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.util.List; 10 11 /** 12 * @author zt1994 2018/3/6 10:55 13 */ 14 public class ProductDao { 15 16 /** 17 * 添加產品 18 * @param product 19 */ 20 public void addProduct(Product product){ 21 String resource = "mybatis-config.xml"; 22 InputStream inputStream = null; 23 try { 24 inputStream = Resources.getResourceAsStream(resource); 25 //1.從配置文件(通常是XML配置文件中)得到 sessionfactory(相當於DataSource)。 26 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 27 //2.由sessionfactory 產生 session(相當於Connection)。 28 SqlSession session = sessionFactory.openSession(); 29 //3.在session 中完成對數據的增刪改查和事務提交等。 30 session.insert("com.mybatis.mapper.ProductMapper.addProduct", product); 31 session.commit(); 32 //4.在用完之後關閉session。 33 session.close(); 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 } 38 39 40 /** 41 * 通過id刪除產品 42 * @param id 43 */ 44 public void deleteProduct(Integer id){ 45 String resource = "mybatis-config.xml"; 46 InputStream inputStream = null; 47 try { 48 inputStream = Resources.getResourceAsStream(resource); 49 //1.從配置文件(通常是XML配置文件中)得到 sessionfactory(相當於DataSource)。 50 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 51 //2.由sessionfactory 產生 session(相當於Connection)。 52 SqlSession session = sessionFactory.openSession(); 53 //3.在session 中完成對數據的增刪改查和事務提交等。 54 session.delete("com.mybatis.mapper.ProductMapper.deleteProduct", id); 55 session.commit(); 56 //4.在用完之後關閉session。 57 session.close(); 58 } catch (IOException e) { 59 e.printStackTrace(); 60 } 61 } 62 63 64 /** 65 * 更新產品 66 * @param product 67 */ 68 public void updateProduct(Product product){ 69 String resource = "mybatis-config.xml"; 70 InputStream inputStream = null; 71 try { 72 inputStream = Resources.getResourceAsStream(resource); 73 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 74 SqlSession session = sessionFactory.openSession(); 75 session.update("com.mybatis.mapper.ProductMapper.updateProduct", product); 76 session.commit(); 77 session.close(); 78 } catch (IOException e) { 79 e.printStackTrace(); 80 } 81 } 82 83 84 /** 85 * 查詢產品列表 86 * @return 87 */ 88 public List<Product> listProduct(){ 89 String resource = "mybatis-config.xml"; 90 InputStream inputStream = null; 91 try { 92 inputStream = Resources.getResourceAsStream(resource); 93 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 94 SqlSession session = sessionFactory.openSession(); 95 List<Product> productList = session.selectList("com.mybatis.mapper.ProductMapper.listProduct"); 96 session.commit(); 97 session.close(); 98 return productList; 99 } catch (IOException e) { 100 e.printStackTrace(); 101 } 102 return null; 103 } 104 }
5、測試dao
測試dao代碼:
1 import com.mybatis.dao.ProductDao; 2 import com.mybatis.pojo.Product; 3 import org.junit.Test; 4 5 import java.util.List; 6 7 /** 8 * @author zt1994 2018/3/6 11:01 9 */ 10 public class TestProductDao { 11 private ProductDao productDao = new ProductDao(); 12 13 /** 14 * 測試添加產品 15 */ 16 @Test 17 public void testAddProduct(){ 18 Product product = new Product(); 19 product.setName("product5"); 20 product.setPrice(5); 21 22 productDao.addProduct(product); 23 } 24 25 /** 26 * 測試刪除產品 27 */ 28 @Test 29 public void testDeleteProduct(){ 30 productDao.deleteProduct(1); 31 } 32 33 /** 34 * 更新產品 35 */ 36 @Test 37 public void testUpdateProduct(){ 38 Product product = new Product(); 39 product.setId(1); 40 product.setName("product5"); 41 product.setPrice(5); 42 productDao.updateProduct(product); 43 } 44 45 /** 46 * 查詢產品列表 47 */ 48 @Test 49 public void testListProduct(){ 50 List<Product> productList = productDao.listProduct(); 51 for (Product product : productList) { 52 System.out.println(product); 53 } 54 } 55 }
6、代碼優化操作
SqlSessionFactory 一旦被創建,應該在你的應用執行期間都存在,沒有理由來處理或重新創建它。最簡單的是使用單例模式或靜態單例模式;最好的是使用Spring框架來管理 SqlSessionFactory 的生命周期。
現在來實現 SqlSessionFactory 的靜態單例模式創建。使用Spring框架來管理 SqlSessionFactory 的生命周期以後再說。
把創建 SqlSessionFactory 和 sqlSession 的代碼抽取為工具類:
1 import org.apache.ibatis.io.Resources; 2 import org.apache.ibatis.session.SqlSession; 3 import org.apache.ibatis.session.SqlSessionFactory; 4 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 5 6 import java.io.IOException; 7 import java.io.InputStream; 8 9 /** 10 * @author zt1994 2018/3/6 11:38 11 */ 12 public class MyBatisUtils { 13 14 private static SqlSessionFactory sessionFactory; 15 static { 16 try { 17 String resource = "mybatis-config.xml"; 18 InputStream inputStream= Resources.getResourceAsStream(resource); 19 //1.從配置文件(通常是XML配置文件中)得到 sessionfactory(相當於DataSource)。 20 sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 21 }catch (IOException e){ 22 e.printStackTrace(); 23 } 24 } 25 26 public static SqlSession getSqlSession(){ 27 //2.由sessionfactory 產生 session(相當於Connection)。 28 return sessionFactory.openSession(); 29 } 30 }
優化後的 dao 層代碼:
1 import com.mybatis.pojo.Product; 2 import com.mybatis.util.MyBatisUtils; 3 import org.apache.ibatis.session.SqlSession; 4 5 import java.util.List; 6 7 /** 8 * @author zt1994 2018/3/6 11:55 9 */ 10 public class ProductDao { 11 12 /** 13 * 添加產品 14 * @param product 15 */ 16 public void addProduct(Product product){ 17 SqlSession session = MyBatisUtils.getSqlSession(); 18 session.insert("com.mybatis.mapper.ProductMapper.addProduct", product); 19 session.commit(); 20 session.close(); 21 } 22 23 24 /** 25 * 通過id刪除產品 26 * @param id 27 */ 28 public void deleteProduct(Integer id){ 29 SqlSession session = MyBatisUtils.getSqlSession(); 30 session.delete("com.mybatis.mapper.ProductMapper.deleteProduct", id); 31 session.commit(); 32 session.close(); 33 } 34 35 36 /** 37 * 更新產品 38 * @param product 39 */ 40 public void updateProduct(Product product){ 41 SqlSession session = MyBatisUtils.getSqlSession(); 42 session.update("com.mybatis.mapper.ProductMapper.updateProduct", product); 43 session.commit(); 44 session.close(); 45 } 46 47 48 /** 49 * 查詢產品列表 50 * @return 51 */ 52 public List<Product> listProduct(){ 53 SqlSession session = MyBatisUtils.getSqlSession(); 54 List<Product> productList = session.selectList("com.mybatis.mapper.ProductMapper.listProduct"); 55 session.commit(); 56 session.close(); 57 return productList; 58 } 59 }
7、項目整體結構
MyBatis 學習(一)