2.1. 流行的ORM框架java
1.JPA:自己是一種ORM規範,不是ORM框架.由各大ORM框架提供實現.mysql
2.Hibernate:目前最流行的ORM框架.設計靈巧,性能通常(本身去控制性能,不是很好控制),文檔豐富.(徹底自動操做)面試
Hibernate是一個完整的ORM框架,常規CRUD咱們不須要寫一句SQL;sql
3.MyBatis:本是apache的一個開源項目iBatis,提供的持久層框架包括SQL Maps和Dao,容許開發人員直接編寫SQL(更好靈活).(Sql操做方式)數據庫
MyBatis 並非一個完整的ORM框架,由於咱們還須要本身去寫所有SQLapache
2.2. JDBC操做數據庫缺陷安全
首先,經過jdbc也能實現對象實體和數據庫關係的映射.那就是採用硬編碼方式,爲每一種可能的數據庫訪問操做提供單獨的方法。 也就是各類Dao(UserDao DeptDao等)。網絡
最大的缺點就是:session
一、sql寫在JAVA代碼中改修改sql必須修改代碼,須要從新編譯。mybatis
二、有不少重複性的操做(好比獲取鏈接,釋放資源等)
2.3. ORM框架的操做數據庫關係方式有不少種,經常使用的有兩種
2.3.1. Sql操做方式(對jdbc進行封裝)(mybatis的實現方式)
把SQL配置到配置文件中,經過不一樣SQL中完成對象實體和數據庫關係相互轉換的操做。
2.3.2. 完整操做(JPA、Hibenate實現方式)
直接映射的是對象實體和數據庫關係映射。操做數據庫關係,不用寫SQL由框架本身生成。
2.4. ORM框架工做原理
一、以必定的映射方式,把實體模型和數據庫關係的映射
二、ORM框架啓動時加載這些映射和數據庫配置文件
三、ORM經過對最原生jdbc的封裝提供更加便利的操做API
四、Dao經過ORM提供的便捷API以對象的方式操做數據庫關係。
3.1. MyBatis的起源
MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,而且更名爲MyBatis 。
2013年11月遷移到Github。
iBATIS一詞來源於「internet」和「abatis」的組合,是一個基於Java的持久層框架。
iBATIS提供的持久層框架包括SQL Maps(XML映射配置)和Data Access Objects(Dao)
3.2. MyBatis的介紹
MyBatis 是一個支持普通 SQL查詢,存儲過程和高級映射的優秀持久層框架。
MyBatis 消除了幾乎全部的JDBC代碼和手工設置參數以及結果集的檢索。
MyBatis 使用簡單的 XML或註解用於配置和原始映射,將接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。
MyBatis不能自動建立表,若是可以自動建表,必須本身先準備好建表的sql語句。
4.1. 操做前的準備工做
建立一個java項目?略過
4.1.1. 導入相應的9個jar包
MyBatis是一個框架,我們說了。在Java中框架就是一組Java類最後打成jar包。所以,不僅是這個框架,之後我們學習的全部框架。在使用前都要先導入相應 的jar包。
在導入jar包以前,咱們得先說一下,MyBatis是操做數據庫的框架。我們之前學JDBC的時候說過:要操做數據庫,必定不要忘了導入相應的數據庫驅動包。
注:驅動包就是各大數據庫廠商根據JDBC規範實現的jar包(忘了的同窗能夠去看JDBC第一天的筆記)
而後找到MyBatis(相關文件咱們已經準備好,你們也能夠到網上進行自行下載),再導入MyBatis的核心包與依賴包。
下圖爲咱們使用MyBatis要導入的包:
4.1.2. 準備相應的表
我們對數據庫進行操做,確定須要準備表。這沒啥好說的。
如今直接引入咱們準備好的product表便可:
4.1.3. 準備相應的domain
建立一個Product對象,和數據庫的表對應
注:類的名稱和類型都和咱們的product表相對應匹配
public class Product {
private Long id;
//商品名稱
private String productName;
//品牌
private String brand;
//供應商
private String supplier;
//零售價
private Double salePrice;
//進價
private Double costPrice;
//折扣比例
private Double cutoff;
//商品分類編號
private Long dir_id;
//提供getter與setter...
}
4.2. 小結
準備步驟:
1 導包
2 建表(product)
3 domain(Product)
4 準備dao層(CRUD)
5 測試(不是必需的)
注意:咱們要引哪些包?
1 必定要引入驅動包(不要忘了)
2 導入mybatis的核心包
3 導入mybatis的依賴包
4.3. product的Dao層準備
/**
* 商品的持久操做
*/
public interface IProductDao {
/**
* 添加一個商品
*/
void save(Product p);
/**
* 更新一個商品
*/
void update(Product p);
/**
* 刪除一個商品
*/
void delete(Long id);
/**
* 獲得一個商品
*/
Product get(Long id);
/**
* 獲得全部商品
*/
List<Product> getAll();
}
5.1. 看文檔
一切準備就緒。接下來就是開始使用MyBatis了。可是問題來了,怎麼用呢?
該文檔雖然只有50多頁,可是已經足夠我們學習了。
先來入個門吧:入門開始,除了介紹什麼是MyBatis以後,就在說一個核心對象:SqlSessionFactory,接下來,我們就是要千方百計拿到這個核心對象。
那SqlSessionFactory對象怎麼拿到:直接找到文檔中的從 XML 中構建 SqlSessionFactory這一小節開始便可。
5.2. 從這一節中咱們能夠看出如下幾個點:
1 咱們須要準備一個核心的xml文件
2 拿到SqlSessionFactory以前須要讀取核心的xml配置文件
3 須要構造者(SqlSessionFactoryBuilder)來建立它
5.3. MyBatis-Config.xml
好了,大概介紹完畢後,咱們能夠開始準備核心配置的xml文件了
在資源文件夾下面建立一個文件,取名爲MyBatis-Config.xml
以把文檔中的配置拷備過來(先作了解測試,等功能能夠用起來後,再本身去寫這個配置)
5.4. 配置MyBatis-Config.xml提示信息
5.5. 核心配置的一個簡單介紹:
咱們須要準備幾個東西須要一個環境environments
environments 裏面兩個內容(transactionManager ,dataSource )
dataSource : driver,url,username,password(鏈接數據庫的最小單位)
<configuration>
<!-- 環境們 (不少環境的意思)
default:默認使用哪個環境(必需對應一個環境的id)
-->
<environments default="development">
<!--
一個環境 id:爲這個環境取惟一一個id名稱
-->
<environment id="development">
<!--
事務管理 type:JDBC(支持事務)/MANAGED(什麼都不作)
-->
<transactionManager type="JDBC" />
<!-- 數據源, 鏈接池 type(POOLED):MyBatis自帶的鏈接池 -->
<dataSource type="POOLED">
<!-- 鏈接數據庫的參數 -->
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///mydb" />
<property name="username" value="root" />
<property name="password" value="admin" />
</dataSource>
</environment>
</environments>
<!-- 這個mappers表明的是相應的ORM映射文件 -->
<mappers>
<mapper resource="cn/itsource/domain/ProductMapper.xml" />
</mappers>
</configuration>
5.6. 抽取數據庫信息配置文件
如今我們的關於數據庫鏈接信息已經在配置文件(XML)中,可是更多時候,咱們仍是會把配置文件的信息放到db.properties中。(因爲properties的結構簡單,便於修改,而這個文件只放數據庫的鏈接信息也更好的體現了職責分離)。
其實,在官方文檔的核心文件配置,直接就是使用的推薦properties的方式
只須要咱們作以下修改便可:
5.6.1. MyBatis-Config.xml
<configuration>
<!-- 引入Properties文件 -->
<properties resource="db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!-- 根據key拿到properties中的value值 -->
<property name="driver" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="cn/itsource/domain/ProductMapper.xml"/>
</mappers>
</configuration>
5.6.2. db.properties
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql:///test0303
db.username=root
db.password=admin
5.7. 映射文件
核心文檔已經搭建準備就緒,內心還有一點小激動。
可是老是以爲,少了點什麼? 是什麼呢?
請你們回顧與分析咱們剛纔學習的內容:
MyBatis是一個ORM映射框架,請問ORM體如今哪?
核心文件中有一個mappers,它指向了一個映射文件。映射文件在哪?
不是說好的MyBatis要寫SQL語句麼?SQL語句又在哪裏?
一切的一切都會出如今咱們的下一個章節:對象與關係的映射!敬請關注。
如今直接寫xml是沒有提示了,在xml的約束中,我們講過,當有約束的時候,xml就會有提示。
提示:出門再拐 在xml那一章的schema與dtd約束
而如今我們的約束是在網絡上。在Eclipse中,咱們能夠找到相應的約束文件,而後配置到本身本地便可。
5.8. 對象與關係的映射(ORM)
接下來,解決上一章的幾個問題。
直接找到咱們文檔中的探究已映射的SQL語句,在這裏,我就能夠看到一段xml(以下圖),這個xml就是我們須要的映射文件,它就能夠體現出ORM,而且在這裏面,也能夠愉快的寫sql語句了。
在這裏,咱們能夠看懂一些配置的意思,可是也有一些東西不是很明白。在下面的實例中,我已經對每一句配置準備好了相應的解釋:
<?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的主要功能就是寫sql
mapper:根
namespace:命令空間 (用來肯定惟一) 之前這個是能夠不加的,如今必需加
namespace的值,規則的:映射文件XxxMapper.xml所在的包+domain類名+Mapper
-->
<mapper namespace="cn.itsource.mybatis.day1._1_hello.ProductMapper">
<!--
select : 這裏面寫查詢語句
id:用來肯定這條sql語句的惟一
之後咱們肯定惟一,也就是找sql語句 : namespace +.+ id
例: cn.itsource.mybatis.day1._1_hello.ProductMapper.get
parameterType : 傳入的參數類型 long:大Long _long:小long (具體的對應請參見文檔)
resultType : 結果類型(第一條數據返回的對象類型) 本身的對象必定是全限定類名
-->
<select id="get" parameterType="long" resultType="cn.itsource.domain.Product">
select * from product where id = #{id}
</select>
</mapper>
5.9. 在上述文件中,但願你們注意幾個規範:
① 咱們的映射文件通常狀況下是和它對應的domain實體類在同一個層級
② 這個映射文件的名稱通常叫作 XxxMapper.xml (Xxx表明的是實體類名稱)
③ namespace的名稱爲了肯定惟一性,請你們根據個人要求取名
如咱們有一個類:
cn.itsource.domain.Product / cn.itsource.domain.Student
那這裏取名應該是:
cn.itsource.domain.ProductMapper /cn.itsource.domain.StudentMapper
④ 除了MyBatis支持的類型,其它的類型都統統使用全限定名
核心文件有了,映射文件也有了。如今能夠來完成我們的CRUD了吧!
可是應該從哪裏開始好呢?
還記得我們前面說過須要的核心對象SqlSessionFactory吧
我們說過,須要經過它去拿到一個SqlSession對象(至關於JDBC的鏈接)
必須要有SqlSession這個對象,咱們才能夠去執行相應的Sql
6.1. 拿到SqlSession對象
官方文檔從XML 中構建 SqlSessionFactory這一章中,除了配置的核心xml,在上面咱們還能夠看到幾句代碼(以下圖),如今我們就來詳細分析一下這幾句代碼是什麼意思:
咱們簡單解釋一下上面的代碼:讀取核心文件,而後再經過SqlSessionFactoryBuilder構建者來建立一個SqlSessionFactory工廠。
注:上面的sqlMapper實際上是一個SqlSessionFactory工廠對象(它取名不是很直觀)
官方文檔從SqlSessionFactory 中獲取 SqlSession這一章中,咱們能夠看到代碼(下圖),而後再拿到SqlSession,而且在這裏面,還附上了我們怎麼調用sql的代碼。
6.2. 工具類的抽取MyBatisUtils
對於MyBatis的工具類抽取,我們直接使用靜態工具的單例模式。
注:幾種單例模式的區別與使用(單例工具與靜態工具的區別),你們能夠去看基礎增強那天的課程。
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtils {
// 保證SqlSessionFactory是單例
private static SqlSessionFactory sqlSessionFactory;
// SqlSessionFactory相似於JPA的EntityManagerFactory,Hibernate的SessionFactory
// SqlSession 相似於JPA的EntityManager,Hibernate的Session
static {
try {
Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("解析MyBatis的配置文件或者映射文件出現異常:" + e.getMessage());
}
}
// 對外提供一個類
public static SqlSession getSession() {
return sqlSessionFactory.openSession();
}
}
6.3. 查詢一條數據
根據上面咱們get到的技能,使用MyBatis查詢一條數據!
你們要注意我們傳過去的參數,還有在SQL接收的參數!【課堂分析】
傳過去的變量名稱和#裏面的字符串名稱不是一回事!
講到這裏,我們再對整個MyBatis的流程再進行一次分析。
①:咱們須要核心文件(提供聯繫數據庫的環境)
②:須要映射文件(提供ORM與運行的SQL語句)
③:拿到SqlSession對象,用於執行SQL
@Override
public Product get(Long id) {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSession();
return sqlSession.selectOne(NAME_SPACE + "get", id);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("ProductDaoImpl.get出現異常:" + e.getMessage());
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
6.4. junit來一個測試(必須的)
寫代碼要測試,這是一個好習慣!
public class ProductDaoTest {
IProductDao productDao = new ProductDaoImpl();
@Test
public void testGet() {
Product product = productDao.get(1L);
System.out.println(product);
}
}
6.5. 查詢全部數據
6.5.1. 代碼
@Override
public List<Product> getAll() {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSession();
return sqlSession.selectList(NAME_SPACE + "getAll");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("ProductDaoImpl.get出現異常:" + e.getMessage());
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
6.5.2. 映射文件
<!-- 返回相似仍然是Product:domain類 -->
<select id="getAll" resultType="cn.itsource.mybatis.day1._1_hello.Product">
select * from product
</select>
6.5.3. 測試
@Test
public void testGetAll() {
List<Product> list = productDao.getAll();
for (Product product : list) {
System.out.println(product);
}
}
6.6. 添加一條數據
注:添加的時候必定要記住提交事務(配置事務、表結構支持事務)
JDBC的事務是自動提交的,而JPA、Hibernate、MyBatis事務都是須要手動提交的
6.6.1. 代碼
@Override
public void save(Product product) {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSession();
sqlSession.insert(NAME_SPACE + "save", product);
// JDBC的事務是自動提交的,而JPA、Hibernate、MyBatis事務都是須要手動提交的
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("ProductDaoImpl.get出現異常:" + e.getMessage());
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
6.6.2. 映射文件
<!-- void save(Product product); -->
<insert id="save" parameterType="cn.itsource.mybatis.day1._1_hello.Product">
<!-- #{productName}==product.getProductName() -->
insert into product(productName,salePrice,costPrice,cutoff,supplier,brand,dir_id)
values
(#{productName},#{salePrice},#{costPrice},#{cutoff},#{supplier},#{brand},#{dir_id})
</insert>
6.6.3. 測試
@Test
public void testSave() {
Product product = new Product();
product.setBrand("大力牌");
product.setCostPrice(30.0);
product.setCutoff(0.8);
product.setDir_id(1L);
product.setProductName("000000");
product.setSalePrice(60D);
product.setSupplier("東莞供應商");
productDao.save(product);
}
添加數據的有時候我們須要拿到當前數據的主鍵。我們先移步到MyBatis細節一章的拿到返回主鍵部分!
6.7. 修改一條數據
6.7.1. 代碼
@Override
public void update(Product product) {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSession();
sqlSession.update(NAME_SPACE + "update", product);
// JDBC的事務是自動提交的,而JPA、Hibernate、MyBatis事務都是須要手動提交的
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("ProductDaoImpl.get出現異常:" + e.getMessage());
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
6.7.2. 映射文件
<!-- void update(Product product); -->
<update id="update" parameterType="cn.itsource.mybatis.day1._1_hello.Product">
<!-- #{productName}==product.getProductName() -->
update product set productName=#{productName},salePrice=#{salePrice},costPrice=#{costPrice},
cutoff=#{cutoff},supplier=#{supplier},brand=#{brand},dir_id=#{dir_id}
where id=#{id}
</update>
6.7.3. 測試
@Test
public void testUpdate() {
Product product = productDao.get(1L);
System.out.println(product);
product.setBrand("大力牌");
product.setCostPrice(30.0);
product.setCutoff(0.8);
product.setDir_id(1L);
product.setProductName("000000");
product.setSalePrice(60D);
product.setSupplier("東莞供應商");
productDao.update(product);
product = productDao.get(1L);
System.out.println(product);
}
6.8. 刪除一條數據
6.8.1. 代碼
@Override
public void delete(Long id) {
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.getSession();
sqlSession.delete(NAME_SPACE + "delete", id);
// JDBC的事務是自動提交的,而JPA、Hibernate、MyBatis事務都是須要手動提交的
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("ProductDaoImpl.delete出現異常:" + e.getMessage());
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
6.8.2. 映射文件
<!-- void delete(Long id); -->
<delete id="delete" parameterType="id">
delete from product where id=#{id}
</delete>
6.8.3. 測試
@Test
public void testDelete() {
productDao.delete(1L);
Product product = productDao.get(1L);
System.out.println(product);
}
6.9. CRUD注意事項
下面的點都很重要,是你們在使用MyBatis的時候常常出現的點。但願你們引發重視。出現問題的時候過來好好的來找。基本我們使用MyBatis中出的錯都在這裏。
使用框架的時候配置信息變多,在配置裏寫的都是字符串,並且常常是要對應的。由於,這裏但願你們要切記:寫的時候細心,出現錯誤找字符串要耐心,
1 主配置中未配置相應的mapper(固然,這個路徑也可能寫錯)
2 在代碼中調用Sql的時候路徑寫錯
3 Sql寫錯,這個應該還好找
4 當咱們在配置文件中不少地方若是寫錯,即使是你尚未使用也可能會報錯
5 寫Sql的標籤不須要所有一致(如添加不必定必需使用insert),可是它的屬性會不一樣
6 在傳入與返回參數時全限定類名寫錯
在開發的時候,要邊作邊測試。 在某一步出現錯誤後,刪除新加的代碼看有沒有問題,若是刪除部分代碼後運行成功,就相應的能夠縮小排錯的範圍。
SqlSessionFactory相似於JPA的EntityManagerFactory,Hibernate的SessionFactory
SqlSession 相似於JPA的EntityManager,Hibernate的Session
詳細的認識一下MyBatis的幾個核心類:
7.1. SqlSessionFactoryBuilder
建造者模式:咱們最後拿到的這個對象是很是複雜的. 用這個建造者就它先爲咱們把這些複雜的代碼完成.
這個類能夠被實例化,使用和丟棄。一旦你建立了SqlSessionFactory後,這個SqlSessionFactoryBuilder類就不須要存在了。所以SqlSessionFactoryBuilder實例的最佳範圍是方法範圍(也就是本地方法變量)。
你能夠重用SqlSessionFactoryBuilder來建立多個SqlSessionFactory實例,可是最好的方式是
不須要保持它一直存在來保證全部XML解析資源,由於還有更重要的事情要作。
7.2. SqlSessionFactory
一旦被建立,SqlSessionFactory應該在你的應用執行期間都存在。沒有理由來處理或從新建立它。使用SqlSessionFactory的最佳實踐是在應用運行期間不要重複建立屢次。這樣的操做將被視爲是很是糟糕的。所以SqlSessionFactory的最佳範圍是應用範圍。
有不少方法能夠作到,最簡單的就是使用單例模式或者靜態單例模式。然而這兩種方法都不認爲是最佳實踐。這樣的話,你能夠考慮依賴注入容器,好比Google Guice或Spring。這樣的框架容許你建立支持程序來管理單例SqlSessionFactory的生命週期。
7.3. SqlSession
每一個線程都應該有它本身的SqlSession實例。SqlSession的實例不能被共享,也是線程不安全的。所以最佳的範圍是請求或方法範圍。
絕對不能將SqlSession實例的引用放在一個類的靜態字段甚至是實例字段中。
也毫不能將SqlSession實例的引用放在任何類型的管理範圍中,好比Serlvet架構中的HttpSession。
若是你如今正用任意的Web框架,要考慮SqlSession放在一個和HTTP請求對象類似的範圍內。換句話說,基於收到的HTTP請求,你能夠打開了一個SqlSession,而後返回響應,就能夠關閉它了。關閉Session很重要,
爲何在這裏咱們要先說這三大核心對象呢,由於在咱們必須要了解這三個對象的特性。才能夠更好的根據這個特性來完成工具類代碼。
8.1. 添加時拿到返回的主鍵
注:如果忘了爲何要拿到主鍵。能夠去看JDBC次日的課程,那裏我們當時有詳細的解釋。
<!--
parameterType:須要傳入咱們的對象
useGeneratedKeys: 是否須要主鍵
keyColumn:主鍵所在的列,能夠不用配置
keyProperty:對象中的屬性(表明主鍵的那個屬性)
-->
<insert id="save" parameterType="cn.itsource.domain.Product"
useGeneratedKeys="true"
keyColumn="id"
keyProperty="id"
>
insert into product (productName,dir_id,salePrice,supplier,brand,cutoff,costPrice)
values (#{productName},#{dir_id},#{salePrice},#{supplier},#{brand},#{cutoff},#{costPrice})
</insert>
主鍵就直接放到返回的對象裏面
8.2. Log4j日誌框架
在使用MyBatis的不少時候,咱們須要把日誌打印出來,幫助咱們進行分析與排錯。特別是你們如今學習階段,要求你們都MyBatis的日誌打開。
打開後咱們能夠看到執行的SQL語句,能夠看到咱們傳遞的參數。
而MyBatis中打印日誌使用的是Log4j
8.2.1. Log4j簡介:
Log4j有三個主要的組件:Loggers(記錄器),Appenders (輸出源)和Layouts(佈局)。
可簡單理解爲日誌類別,日誌要輸出的地方和日誌以何種形式輸出。綜合使用這三個組件能夠輕鬆地記錄信息的類型和級別,並能夠在運行時控制日誌輸出的樣式和位置。
8.2.2. 日誌等級
等級從低到高
TRACE:詳細
Debug:調試,相似於System.out.print
Info:信息,相似於JPA打印sql等級
Warn:警告,程序能夠正常運行,出現提示
Error:錯誤,出現異常
8.2.3. log4j.properties
要在項目中打開日誌,你們在資源文件根目錄下建立一個log4j.properties的文件,並把下面的代碼拷備到裏面。
log4j.properties(日誌文件:)
log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.itsource=TRACE 把左邊包名改爲你本身的包名
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
注意:在上面的標紅部分是咱們須要修改的,它大概表示爲當前會打印哪些位置下面文件的日誌。
cn.itsource:必定要根據本身的包名狀況進行修改
若是配置成功,那麼在MyBatis運行操做數據時就能夠看到相應的日誌了。
8.3. MyBatis中爲一個類取別名
別名:分兩種
8.3.1. 內置別名
8.3.2. 自定義別名
在咱們前面傳參與接收結果的時候,我們一直是使用的全限定名。
可是MyBatis本身在使用不少類型的時候(如Integer,Boolean)卻能夠直接使用別名。
那麼,我們本身的寫的類能不能使用別名呢?
你們能夠直接找到官文文檔上typeAliases這一章,有介紹咱們怎麼爲本身的類取別名。
取別名有什麼用,呵呵。我認識一個朋友,他叫作:特雷西.麥克格雷迪,我叫他麥迪
下面爲取別名的代碼:
<typeAliases>
<!--
將一個包下面的全部類都取上別名:<package name="cn.itsource.domain" />
alias:取的別名
type:這個別名所對應的Java類
:別名使用的時候與大小寫無關
-->
<typeAlias alias="product" type="cn.itsource.domain.Product" />
<!-- 作項目的時候使用 -->
<package name="cn.itsource.mybatis.day1._2_detail" />
</typeAliases>
注:必需在主文件中設置別名,其它地方纔可使用(切記切記)
8.4. 列名與屬性名不對應的解決方案resultMap
原來經過javaBean自動映射,可使用手動映射
你們應該有注意到,前面我們作映射文件的時候,只作了表與對象之間的聯繫。並無作列與字段之間的聯繫。那麼它們之間是怎麼聯繫上的呢?
因爲以前我們的列名與屬性名是同樣的,所以框架進行了自動的識別。
那麼:若是我們的列名與屬性名不一致了(對應不上),這時候應該怎麼辦呢?
這時候,就須要咱們開發人員告訴MyBatis,咱們須要把哪些列名與屬性名對應上。
在MyBatis中,提供了一個resultMap的標籤,就是讓我們來完成返回結果的關係對應的,使用方式以下:
<!--
返回的數據映射
type:表明是要映射的對象
id:表明惟一(過會咱們要拿到它)
-->
<resultMap type="cn.itsource.domain.Product" id="productMap">
<!--
column:對應的列名
property:對應的屬性名
-->
<id column="id" property="id" />
<result column="productName" property="name" />
</resultMap>
<select id="queryOne" parameterType="long" resultMap="productMap">
select * from product where id = #{id}
</select>
9.1. 重點
9.2. 難點
<delete id="delete" parameterType="id">應該傳入long類型,而不是id
<select id="getAll" resultType="cn.itsource.mybatis.day1._1_hello.Product">
select id,productName,salePrice,costPrice,cutoff,supplier,brand,dir_id from
product
</insert>
沒有配置文件裏面加載映射文件,如何開始就使用
Product類裏面沒有'productName'屬性
把sql語句從java代碼中抽取出來,方便維護。而且修改sql時不用修改java代碼
不用手動設置參數和對結果集的處理。
14.1. 擴展知識