Java框架-mybatis連線池、動態sql和多表查詢
1. mybatis連線池
- 通過SqlMapConfig.xml設定
dataSource type
實現連線池的配置
1.1 dataSource標籤type屬性值含義
type=”POOLED”
: MyBatis 會建立 PooledDataSource 例項
type=”UNPOOLED”
: MyBatis 會建立 UnpooledDataSource 例項
type=”JNDI”
: MyBatis 會從 JNDI 服務上查詢 並獲取DataSource 例項
1.2 mybatis連線池及dataSource
1.2.1 mybatis連線池分類及關係
-
Mybatis 的資料來源分為三類:
- UNPOOLED 不使用連線池的資料來源
- POOLED 使用連線池的資料來源
- JNDI 使用 JNDI 實現的資料來源
-
Mybaits連線池關係
PooledDataSource通過UnPooledDataSource例項物件,實際上是一種快取連線池機制
1.2.2 UnPooledDataSource連線池
獲取連線方式有兩種
- 通過使用者名稱和密碼獲取連線(實際上是將使用者名稱、密碼封裝到屬性集,再呼叫第二種方法獲取)
- 通過配置檔案獲取連線
1.2.3 PooledDataSource連線池(建議使用)
- PooledDataSource在建立連線時候,會自動呼叫UnPooledDataSource中建立連線的方法
1.2.4 連接獲取時機
- 在例項資料庫時不會建立連線,而是在真正進行資料庫操作的時候再獲取連線
2. Mybatis對映檔案的動態sql
部分業務邏輯是動態變化的,需要使用動態sql滿足需求。Mybatis框架中sql是寫在dao介面對映檔案中,Mybatis提供多種標籤用以使用動態sql
2.1 <if>
標籤
- 使用if標籤進行條件判斷
- 屬性test:用於判斷表示式,返回boolean型別。其值為條件表示式
2.1.1 對映檔案
<!--
使用if條件語句 test屬性用以判斷,其屬性值為條件判斷語句
-->
<select id="findByConditon" parameterType="user" resultType="com.azure.entity.User">
select * from user where 1=1
<!--條件判斷並拼接sql語句-->
<if test="id != 0">
and id=#{id}
</if>
<if test="username != null">
and username=#{username}
</if>
</select>
2.2 <where>
標籤
- 使用where標籤拼接where條件
<!--使用where標籤拼接where條件-->
<select id="findByConditon" parameterType="user" resultType="com.azure.entity.User">
select * from user
<where>
<!--條件判斷並拼接sql語句-->
<if test="id != 0">
and id=#{id}
</if>
<if test="username != null">
and username=#{username}
</if>
</where>
</select>
2.3 <foreach>
標籤
-
使用foreach標籤遍歷引數
屬性值:
- collection:遍歷的集合(引數列表)
- open:sql語句最先拼接的部分,遍歷開始
- close:sql語句最後拼接的部分,遍歷結束
- separator:每次遍歷時,sql語句拼接時以指定的分割符分割
- item:儲存每次遍歷的結果
- index:當前遍歷元素的索引
標籤體:給每個item賦值,可使用#{}賦值
案例需求:根據多個id查詢使用者返回使用者集合
2.3.1 定義查詢擴充套件物件
- 用於封裝多個引數
- 對原有的QueryVo進行拓展優化
/**
* 通過繼承User類,QueryVO類可以實現User所有屬性查詢以及擴充套件屬性
*/
public class QueryVo extends User{
/*
使用一個List封裝多個id值
*/
private List<Integer> ids;
public QueryVo(){
}
//getter&setter
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
2.3.2 dao層介面
List<User> findByCondition2(QueryVo queryVo);
2.3.3 dao對映檔案
<!--使用foreach標籤進行多id查詢
使用程式碼格式select * from user where 1=1 and id in (xx,xx,...)
格式:select * from user where 1=1 and id=xx orid=xx,...不能使用foreach標籤
-->
<select id="findByCondition2" resultType="user" parameterType="user">
select * from user
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="id in (" separator="," close=")" item="id">
#{id}
</foreach>
</if>
</where>
</select>
2.3.4 測試類
@Test
public void find2() {
//封裝條件
QueryVo queryVo = new QueryVo();
List<Integer> ids = new ArrayList<Integer>();
ids.add(47);
ids.add(48);
ids.add(49);
queryVo.setIds(ids);
//執行方法
List<User> list = userDao.findByCondition2(queryVo);
System.out.println(list);
}
2.4 Mybatis簡化sql語句
-
sql標籤:定義sql片段,可以將公用的sql抽取出來
- 屬性值:id,為sql片段命名
-
include標籤:用於引用sql片段
- 屬性值:refid,與引用的sql標籤的id對應
-
如果引用其它 mapper.xml 的 sql 片段,則在引用時需要加上 namespace,如下:
<include refid=*"*namespace.sql 片段”/>
<!--抽取公共sql語句-->
<sql id="selectUser">
select * from user
</sql>
<select id="findByCondition2" resultType="user" parameterType="queryVo">
<!--引用sql片段-->
<include refid="selectUser"></include>
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open=" id in (" separator="," close=")" item="id">
#{id}
</foreach>
</if>
</where>
</select>
- 注意事項:
- 何時進行抽取?如果相同sql程式碼出現2次以上,就要將相同程式碼抽取出來,便於後期維護
- 強烈建議將sql抽取出來!!!!!
3. Mybatis的多表關聯查詢
以使用者、賬戶和角色表之間查詢為例
準備工作:
-
賬戶表
DROP TABLE IF EXISTS account; CREATE TABLE account ( accountId INT(11) NOT NULL COMMENT '編號', UID INT(11) DEFAULT NULL COMMENT '使用者編號', MONEY DOUBLE DEFAULT NULL COMMENT '金額', PRIMARY KEY (accountId), KEY FK_Reference_8 (UID), CONSTRAINT FK_Reference_8 FOREIGN KEY (UID) REFERENCES USER (id) ) ENGINE=INNODB DEFAULT CHARSET=utf8; INSERT INTO account(accountId,UID,MONEY) VALUES (1,46,1000),(2,45,1000),(3,46,2000);
-
角色表
CREATE TABLE role ( ID int(11) NOT NULL COMMENT '編號', ROLE_NAME varchar(30) default NULL COMMENT '角色名稱', ROLE_DESC varchar(60) default NULL COMMENT '角色描述', PRIMARY KEY (ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into role(ID,ROLE_NAME,ROLE_DESC) values (1,'院長','管理整個學院'),(2,'總裁','管理整個公司'),(3,'校長','管理整個學校');
3.1 一對一
需求:查詢賬戶表,並把賬戶對應的使用者資訊顯示出來
3.1.1 需求分析
賬戶與使用者是一對一關係,一個賬戶只能對應一個使用者
實現一對一關係步驟:
-
建立專案;
-
建立實體類(賬戶)
-
賬戶表屬性
-
封裝User資料
-
-
介面編寫
-
配置對映檔案,裡面配置1to1的關係,讓Mybatis自動封裝多表資料
-
測試
3.1.2 建立實體類
public class Account implements Serializable {
private int accountId;
private int uid;
private double money;
//封裝User資料,賬戶與使用者是一對一關係
private User user;
public Account() {
}
/*省略有參、toString、getter&setter*/
}
3.1.3 建立dao介面
public interface IAccountDao {
//查詢所有賬戶及對應的使用者資訊
List<Account> findAll();
}
3.1.4 配置dao介面對映檔案
-
一對一關係中,返回值型別必須使用resultMap,用來封裝多表查詢的資料
-
使用
<association>
標籤表示一對一關係的對映配置。屬性值有:
- property:一對一關係的對應物件屬性名(本例是指賬戶物件對應的user物件屬性);
- JavaType:對應物件屬性型別
- column:外來鍵欄位
<?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.azure.dao.IAccountDao">
<!--返回集的型別是Account型別,裡面需封裝account表資料和User物件-->
<resultMap id="accountResultMap" type="account">
<!--先建立account物件屬性與account表字段的對映關係-->
<id property="accountId" column="accountId"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--建立user物件與User表字段的對映關係-->
<!--
使用association標籤標示一對一關係
- property:一對一關係的對應物件屬性名(本例是指賬戶物件對應的user物件屬性);
- JavaType:對應物件屬性型別(本例即User型別)
- column:外來鍵欄位
-->
<association property="user" javaType="user" column="uid">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
</association>
</resultMap>
<!--使用resultMap明確一對一關係。
使用左外連線確保account表資料能全部顯示
-->
<select id="findAll" resultMap="accountResultMap">
select * from account a left join user u on a.uid=u.id
</select>
</mapper>
3.1.5 測試類
public class AccountDaoTest {
private InputStream is;
private SqlSession session;
private IAccountDao accountDao;
/**
* 每次執行Junit前都會執行
* @throws IOException
*/
@Before
public void before() throws IOException {
is = Resources.getResourceAsStream("SqlMapConfig.xml");
session = new SqlSessionFactoryBuilder().build(is).openSession();
accountDao = session.getMapper(IAccountDao.class);
}
/**
* 每次執行Junit後都會執行,提交事務和關閉資源
* @throws IOException
*/
@After
public void close() throws IOException {
//手動提交事務
session.commit();
//關閉資源
session.close();
is.close();
}
@Test
public void find() throws IOException{
List<Account> accounts = accountDao.findAll();
System.out.println(accounts);
}
}
3.2 一對多
需求:查詢使用者,並將使用者對應的賬戶顯示
3.2.1 需求分析
- 使用者與賬戶是一對多的關係,一個使用者可以有多個賬戶
-
建立專案;
-
建立實體類(使用者)
-
使用者表屬性
-
封裝Account資料
-
-
介面編寫
-
配置對映檔案,裡面配置1ton的關係,讓Mybatis自動封裝多表資料
-
測試
3.2.2 建立實體類
public class User implements Serializable{
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
//封裝account賬戶表資料,用一個list封裝所有賬戶
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
/*省略有參、toString、getter&setter*/
}
3.2.3 dao介面
public interface IUserDao {
/*查詢所有使用者*/
List<User> findAll();
}
3.2.4 介面對映檔案
-
需要使用resultMap封裝多表查詢結果
-
使用
<collection>
標籤表示一對一關係的對映配置。屬性值有:
- property:指定集合在實體類中的屬性名;(本例是User類中的
List<Account>
的屬性名accounts) - ofType:指定集合元素的java型別
- column:外來鍵
- property:指定集合在實體類中的屬性名;(本例是User類中的
<!--返回集的型別是User型別,裡面需封裝user表資料和Account物件-->
<resultMap id="usersMap" type="user">
<!--先建立user物件屬性與user表字段的對映關係-->
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<!--建立user物件與account表字段的對映關係-->
<!--
使用<collection>標籤表示一對一關係的對映配置。
屬性值有:
- property:對應的集合名;
- ofType:指定集合元素的型別(本例指List<Account> 的Account型別)
-->
<collection property="accounts" ofType="account">
<id property="accountId" column="accountId"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="usersMap">
select * from user u left join account a ON u.id = a.UID
</select>
3.2.5 測試類
public class UserDaoTest {
private InputStream is;
private SqlSession session;
private IUserDao userDao;
/**
* 每次執行Junit前都會執行
* @throws IOException
*/
@Before
public void before() throws IOException {
is = Resources.getResourceAsStream("SqlMapConfig.xml");
session = new SqlSessionFactoryBuilder().build(is).openSession();
userDao = session.getMapper(IUserDao.class);
}
/**
* 每次執行Junit後都會執行,提交事務和關閉資源
* @throws IOException
*/
@After
public void close() throws IOException {
//手動提交事務
session.commit();
//關閉資源
session.close();
is.close();
}
@Test
public void findAll() {
List<User> list = userDao.findAll();
System.out.println(list);
}
}
3.3 多對多
- 所謂的多對多關係,實際上是有多個一對多關係組合起來,所以處理多對多關係,要轉換成一對多關係。
需求:查詢所有使用者,並顯示對應的角色
3.3.1 需求分析
使用者與角色是多對多的關係,一個使用者有多種角色,一種角色也有多個使用者,需要分別描述
3.3.1.1 使用者對角色的一對多
- 建立專案;
- 建立實體類
- User類(User本身資料,List
<Role>
roles) - Role類(Role本身資料)
- User類(User本身資料,List
- 介面編寫
- 配置對映檔案,裡面配置1ton的關係,讓Mybatis自動封裝多表資料
- 測試
3.3.1.2 角色對使用者一對多
- 建立專案;
- 建立實體類
- User類(User本身資料,List
<Role>
roles) - Role類(Role本身資料,List
<User>
users)
- User類(User本身資料,List
- 介面編寫
- 配置對映檔案,裡面配置1ton的關係,讓Mybatis自動封裝多表資料
- 測試
3.3.1.3 使用者表與角色表分析
兩個表之間並無主鍵連線,無法單純用兩個表去描述表之間的關係,故需要新增使用者角色關係表用以描述關係。
DROP TABLE IF EXISTS user_role;
CREATE TABLE user_role (
UID int(11) NOT NULL COMMENT '使用者編號',
RID int(11) NOT NULL COMMENT '角色編號',
PRIMARY KEY (UID,RID),
KEY FK_Reference_10 (RID),
CONSTRAINT FK_Reference_10 FOREIGN KEY (RID) REFERENCES role (ID),
CONSTRAINT FK_Reference_9 FOREIGN KEY (UID) REFERENCES user (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into user_role(UID,RID) values (41,1),(45,1),(41,2);
3.3.2 實體類
Role類
public class Role implements Serializable {
private int id;
private String roleName;
private String roleDesc;
//封裝User使用者表資料,使用List封裝
private List<User2> user2s;
/*省略建構函式、toString、getter&setter
}
User類
這裡新建一個User2,避免與上面的User類衝突
public class User2 implements Serializable {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
//封裝role角色表資料,使用List封裝
private List<Role> roles;
/*省略建構函式、toString、getter&setter*/
}
3.3.3 使用者對角色一對多
3.3.3.1 dao層介面
/*
查詢所有使用者,Role有關
*/
List<User2
相關推薦
Java框架-mybatis連線池、動態sql和多表查詢
1. mybatis連線池
通過SqlMapConfig.xml設定dataSource type實現連線池的配置
1.1 dataSource標籤type屬性值含義
type=”POOLED”: MyBatis 會建立 PooledDataSource 例項
Mybatis連線池丶動態sql丶抽取sql語句
當實體類的屬性(uid)與資料庫的欄位(id)不一致的時候
對於增刪改: 只需在傳入引數後的佔位符中把對應的屬性傳遞進去就行
對於查詢:
1. 可以通過資料庫的別名來解決 select id as uid from user
2. 可以使用r
Java框架-mybatis延遲載入、快取和註解開發
1. 延遲載入
1.1 概念
在需要用到資料時才進行載入,不需要用到資料時就不載入資料。也稱作懶載入
好處:先從單表查詢,需要時再從關聯表去關聯查詢,大大提高資料庫效能
缺點:在大批量資料查詢時,由於查詢會耗時,可能導致使用者等待時間變長,影響使用者體驗
Java框架資料庫連線池
Java框架資料庫連線池比較(c3p0,dbcp和proxool)
現在常用的開源資料連線池主要有c3p0,dbcp和proxool三種,其中: ¨ hiber
Java框架資料庫連線池比較(c3p0,dbcp和proxool)
現在常用的開源資料連線池主要有c3p0,dbcp和proxool三種,其中:
¨ hibernate開發組推薦使用c3p0;
¨ spring開發組推薦使用dbcp (dbcp連線池有weblogic連線池同樣的問題,就是強行關閉連
Mybatis——傳入POJO對象,動態SQL,多表關系
this h標簽 根據 strong src 實現 圖片 tis his 傳入POJO對象
QueryVo.java
public class QueryVo implements Serializable{
private User user;
pu
SSM框架學習-MyBatis篇 SQL對映檔案——實現高階結果對映和多表查詢
SSM框架學習-MyBatis篇 SQL對映檔案——實現高階結果對映(多表查詢)
問題情境:比如有張表,使用者和使用者詳情,這兩張表裡面沒長表都有一個id欄位,這兩個表的id欄位都是對應的。
實體類裡面分別對應兩個實體類,user和userdetail,還有一個很重要的實
MyBatis中resultType、resultMap元素和分步關聯查詢
MyBatis select標籤, 常用元素有:id、parameterType、resultType、resultMap,
id:配合Mapper的全限定名,聯合成為一個唯一的標識,使用者標識這條SQL。
parameterType:表示這條SQL接受的引數型別,可以是MyBatis系統定
Sql語句多表查詢和更新
//多表查詢
select 表1.表1欄位, 表2.表2欄位 from 表1
inner join 表2 on 表1.Id=表2.Id
//多表更新。讓A表的某欄位和B表的某欄位相同
update 表A set 表A.表A 欄位=表B.表B欄位
from 表B WHERE 表A
MySQL學習(三、分組查詢和多表查詢)
一、分組查詢1.MySQL查詢函式 函式的分類: 1,單行函式:將每條資料進行獨立的計算,然後每條資料得到一條結果。 2,多行函式:多條資料同時計算,最終得到一條結果資料。也成為聚集函式、分組函式, 主要用於完成一些統計功能。2.什麼是分組? 針對於班
SQL筆記一:單表查詢和多表查詢
軟體相關不可避免的要用到資料庫相關技巧,對於測試來說最重要的是掌握資料庫的查詢技巧。
1.單表查詢
1.1無條件查詢特定欄位
語法:select 欄位A,欄位B……,欄位N from 表名 ,例如:select id,name from student 在stud
SQL server 多表查詢與檢視的使用
use Saijie
create table goods1(
商品編號 int primary key identity(1,1),--主鍵,自增
商品名稱 varchar(20) unique, --唯一鍵
商品價格 decimal(5,
SQL判斷語句用法和多表查詢
1.格式化時間sql語句
本例中本人隨便做了兩張表,和實際不是很相符,只是想說明sql語句的寫法。
例1表格式如下:
需求:查詢出本表,但需要使time欄位的時間格式為yyyy-MM-dd,比如:2013-08-13
sql寫法:
S
sql語句多表查詢(學生表/課程表/教師表/成績表 )
問題及描述:
--1.學生表
Student(S#,Sname,Sage,Ssex) --S# 學生編號,Sname 學生姓名,Sage 出生年月,Ssex 學生性別
--2.課程表
Course(C#,Cname,T#) --C# --課程編號,Cname 課程名稱,T# 教師編號
--3.教師表
Te
MyBatis從入門到精通(三):MyBatis XML方式的基本用法之多表查詢
最近在讀劉增輝老師所著的《MyBatis從入門到精通》一書,很有收穫,於是將自己學習的過程以部落格形式輸出,如有錯誤,歡迎指正,如幫助到你,不勝榮幸!
1. 多表查詢
上篇部落格中,我們示例的2個查詢都是單表查詢,但實際的業務場景肯定是需要多表查詢的,比如現在有個需求:
查詢某個使用者擁有的所有角色。這個需求
Java框架-Spring的jdbc、連線池及事務管理
1. Spring的AOP程式設計
1.1 純xml程式設計
<!--通知配置型別-->
<aop:config>
<!--設定切面-->
<aop:aspect ref="logger">
<!-
MyBatis入門(二)—— 輸入映射和輸出映射、動態sql、關聯查詢
輸出類型 sql name屬性 一對一 test HA h標簽 自動 CI p.p4 { margin: 0.0px 0.0px 0.0px 10.0px; font: 10.5px "PingFang SC" }
p.p6 { margin: 0.0px 0.0px 0.
Java打造RPC框架(五):連線池化
在上一篇的文章中https://blog.csdn.net/we_phone/article/details/79053472
我初步完成了整個RPC框架的搭建,從服務呼叫到服務發現再到負載均衡,這一篇開始進行的是一系列我所知的優化操作
這一篇我講的是連線池,比較簡單,詳細程式碼已託管到gi
mybaits(查詢與別名、日誌框架顯示sql語句、物件屬性和資料庫表字段不匹配resultMap使用、mysql資料查詢分頁、執行sql和儲存過程、動態SQL語句)
主要是各種配置檔案,建議把整個專案搬到自己電腦上慢慢看。
建立maven專案
首先是各種配置檔案:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://m
JDBC/InvocationHandler動態代理實現資料庫連線池、資料來源
Java的JDBC程式設計中,資料庫的連線和關閉是十分耗費資源的。當對資料庫的訪問不是很頻繁時,可以在每次訪問資料庫時建立一個連線,用完之後關閉。但是,對於一個複雜的資料庫應用,頻繁的建立、關閉連線,會極大的減低系統性能,造成瓶頸。所以可以使用資料庫連線池來達到