本文主要內容:java
public class DataBaseUtil {
public static final String URL = "jdbc:mysql://localhost:3306/mblog";
public static final String USER = "root";
public static final String PASSWORD = "123456";
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
//2.
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//3.
Statement stmt = conn.createStatement();
//4.
ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM m_user where id =1");
//若是有數據,rs.next()返回true
while(rs.next()){
System.out.println("name: "+rs.getString("name")+" 年齡:"+rs.getInt("age"));
}
}
}
上面代碼中知識爲了展現JDBC整個過程(異常和資源是簡單粗暴的處理了,咱們關注的點不在這兩個)。mysql
大體能夠分爲六個步驟:程序員
從使用層面來講,採用原生態的JDBC在項目中使用起來成本仍是很高的。若是咱們的項目中的業務相對比較複雜,數據庫表也相對較多,各類操做數據庫的增刪改查的方法也會隨之多起來,那麼這樣的代碼重複次數會很是之多。面試
爲了解決以上問題,就誕生了各類各樣替換JDBC
的產品。即就是ORM框架。算法
全稱爲Object Relational Mapping。對象-映射-關係型數據庫。對象關係映射(,簡稱ORM,或O/RM,或O/R mapping),用於實現面向對象編程語言裏不一樣類型系統的數據之間的轉換。簡單的說,ORM是經過使用描述對象和數據庫之間映射的元數據,將程序中的對象與關係數據庫相互映射。sql
ORM提供了實現持久化層的另外一種模式,它採用映射元數據來描述對象關係的映射,使得ORM中間件能在任何一個應用的業務邏輯層和數據庫層之間充當橋樑。數據庫
咱們的項目中是這樣的:apache
好比說:Apache DbUtils、Spring JDBC、 Hibernate、Ibatis
(Mybatis
的前生)、Spring Data Jpa
等等。編程
目前最爲流行的Mybatis
和Spring Data Jpa
。本系列咱們先講解Mybatis
,Jpa
後面再講。安全
優勢1.提升了開發效率。因爲ORM能夠自動對Entity對象與數據庫中的Table進行字段與屬性的映射,因此咱們實際可能已經不須要一個專用的、龐大的數據訪問層。2.ORM提供了對數據庫的映射,不用sql直接編碼,可以像操做對象同樣從數據庫獲取數據。
缺點犧牲程序的執行效率和會固定思惟模式,下降了開發的靈活性。
從系統結構上來看,採用ORM的系統通常都是多層系統,系統的層次多了,效率就會下降。ORM是一種徹底的面向對象的作法,而面向對象的作法也會對性能產生必定的影響。在咱們開發系統時,通常都有性能問題。性能問題主要產生在算法不正確和與數據庫不正確的使用上。ORM所生成的代碼通常不太可能寫出很高效的算法,在數據庫應用上更有可能會被誤用,主要體如今對持久對象的提取和和數據的加工處理上,若是用上了ORM,程序員頗有可能將所有的數據提取到內存對象中,而後再進行過濾和加工處理,這樣就容易產生性能問題。在對對象作持久化時,ORM通常會持久化全部的屬性,有時,這是不但願的。但ORM是一種工具,工具確實能解決一些重複,簡單的勞動。這是不能否認的。但咱們不能期望工具能一勞永逸的解決全部問題,有些問題仍是須要特殊處理的,但須要特殊處理的部分對絕大多數的系統,應該是不多的。
若是在面試的時候被問到,只要你說出下面三種便可。
MyBatis 是一款優秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。
MyBatis 免除了幾乎全部的 JDBC 代碼以及設置參數和獲取結果集的工做。
MyBatis 能夠經過簡單的 XML 或註解來配置和映射原始類型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對象)爲數據庫中的記錄。
來自官網。
優勢:
(1)基於SQL語句編程,至關靈活,不會對應用程序或者數據庫的現有設計形成任何影響,SQL寫在XML裏,解除sql與程序代碼的耦合,便於統一管理;提供XML標籤,支持編寫動態SQL語句,並可重用。
(2)與JDBC相比,減小了50%以上的代碼量,消除了JDBC大量冗餘的代碼,不須要手動開關鏈接;
(3)很好的與各類數據庫兼容(由於MyBatis使用JDBC來鏈接數據庫,因此只要JDBC支持的數據庫MyBatis都支持)。
(4)可以與Spring很好的集成;
(5)提供映射標籤,支持對象與數據庫的ORM字段關係映射;提供對象關係映射標籤,支持對象關係組件維護。
缺點
(1)SQL語句的編寫工做量較大,尤爲當字段多、關聯表多時,對開發人員編寫SQL語句的功底有必定要求。
(2)SQL語句依賴於數據庫,致使數據庫移植性差,不能隨意更換數據庫。
Mybatis
環境搭建及簡單實例建立一張m_user表使用MySQL
數據庫。
CREATE TABLE `m_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>runtime</scope>
</dependency>
</dependencies>
項目結構以下:
建立一個mybatis-config.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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mblog?useUnicode=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
實體類User
ublic class User {
private Integer id;
private String name;
private Integer age;
//set get
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
建立UserMapper.java
import com.tian.mybatis.entity.User;
public interface UserMapper {
User selectUserById(Integer id);
}
建立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.tian.mybatis.mapper.UserMapper">
<select id="selectUserById" resultType="com.tian.mybatis.entity.User">
select * from m_user where id = #{id}
</select>
</mapper>
建立一個測試類
import com.tian.mybatis.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisApplication {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
SqlSession sqlSession =null;
try {
inputStream = Resources.getResourceAsStream(resource);
//工廠模式
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//sql操做會話
sqlSession = sqlSessionFactory.openSession();
//獲取數據並解析成User對象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
sqlSession.close();
}
}
}
輸出結果:
User{id=1, name='tian', age=22}
總體步驟:
另一種啓動方式
import com.tian.mybatis.entity.User;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MybatisApplication {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
//解析xml文件
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, null, null);
//構建一個SqlSessionFactory工廠類
SqlSessionFactory sqlSessionFactory = build(parser.parse());
//建立一個SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//獲取數據並解析成User對象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
}
public static SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
輸出和上面同樣。還能夠直接使用Java代碼而不用mybatis-config.xml
。
//建立數據源
DataSource dataSource = getDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
小總結
從上面這個案例中咱們大體能猜到,Mybatis中最主要幾個組件:
SqlSessionFactoryBuilder
SqlSessionFactory
SqlSession
Mapper
SqlSessionFactoryBuilder
這個類能夠被初始、使用和丟棄,若是你已經建立好了一個 SqlSessionFactory
後就不用再保留它。所以 ,SqlSessionFactoryBuilder
的最好做用域是方法體內,好比說定義一個方法變量。
你能夠重複使用SqlSessionFactoryBuilder
生成多個 SqlSessionFactory
實例,可是最好不要強行保留,由於 XML 的解析資源要用來作其它更重要的事。
SqlSessionFactory
一旦建立,SqlSessionFactory
就會在整個應用過程當中始終存在。因此沒有理由去銷燬和再建立它,一個 應用運行中也不建議屢次建立 SqlSessionFactory。若是真的那樣作,會顯得很拙劣。
所以 SqlSessionFactory最好的做用域是 Application。能夠有多種方法實現。最簡單的方法是單例模式或者是靜態單例模式。然而這既不是普遍同意和好用的。反而,使用 Google Guice 或 Spring 來進行依賴反射會更好。這些框架允 許你生成管理器來管理 SqlSessionFactory
的單例生命週期
SqlSession
每一個線程都有本身的 SqlSession 實例,SqlSession 實例是不能被共享,也是否是線程安全的。所以最好 使用 Request 做用域或者方法體做用域。
不要使用類的靜態變量來引用一個 SqlSession 實例,甚至不要使用類的一個實例變動來引用。永遠不要在一個被管理域中引用 SqlSession,好比說在 Servlet 中的HttpSession 中。若是你正在使用 WEB 框架,應該讓 SqlSession 跟隨 HTTP 請求的類似做用域。
也就是說,在收到一個 HTTP 請求事後,打開 SqlSession,等返回一個迴應之後,立馬關掉這個 SqlSession。關閉 SqlSession 是很是重要的。你必需要確保 SqlSession 在 finally 方法體中正常關閉。
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
使用這種模式來貫穿你的全部代碼,以確保全部數據庫資源都被徹底關閉。
Mapper
Mapper 是一種你建立的用於綁定映射語句的接口。Mapper 接口的實例是用 SqlSession 來得到的。一樣 , 從技術上來講,最普遍的 Mapper 實例做用域像 SqlSession 同樣,使用請求做用域。確切地說,在方法 被調用的時候調用 Mapper 實例,而後使用後,就自動銷燬掉。不須要使用明確的註銷。當一個請求執 行正確無誤的時候,像 SqlSession 同樣,你能夠垂手可得地操控這一切。保持簡單性,保持 Mapper 在 方法體做用域內。
//獲取數據並解析成User對象
User user = sqlSession.selectOne("com.tian.mybatis.mapper.UserMapper.selectUserById", 1);
System.out.println(user);
這裏映射涉及到四個主體:
UaerMapper
。xml
配置文件UserMapper
。Mybatis的五部曲:
回顧JDBC
的demo,JDBC
中的問題,建立一個Mybatis示例,總結出重要的四個組件,以及每一個組件的做用。