1. 回顧JDBC編程步驟
加載數(shù)據(jù)庫驅(qū)動
創(chuàng)建并獲取數(shù)據(jù)庫鏈接
創(chuàng)建jdbc PreparedStatement對象
定義sql語句
設置sql語句中的參數(shù)(使用PreparedStatement)
通過statement執(zhí)行sql并獲取結果
對sql執(zhí)行結果進行解析處理
釋放資源(ResultSet攘蔽、PreparedStatement、Connection)
2. 問題總結
- 數(shù)據(jù)庫連接,使用時就創(chuàng)建伞剑,不使用立即釋放,對數(shù)據(jù)庫進行頻繁連接開啟和關閉傀蓉,造成數(shù)據(jù)庫資源浪費笛园,影響數(shù)據(jù)庫性能。
設想:使用數(shù)據(jù)庫連接池管理數(shù)據(jù)庫連接替久。
- 將sql語句硬編碼到Java代碼中,如果sql語句修改躏尉,需要重新編譯Java代碼蚯根,不利于系統(tǒng)維護。
設想:將sql語句配置在xml配置文件中醇份,即使sql變化稼锅,不需要對Java代碼進行重新編譯。
3)向preparedStatement中設置參數(shù)僚纷,對占位符號位置和設置參數(shù)值矩距,硬編碼在Java代碼中,不利于系統(tǒng)維護怖竭。
設想:將sql語句及占位符號和參數(shù)全部配置在xml中锥债。
- 從resultSet中遍歷結果集數(shù)據(jù)時,存在硬編碼痊臭,將獲取表的字段進行硬編碼哮肚,不利于系統(tǒng)維護。
設想:將查詢的結果集广匙,自動映射成Java對象允趟。
3. 引入MyBatis
(1)Mybatis 介紹
Mybatis是一個持久層的框架,是apache下的頂級項目鸦致。
Mybatis托管到goolecode下潮剪,再后來托管到github下
Mybatis讓程序?qū)⒅饕Ψ旁趕ql上涣楷,通過Mybatis提供的映射方式,自由靈活生成(半自動化抗碰,大部分需要程序員編寫sql)滿足需要sql語句狮斗。
Mybatis可以將向 PreparedStatement中的輸入?yún)?shù)自動進行輸入映射,將查詢結果集靈活映射成java對象弧蝇。(輸出映射)
MyBatis官方文檔:https://mybatis.org/mybatis-3/
MyBatis GitHub下載:https://github.com/mybatis/mybatis-3
(2)ORM
ORM :Object Relational Mapping 對象關聯(lián)映射
對象關系映射即是將Java中的對象一一對應映射到數(shù)據(jù)庫的Table(表)中碳褒,通過對對象各個屬性賦值來更新數(shù)據(jù)庫。官方的說看疗,對象關系映射(Object Relational Mapping沙峻,簡稱ORM)是通過使用描述對象和數(shù)據(jù)庫之間映射的元數(shù)據(jù),將面向?qū)ο笳Z言程序中的對象自動持久化到關系數(shù)據(jù)庫中鹃觉。
Java MySQL
Object Data
一個個對象 一條條記錄
用于實現(xiàn)面向?qū)ο缶幊陶Z言里不同類型系統(tǒng)的數(shù)據(jù)之間的轉(zhuǎn)換专酗。從效果上說,它其實是創(chuàng)建了一個可在編程語言里使用的--“虛擬對象數(shù)據(jù)庫”盗扇。
ORM只是 對象關聯(lián)映射 設計思想,具體技術: Mybatis 沉填、Hibernate
(3)第一個Mybatis環(huán)境搭建
(1)新建Java項目疗隶,導入mybatis 、mysql-connector-java 相關依賴
(2)數(shù)據(jù)源配置 mybatis-config.xml
(3)實體類 pojo
(4)dao 接口
(5)映射文件mapper
(6)MybatisUtil類設計
(7)測試
(3.1)maven 導入相關依賴
<!--=================依賴========================-->
<dependencies>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.33</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
</dependencies>
說明:
mybatis-config.xml: 從mybatis框架下載的源碼中獲取翼闹,復制到項目中
是Mybatis 核心配置文件: 配置了數(shù)據(jù)源斑鼻、連接池、映射mapper文件等
(3.2)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">
<!--Mybatis 核心配置文件:配置了數(shù)據(jù)源猎荠、連接池坚弱、映射mapper文件 -->
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="" value=""/>
</transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:hsqldb:mem:automapping"/>
<property name="username" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 注冊mapper文件到mybatis-config.xml中-->
<mappers>
<mapper resource="com/aistar/dao/CustomerMapper.xml" />
</mappers>
</configuration>
(3.2)定義dao接口
public interface CustomerDao {
/**
* 根據(jù)主鍵查詢用戶對象
* @param id 指定查詢的用戶id
* @return 返回對應的Customer對象
*/
public Customer selectById(int id);
}
(3.3) Customer.java POJO類省略
(3.4) CustomerMapper.xml ( mybatis框架下載的源碼中獲取,復制到項目中 )
定義了執(zhí)行sql語句关摇,結果映射(數(shù)據(jù)庫表中記錄與java中對象的映射關系)
<?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">
<!--
namespace: dao接口的類全名
-->
<mapper namespace="com.aistar.dao.CustomerDao">
<resultMap id="customer" type="com.aistar.entity.Customer">
<!--主鍵列 映射 id -->
<id column="cust_id" property="custId"></id>
<result column="cust_name" property="custName"></result>
<result column="cust_pwd" property="custPwd"></result>
<result column="cust_gender" property="custGender"></result>
<result column="cust_telno" property="custTelno"></result>
<result column="cust_email" property="custEmail"></result>
</resultMap>
<!--
根據(jù)主鍵查詢用戶對象
id:dao接口方法名
parameterType: 方法的參數(shù)類型
resultType: (類類型荒叶、基本數(shù)據(jù)類型)方法返回值類型
resultMap: 返回的是自定義好的<resultMap id="">
-->
<select id="selectById" parameterType="int" resultMap="customer">
select cust_id,cust_name,cust_pwd, cust_gender,cust_telno, cust_email
from customer
where cust_id = #{id} and cust_status =0
</select>
</mapper>
(3.5)MybatisUtil.java
/**
* 獲得SqlSession與關閉SqlSession
*/
public class MyBatisUtil {
private static SqlSession sqlSession;
private static SqlSessionFactory sqlSessionFactory;
static {
//將mybatis-config.xml(還包含mapper.xml)加載到讀取流中
InputStream is = MyBatisUtil.class.getClassLoader().getResourceAsStream("config/mybatis-config.xml");
System.out.println(is);
//讀取mybatis-config.xml的數(shù)據(jù)源信息,建立數(shù)據(jù)庫連接
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
}
/**
* SqlSession : 一級緩存 输虱,管理數(shù)據(jù)庫的sql語句操作(增刪改查操作)些楣,封裝的是PreparedStatement
* @return 返回SqlSession對象
*/
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
/**
* 關閉SqlSession
*/
public static void closeSqlSession(){
if(sqlSession!=null ){
sqlSession.close();
}
}
}
(3.6)測試類
public class TestCustomer {
public static void main(String[] args) {
CustomerDao dao = MyBatisUtil.getSqlSession().getMapper(com.aistar.dao.CustomerDao.class);
Customer customer = dao.selectById(101);
System.out.println(customer);
}
}
分析:
mybatis-config.xml:
<mappers>
<mapper resource="com/aistar/dao/CustomerMapper.xml" />
<mapper resource="com/aistar/dao/NoteMapper.xml" />
<mapper resource="com/aistar/dao/TraceMapper.xml" />
<mapper resource="com/aistar/dao/CommentMapper.xml" />
</mappers>
1.
mapper文件注冊到mybatis-config.xml 中心
注冊:CustomerMapper.xml 【namespace="com.aistar.dao.CustomerDao"】
注冊:NoteMapper.xml 【namespace="com.aistar.dao.NoteDao"】
2. Statement Collection 容器
namespace ="接口類全名1 com.aistar.dao.CustomerDao"
<select id="接口的方法名">
<insert id="接口的方法名">
<update id="接口的方法名">
<delete id="接口的方法名">
<.... id="接口的方法名">
namespace ="接口類全名2 com.aistar.dao.NoteDao"
<select id="接口的方法名">
<insert id="接口的方法名">
<update id="接口的方法名">
<delete id="接口的方法名">
<.... id="接口的方法名">
getMapper :底層產(chǎn)生一個CustomerDao代理對象(是CustomerDao的實現(xiàn)子類),CustomerDaoImplProxy到注冊中心 mybatis-config.xml 找對應namespace文件中的
dao.selectById(..):CustomerDaoImplProxy 到Statement Collection 對應 namespace 有沒有匹配的id與當前方法同名宪睹,
sqlSession封裝了 PreparedStatement.executeQuery( <select id="接口的方法名"> 轉(zhuǎn)換成sql語句)