Java框架-mybatis-基礎
1. 概念
1.1 概念引入
- 框架( Framework)是整個或部分系統的可重用設計,表現為一組抽象構件及構件例項間互動的方法。或者說是可被應用開發者定製的應用骨架。
- 框架的優點:
- 框架已經實現了一些功能,使用時不需重複實現這些功能,提高開發效率;
- 使用框架後,我們軟體的架構更加穩定、開發流程必須按照框架約定進行,而優秀的框架是所有開發人員都熟悉的,任何人進入專案團隊後可以更快適應開發,同時框架良好的擴充套件性更易於後期維護,減少專案成本。
1.2 javaweb常用框架
表現層:SpringMVC、Struts2
業務層:Spring可對service層提供統一的事務控制。
資料訪問層:JDBC、自定義框架封裝jdbc、JDBCTemplate(Spring)、apache DbUtils、Hibernate框架、Jpa、Spring Data Jpa、Mybatis等
1.3 傳統JDBC開發弊端
-
頻繁建立連線物件和釋放,容易浪費系統資源影響效能;
-
sql語句的定義、引數設定、結果集處理存在硬編碼,不好維護和修改
. (3) 結果集處理存在重複程式碼,每次都要遍歷ResultSet,獲取一行資料,封裝為物件處理麻煩。
2. MyBatis框架
-
mybatis早期版本叫做ibatis,目前程式碼託管在github。
-
mybatis是對jdbc的封裝,是一個持久層的框架。開發者只需要關注業務本身,不需要花費精力去處理其他過程程式碼
-
mybatis是通過xml或者註解進行配置,實現java物件與sql語句的對應關係(對映)。
3. MyBatis框架-構建專案
3.1 準備環境
1.準備資料庫
-- 1.建立資料庫 CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8; -- 2.建立使用者表 DROP TABLE IF EXISTS USER; CREATE TABLE USER ( id INT(11) NOT NULL AUTO_INCREMENT, username VARCHAR(32) NOT NULL COMMENT '使用者名稱稱', birthday DATETIME DEFAULT NULL COMMENT '生日', sex CHAR(1) DEFAULT NULL COMMENT '性別', address VARCHAR(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (id) ) ENGINE=INNODB DEFAULT CHARSET=utf8; INSERT INTO USER(id,username,birthday,sex,address) VALUES (41,'旺旺','2018-08-27 17:47:08','男','北京'),(42,'小二王','2018-09-02 15:09:37','女','南京'), (43,'明明','2018-01-04 11:34:34','女','東京'), (45,'狗蛋','2017-02-04 12:04:06','男','西安'), (46,'隔壁老王','2015-05-07 17:37:26','男','濟南'), (48,'茱莉','2017-07-07 11:44:00','女','華盛頓'); SELECT * FROM USER;
2.建立專案
3.建立實體類
package com.azure.entity;
import java.util.Date;
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
public User() {
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
public User(int id, String username, Date birthday, String sex, String address) {
this.id = id;
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getUsername() {return username;}
public void setUsername(String username) {this.username = username;}
public Date getBirthday() {return birthday;}
public void setBirthday(Date birthday) {this.birthday = birthday;}
public String getSex() {return sex;}
public void setSex(String sex) {this.sex = sex;}
public String getAddress() {return address;}
public void setAddress(String address) {this.address = address;}
}
4.新增依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.azure</groupId>
<artifactId>day47projects_mybatis01</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!--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.30</version>
</dependency>
<!--日誌包-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
3.2 配置SqlMapConfig.xml
- 該檔案要放在src/main/resources目錄下
<?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>
<!--default 表示預設使用哪一個執行環境配置-->
<environments default="mysql">
<!--id="mysql" 表示mysql的執行環境配置-->
<environment id="mysql">
<!--事務管理器配置:基於JDBC的事務控制-->
<transactionManager type="JDBC"></transactionManager>
<!--配置資料庫連線池方式,type值有三個UNPOOLED,POOLED,JNDI
unpooled,不使用連線池
pooled,使用mybatis內建資料庫連線池(推薦使用,與mybatis配合使用效能最好)
JNDI,使用javaee容器(伺服器)內建的資料庫連線池
-->
<dataSource type="pooled">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///mybatis?characterEncoding=utf8"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<!--載入介面的對映檔案-->
<mappers>
<!--必須放到類路徑下-->
<mapper resource="com/azure/dao/IUserDao.xml"></mapper>
<!--注意:如果這裡是/,那麼在resources建立資料夾時也要對應的寫成"com/azure/dao",而不能用"."分隔!!-->
</mappers>
</configuration>
3.3 dao層
3.3.1 面向介面程式設計,建立介面
/*
資料訪問層介面
*/
public interface IUserDao {
List<User> findAll();
}
3.3.2 dao介面對映
-
介面對映檔案相當於dao介面的實現類!
-
注意:對映檔案存放目錄要與SqlMapConfig.xml載入對映的路徑要一致。如果SqlMapConfig.xml是用/分隔路徑,那麼再建立對映檔案的存放目錄時也一定要以/分隔,否則會報錯無法找到對映檔案!!原因詳見“3.6節 注意事項”
<?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名稱空間,用於定義實現哪個介面,需要寫所對映介面的類全名-->
<mapper namespace="com.azure.dao.IUserDao">
<!--
select:代表實現查詢操作
id:用於設定實現介面中哪個方法
resultType:用於設定介面方法返回的泛型型別
標籤體:執行的sql語句
-->
<select id="findAll" resultType="com.azure.entity.User">
select * from user
</select>
</mapper>
3.4 引入日誌檔案
- 日誌檔案 log4j.properties要放在src/main/resources目錄下
- 注意:
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
3.5 dao層測試類
public class UserDaoTest {
public static void main(String[] args) throws Exception {
//1.獲取檔案流
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.建立工廠構造器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.根據檔案和構造器建立工廠
SqlSessionFactory factory = builder.build(is);
//4.使用工廠建立SqlSession物件
SqlSession sqlSession = factory.openSession();
//5.建立介面代理物件
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//檢視是否代理物件
System.out.println(userDao.getClass());
//6.呼叫方法
List<User> users = userDao.findAll();
System.out.println(users);
//7.關閉並釋放資源
sqlSession.close();
is.close();
}
}
3.6 注意事項
-
需要主配置(SqlMapConfig.xml)載入介面對映檔案路徑;
-
對映檔案的namespace對應介面路徑(相當於實現類);
-
介面的方法與介面對應對映的方法名稱要一一對應:
-
在IDEA內resources目錄下建立資料夾與java目錄下建立資料夾不同。java目錄下建立多級目錄可以用".“分隔,比如
com.azure.dao
是三級目錄。而在resources目錄下建立多級目錄只能用”/“分隔,如果仍以”."分隔,比如com.azure.dao
,實際上只是建立一個資料夾,資料夾名就是com.azure.dao。
4. 自定義框架(瞭解)
系統架構分析:
最後是使用dao的代理物件查詢資料庫,首先得生成代理物件,分析如下:
- 先對指定的dao介面生成代理物件,通過sqlSession物件呼叫方法獲得:
<T> T getMapper(Class<T> daoClass);
; - 獲得sqlSession物件,對SqlSession介面進行實現
- 而SqlSession是通過SqlSessionFactory工廠建立的,故要先定義工廠
4.1 SqlSession介面、DefaultSqlSession介面預設實現類
4.1.1 SqlSession介面
/*
SqlSession介面定義
*/
public interface SqlSession {
/**
* 根據指定的dao介面獲得代理物件
* @param daoClass
* @param <T>
* @return dao代理物件
*/
<T> T getMapper(Class<T> daoClass);
}
4.1.2 DefaultSqlSession介面預設實現類
public class DefaultSqlSession implements SqlSession {
/**
* 根據指定的dao介面獲得代理物件
*
* 使用jdk動態代理proxy
* @param daoClass
* @return dao代理物件
*/
public <T> T getMapper(Class<T> daoClass) {
/*
代理實現方式:
靜態代理
jdk動態代理
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
1.ClassLoader loader:類載入器
2.Class<?>[] interfaces:需要代理的介面類物件陣列(代理IUserDao獲取動態代理虛擬實現物件)
3.InvocationHandler h:事件處理程式,當執行代理物件方法時候會觸發事件處理程式,把當前方法傳入事件處理程式中。
cglib代理(spring)
*/
return (T) Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(),new Class[]{daoClass},new MapperProxy());
}
}
4.1.3 SqlSessionFactory工廠
public class SqlSessionFactory {
/*
建立SqlSession
*/
public static SqlSession openSession(){
return new DefaultSqlSession();
}
}
4.1.4 MapperProxy代理 (事件處理程式)
public class MapperProxy implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//1.獲取當前執行的方法的名稱
String methodName = method.getName();
//2.獲得方法所屬類全名
String className = method.getDeclaringClass().getName();
//3.獲取對映配置檔案資料,由於對映檔案資料內容較多,而且對映檔案數目也多
// 可以使用一個類(Mapper)將每個對映檔案資料封裝起來,然後再用一個Map將所有對映檔案的Mapper物件封裝
Map<String, Mapper> mappers = Configuration.getInstance().getMappers();
//獲取當前方法的對映配置
Mapper mapper = mappers.get(className + "." + methodName);
//4.執行sql命令並返回資料
//判斷sql語句型別
if (mapper.getSqlType().equalsIgnoreCase("select")) {
//使用工具類執行sql
return Executor.selectList(mapper);
}
return null;
}
}
4.1.5 Executor工具類
/*
執行sql語句工具類
*/
public class Executor {
//獲取資料庫連線池
private static DataSource ds = Configuration.getDataSource();
public static Object selectList(Mapper mapper) {
//獲取sql
String sql = mapper.getSql();
//獲取返回值型別
String resultType = mapper.getResultType();
/*
目標:執行sql語句,封裝資料到List<>返回
*/
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//返回集合資料,使用泛型
List list = new ArrayList<>();
try {
conn = ds.getConnection();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
//獲取結果集元資料
ResultSetMetaData metaData = rs.getMetaData();
//通過元資料獲取列數
int columnCount = metaData.getColumnCount();
//獲取返回型別的位元組碼型別物件(用於後面獲取改類的物件例項封裝資料)
Class resultTypeClazz = Class.forName(resultType);
//迭代結果集
while (rs.next()) {
//例項返回物件
Object obj = resultTypeClazz.getConstructor().newInstance();
//迴圈獲取每條資料封裝
for (int i = 1; i <= columnCount; i++) {
//根據列索引獲取列名
String columnName = metaData.getColumnName(i);
//根據列索引獲取每個欄位的值
Object value = rs.getObject(i);
//使用反射根據屬性名和位元組碼物件獲得屬性描述器物件
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName,resultTypeClazz);
//根據屬性描述器獲取set封裝方法
Method setMethod = propertyDescriptor.getWriteMethod();
//將列名和值封裝對物件中,利用物件set方法物件的invoke執行封裝
setMethod.invoke(obj,value);
}
//新增資料到集合中
list.add(obj);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
ps.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
}
4.1.6 Configuration解析並封裝配置檔案資料
/*
使用Configuration解析並封裝配置檔案資料
*/
public class Configuration {
//使用單例模式建立物件並解析資料,確保當前物件被例項化一次
//1. 建立靜態類物件
private static Configuration configuration = null;
//2.定義私有建構函式
private Configuration() {
//在例項化的時候解析配置檔案資料並封裝
//載入主配置檔案資料SqlMapConfig.xml
loadSqlMapConfig();
}
//3.提供共有靜態方法返回物件
public static Configuration getInstance() {
//只有呼叫方法才會建立物件,後面呼叫所獲取的都是同一個物件(即第一次建立的物件)--單例模式的選擇原因
if (configuration == null) {
configuration = new Configuration();
}
return configuration;
}
/**
* 用於載入主配置檔案
* 使用jsoup對xml檔案進行解析
*/
private void loadSqlMapConfig() {
try {
//1.根據檔案路徑獲取xml的Document物件
String path = Resources.class.getResource("/SqlMapConfig.xml").getPath();//使用類位元組碼物件獲取檔案路徑
Document document = Jsoup.parse(new File(path), "utf-8");
/*獲取Document物件的資料並封裝資料庫連線的4個數據到configuration物件中
原因:所有的配置檔案資料都封裝到configuration物件中,資料庫連線可以通過configuration物件獲取配置檔案中所需的這4個數據
*/
this.driver = document.selectFirst("property[name='driver']").attr("value");
this.url = document.selectFirst("property[name='url']").attr("value");
this.username = document.selectFirst("property[name='username']").attr("value");
this.password = document.selectFirst("property[name='password']").attr("value");
//2.載入介面對映配置檔案
//2.1 獲取mapper標籤列表,迴圈遍歷載入
Elements mapperElements = document.select("mapper");
for (Element mapperElement : mapperElements) {
String mapperPath = mapperElement.attr("resource");
//載入每個對映介面配置檔案
loadMapperData(mapperPath);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 載入當前介面配置檔案的所有資料到mappers中
* @param mapperPath
*/
private void loadMapperData(String mapperPath) throws IOException {
//根據檔案路徑獲取Document物件
String path = Resources.class.getResource("/" + mapperPath).getPath();//注意:這裡必須拼接/
Document document = Jsoup.parse(new File(path),"utf-8");
//解析資料
Element mapperElement = document.selectFirst("mapper");
String namespace = mapperElement.attr("namespace");
Elements childrenElements = mapperElement.children();
//遍歷子標籤封裝資料
for (Element childrenElement : childrenElements) {
String id = childrenElement.attr("id");
String resultType = childrenElement.attr("resultType");
String sql = childrenElement.text();
String sqlType = childrenElement.nodeName();
//將資料封裝到Mapper裡面
Mapper mapper = new Mapper();
mapper.setNamespace(namespace);
mapper.setId(id);
mapper.setResultType(resultType
相關推薦
Java框架-mybatis-基礎
1. 概念
1.1 概念引入
框架( Framework)是整個或部分系統的可重用設計,表現為一組抽象構件及構件例項間互動的方法。或者說是可被應用開發者定製的應用骨架。
框架的優點:
框架已經實現了一些功能,使用時不需重複實現這些功能,提高開發效率;
JAVA 框架-Mybatis
必備 事務管理器 manager ride 1.0 聯合查詢 pub etime and 一.Mybatis簡介
1.MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google
Java框架-mybatis延遲載入、快取和註解開發
1. 延遲載入
1.1 概念
在需要用到資料時才進行載入,不需要用到資料時就不載入資料。也稱作懶載入
好處:先從單表查詢,需要時再從關聯表去關聯查詢,大大提高資料庫效能
缺點:在大批量資料查詢時,由於查詢會耗時,可能導致使用者等待時間變長,影響使用者體驗
Java框架-mybatis連線池、動態sql和多表查詢
1. mybatis連線池
通過SqlMapConfig.xml設定dataSource type實現連線池的配置
1.1 dataSource標籤type屬性值含義
type=”POOLED”: MyBatis 會建立 PooledDataSource 例項
JAVA框架學習——基礎準備(log4j,靜態代理與動態代理,列舉,註解)
一、log4j。
1.log4j基礎科普:記錄日誌。
有兩種日誌模式:
a.Apatcha提供:Log4j(MyBatis使用這種)和Log4j2(Hibernate使用這個)
b.JDK自帶,由於自帶不好用所以用上一個
Java框架Mybatis的工作流程及原理
Mybatis簡介:
MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映。MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置
Java學習關於集合框架的基礎接口--Collection接口
api 類型 拋出異常 exc 高效率 tee height 存在 support 集合框架(Collection Framework)是Java最強大的子系統之一,位於java.util 包中。集合框架是一個復雜的接口與和類層次,提供了管理對象組的最新技術。Jav
java:Mybatis框架1(基本配置,log4j)
屬性 apache led sta sql inpu ack ima 文件中 1.mybatis01:
db.properties:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3
java框架整合Springmvc+mybatis+shiro+lucene+rest+webser
獲取 roi 架構師 tpc maven項目 組管理 col 公司 log 框架整合:
Springmvc + Mybatis + Shiro(權限) + REST(服務) + WebService(服務) + JMS(消息) + Lucene(搜搜引擎) + Quartz
MyBatis基礎:使用java提供的ThreadLocal類優化程式碼
public class MyBaitsView {
//使用java提供的ThreadLocal類來儲存SqlSession物件,方便同一執行緒獲得sqlSession
public static ThreadLocal<SqlSession> threadLocal=ne
JAVA框架底層源碼剖析系列Spring,Mybatis,Springboot,Netty源碼深度解析
spring 消費者 接口 jdbc 剖析 tty 必須 實戰 整體架構 《Spring源碼深度解析》從核心實現和企業應用兩個方面,由淺入深、由易到難地對Spring源碼展開了系統的講解,包括Spring的設計理念和整體架構、容器的基本實現、默認標簽的解析、自定義標簽的解析
整合框架 javaweb開發平臺ssmy_m(與程式碼生成) java struts2 mybatis spring maven jquery
本頁地址 http://blog.csdn.net/lpy3654321/article/details/31841573
專案設想,在專案開發中,我們的
【MyBatis】(一)MyBatis基礎知識點(概念,Mybatis框架的優缺點,簡單的Mybatis框架使用Demo,基本的增刪改查操作案例)
一、概念
簡單的說:一款封裝了資料庫JDBC操作的ORM框架技術.(Apache(ibatis) --> Google(Mybatis))
MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映。MyBatis 避免了幾乎
Java框架(七)之Mybatis(簡介、mybatis開發dao的方式)
一、Mybatis簡介
1.定義
MyBatis 是支援普通 SQL 查詢,儲存過程和高階對映的優秀持久層(dao)框架。MyBatis 消除 了幾乎所有的 JDBC程式碼和 引數的手工設定 以及對 結果集的檢索。MyBatis 可以使用簡單的 XML 或註解
Java框架之Mybatis中佔位符 # 和 $ 的區別是什麼?
佔位符 # 和 $ 的區別
/# 符號存在預編譯的過程,對問號賦值,防止 SQL 注入。它將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號
/$ 沒有預編譯過程,將傳入的資料直接顯示生成 SQL 中
/$ 符號是直譯的方式,一般用在 order
Java SSM框架相關基礎面試題整理
一、Spring面試題
1、Spring 在ssm中起什麼作用?Spring:輕量級框架作用:Bean工廠,用來管理Bean的生命週期和框架整合。兩大核心:①. IOC/DI(控制反轉/依賴注入) :把dao依賴注入到service層,service層反轉給action層,Spring頂層容器為BeanFa
java的orm框架 mybatis 多對多 一對多關係的關聯對映和查詢--簡單易懂,理解才是王道
mybatis作為輕量級orm框架,需要配置很多sql 語句,sql是比較好控制的,所以都比較喜歡,而一般其他的orm都要學一大堆各種古怪配置,概念,看完文件仍是不明所以。
mybatis的整個流程處理來看,主要有【三方面】
1、sql語句查詢後的結果集,簡
Java框架篇---Mybatis 入門
一、Mybatis介紹
MyBatis是一款一流的支援自定義SQL、儲存過程和高階對映的持久化框架。MyBatis幾乎消除了所有的JDBC程式碼,也基本不需要手工去設定引數和獲取檢索結果。MyBatis能夠使用簡單的XML格式或者註解進行來配置,能夠對映基本資
Java框架學習_Mybatis(七)Mybatis的核心配置檔案的配置
1、Mybatis的核心配置檔案:
核心配置檔案裡面還有很多可以配置的(DTD格式,順序不能亂)
properties :屬性
settings
typeAliases :別名
typeHandlers
objectFactory
plugins
Java框架學習_Mybatis(六)Mybatis的動態代理模式
之前我們為了實現資料庫操作的封裝和業務的分離,使用Dao模式,現在Mybatis提供了更加簡潔的動態代理模式,只要有介面不需要實現,就能進行資料庫操作
動態代理模式必須遵循的規範:
與表相對應的mapper配置的namespace必須是介面的全路徑名
介面的方法名