mybatis框架入門(一)
標簽: Mybatis Java MySQL mybatis 數據庫 mysql java
文章目錄
一、MyBatis簡介
(一)什么是MyBatis
MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,并且改名為MyBatis 。2013年11月遷移到Github。
MyBatis是一個優秀的持久層框架,它對jdbc的操作數據庫的過程進行封裝,使開發者只需要關注SQL本身,而不需要花費精力去處理例如注冊驅動、創建connection、創建statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。
Mybatis通過xml或注解的方式將要執行的各種statement(statement、preparedStatemnt)配置起來,并通過java對象和statement中的sql進行映射生成最終執行的sql語句,最后由mybatis框架執行sql并將結果映射成java對象并返回。
總之,Mybatis對JDBC訪問數據庫的過程進行了封裝,簡化了JDBC代碼,解決JDBC將結果集封裝為Java對象的麻煩。
下圖是MyBatis架構圖:
(1)mybatis-config.xml
是Mybatis的核心配置文件,通過其中的配置可以生成SqlSessionFactory
,也就是SqlSession
工廠
(2)基于SqlSessionFactory
可以生成SqlSession
對象
(3)SqlSession
是一個既可以發送SQL去執行,并返回結果,類似于JDBC中的Connection
對象,也是Mybatis中至關重要的一個對象。
(4)Executor
是SqlSession
底層的對象,用于執行SQL語句
(5)MapperStatement
對象也是SqlSession
底層的對象,用于接收輸入映射(SQL語句中的參數),以及做輸出映射(即將SQL查詢的結果映射成相應的結果)
(二)為什么要使用MyBatis
思考:在開始之前,思考下如何通過JDBC查詢Emp表中的所有記錄,并封裝到一個List集合中返回。(演示:準備數據、導包、導入JDBC程序)
1、使用傳統方式JDBC訪問數據庫:
(1)使用JDBC訪問數據庫有大量重復代碼(比如注冊驅動、獲取連接、獲取傳輸器、釋放資源等);
(2)JDBC自身沒有連接池,會頻繁的創建連接和關閉連接,效率低;
(3)SQL是寫死在程序中,一旦修改SQL,需要對類重新編譯;
(4)對查詢SQL執行后返回的ResultSet對象,需要手動處理,有時會特別麻煩;
…
2、使用mybatis框架訪問數據庫:
(1)Mybatis對JDBC對了封裝,可以簡化JDBC代碼;
(2)Mybatis自身支持連接池(也可以配置其他的連接池),因此可以提高程序的效率;
(3)Mybatis是將SQL配置在mapper文件中,修改SQL只是修改配置文件,類不需要重新編譯。
(4)對查詢SQL執行后返回的ResultSet對象,Mybatis會幫我們處理,轉換成Java對象。
…
總之,JDBC中所有的問題(代碼繁瑣、有太多重復代碼、需要操作太多對象、釋放資源、對結果的處理太麻煩等),在Mybatis框架中幾乎都得到了解決!!
二、MyBatis入門
(一)準備數據,創建庫和表
創建yonghedb庫、emp表,并插入若干條記錄
-- 1、創建數據庫 yonghedb 數據庫
create database if not exists yonghedb charset utf8;
use yonghedb; -- 選擇yonghedb數據庫
-- 2、刪除emp表(如果存在)
drop table if exists emp;
-- 3、在 yonghedb 庫中創建 emp 表
create table emp(
id int primary key auto_increment,
name varchar(50),
job varchar(50),
salary double
);
-- 4、往 emp 表中, 插入若干條記錄
insert into emp values(null, '王一', '程序員', 3300);
insert into emp values(null, '齊二', '程序員', 2800);
insert into emp values(null, '劉三', '程序員鼓勵師', 2700);
insert into emp values(null, '陳四', '部門總監', 4200);
insert into emp values(null, '趙五', '程序員', 3000);
insert into emp values(null, '董六', '程序員', 3500);
insert into emp values(null, '蒼七', '程序員', 3700);
insert into emp values(null, '韓八', 'CEO', 5000);
(二)創建工程,導入所需jar包、創建測試類
1、創建Maven的java工程
2、導入junit、mysql、mybaits等開發包
在pom.xml文件中引入相關依賴包即可
<dependencies>
<!-- junit單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<!-- mysql驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<!-- 整合log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>
3、創建com.tedu.mybatis.TestMybatis01
測試類,并提供findAll
方法(查詢emp表中所有的員工信息),開發步驟如下:
/** 練習1(快速入門): 查詢emp表中的所有員工, 返回一個List<Emp>集合
* @throws IOException */
@Test
public void findAll() throws IOException {
//1.讀取mybatis的核心配置文件(mybatis-config.xml)
//2.通過配置信息獲取一個SqlSessionFactory工廠對象
//3.通過工廠獲取一個SqlSession對象
//4.通過namespace+id找到要執行的sql語句并執行sql語句
//5.輸出結果
}
(三)添加mybatis-config.xml文件
1、在src/main/resources目錄下,創建mybatis-config.xml文件(MyBatis的核心配置文件)
2、mybatis-config.xml文件配置如下:
mybatis-config文件頭信息如下:
<?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的全局配置文件 -->
<configuration >
</configuration>
mybatis-config文件詳細配置如下:
<?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的全局配置文件 -->
<configuration >
<!-- 1.配置環境,可配置多個環境(比如:develop開發、test測試) -->
<environments default="develop">
<environment id="develop">
<!-- 1.1.配置事務管理方式:JDBC/MANAGED
JDBC:將事務交給JDBC管理(推薦)
MANAGED:自己管理事務
-->
<transactionManager type="JDBC"></transactionManager>
<!-- 1.2.配置數據源,即連接池 JNDI/POOLED/UNPOOLED
JNDI:已過時
POOLED:使用連接池(推薦)
UNPOOLED:不使用連接池
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 2.導入Mapper配置文件,如果mapper文件有多個,可以通過多個mapper標簽導入 -->
<mappers>
<mapper resource="EmpMapper.xml"/>
</mappers>
</configuration>
dtd文件時xml的約束文件
(四)添加EmpMapper.xml文件
1、在src/main/resources目錄下,創建EmpMapper.xml文件 (實體類的映射文件)
2、EmpMapper.xml文件配置如下:
EmpMapper文件頭信息如下:
<?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值應該保證唯一
在程序中通過[ namespace + id ]定位到要執行哪一條SQL語句
-->
<mapper namespace="">
</mapper>
EmpMapper文件詳細配置如下:
<?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值應該保證唯一
在程序中通過[ namespace + id ]定位到要執行哪一條SQL語句
-->
<mapper namespace="EmpMapper">
<!-- 通過select、insert、update、delete標簽聲明要執行的SQL -->
<!-- 練習1: 查詢emp表中的所有員工信息
resultType指定查詢的結果將會封裝到什么類型中
即使最終返回的結果是集合(List<Emp>),resultType也只需要指定集合中的泛型即可!
-->
<select id="findAll" resultType="com.tedu.pojo.Emp">
select * from emp
</select>
</mapper>
(五)添加并編寫Emp實體類
注意:在當前實例中,Emp類中的屬性和數據庫表的字段名稱必須一致,否則將會無法將結果集封裝到Java對象中。
在src/main/java目錄下創建 com.tedu.pojo.Emp類,并編輯Emp類:提供私有屬性以及對應的getter方法、setter方法,并重寫toString方法
(要是添加有參構造函數,就一定要首先添加無參構造函數,否則會報錯)
package com.tedu.pojo;
/**
* 實體類,用于封裝Emp表中的一條用戶信息
*/
public class Emp {
//1.聲明實體類中的屬性
private Integer id;
private String name;
private String job;
private Double salary;
//2.提供對應的getter和setter方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
//3.重寫toString方法
@Override
public String toString() {
return "Emp [id=" + id + ", name=" + name + ", job=" + job + ", salary=" + salary + "]";
}
}
(六)實現測試類,并測試
1、實現findAll方法,代碼如下:
/** 練習1(快速入門): 查詢emp表中的所有員工, 返回一個List<Emp>集合
* @throws IOException */
@Test
public void findAll() throws IOException {
//1.讀取mybatis的核心配置文件(mybatis-config.xml)
InputStream in = Resources
.getResourceAsStream("mybatis-config.xml");
//2.通過配置信息獲取一個SqlSessionFactory工廠對象
SqlSessionFactory fac =
new SqlSessionFactoryBuilder().build( in );
//3.通過工廠獲取一個SqlSession對象
SqlSession session = fac.openSession();
//4.通過namespace+id找到要執行的sql語句并執行sql語句
List<Emp> list = session
.selectList("EmpMapper.findAll");
//5.輸出結果
for(Emp e : list) {
System.out.println( e );
}
}
2、執行findAll方法,輸出結果為:
Emp [id=1, name=王一, job=程序員, salary=3300.0]
Emp [id=2, name=齊二, job=程序員, salary=2800.0]
Emp [id=3, name=劉三, job=程序員鼓勵師, salary=2700.0]
Emp [id=4, name=陳四, job=部門總監, salary=4200.0]
Emp [id=5, name=趙五, job=程序員, salary=3000.0]
Emp [id=6, name=董六, job=程序員, salary=3500.0]
Emp [id=7, name=蒼七, job=程序員, salary=3700.0]
Emp [id=8, name=韓八, job=CEO, salary=5000.0]
三、MyBatis入門細節
(一)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的全局配置文件 -->
<configuration >
<!-- 1.配置環境,可配置多個環境(比如:develop開發、test測試) -->
<environments default="develop">
<environment id="develop">
<!-- 1.1.配置事務管理方式:JDBC/MANAGED
JDBC:將事務交給JDBC管理(推薦)
MANAGED:自己管理事務
-->
<transactionManager type="JDBC"></transactionManager>
<!-- 1.2.配置數據源,即連接池 JNDI/POOLED/UNPOOLED
JNDI:已過時
POOLED:使用連接池(推薦)
UNPOOLED:不使用連接池
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 2.導入Mapper配置文件,如果mapper文件有多個,可以通過多個mapper標簽導入 -->
<mappers>
<mapper resource="EmpMapper.xml"/>
</mappers>
</configuration>
-
environments
標簽:該標簽內部可以配置多個environment,即多種環境,每種環境可以做不同配置或連接不同數據庫。例如,開發、測試、生產環境可能需要不同的配置,連接的數據庫可能也不相同,因此我們可以配置三個environment,分別對應上面三種不同的環境。但是要記住,
environment
可以配置多個,但是最終要使用的只能是其中一個! -
environment
標簽:內部可以配置多種配置信息,下面介紹事務管理配置和數據源配置。 -
transactionManage
標簽:事務管理配置,mybatis中有兩種事務管理方式,也就是type="[JDBC\|MANAGED]
- JDBC:這個配置就是直接使用了 JDBC的提交和回滾設置,它依賴于從數據源得到的連接來管理事務范圍。推薦使用。
- MANAGED:這個配置幾乎沒做什么。它從來不提交或回滾一個連接。需要自己手動添加并管理。不推薦使用。
-
dataSource
標簽:數據源,也就是連接池配置。這里type指定數據源類型,有三種內建的類型:JNDI
、POOLED
、UNPOOLED
JNDI
:已過時,不推薦使用!POOLED
:使用連接池,mybatis會創建連接池,并從連接池中獲取連接訪問數據庫,在操作完成后,將會把連接返回連池。UNPOOLED
:不使用連接池,該方式適用于只有小規模數量并發用戶的簡單應用程序上。
-
mappers
標簽:用于導入mapper文件的位置,其中可以配置多個mapper,即可以導入多個mapper文件。
(二)EmpMapper.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值應該保證唯一
在程序中通過[ namespace + id ]定位到要執行哪一條SQL語句
-->
<mapper namespace="EmpMapper">
<!-- 通過select、insert、update、delete標簽聲明要執行的SQL -->
<!-- 練習1: 查詢emp表中的所有員工信息
resultType指定查詢的結果將會封裝到什么類型中
即使最終返回的結果是集合(List<Emp>),resultType也只需要指定集合中的泛型即可!
-->
<select id="findAll" resultType="com.tedu.pojo.Emp">
select * from emp
</select>
</mapper>
(1)第1行是xml的文檔聲明,用于聲明xml的版本和編碼
(2)第2、3、4行,引入了xml約束文檔,當前xml文檔將會按照mybatis-3-mapper.dtd文件所要求的規則進行書寫。
(3)Mapper
標簽:根標簽,其中namespace(名稱空間,也叫命名空間),要求不能重復。在程序中通過[ namespace + id ]
定位到要執行哪一條SQL語句
(4)select
標簽:用于指定將來要執行的各種SQL語句。標簽上可以聲明屬性,下面介紹常用的屬性:id
、resultType
、resultMap
-
id
屬性:要求值不能重復。將來在執行SQL時,可以通過[ namespace + id ]
找到指定SQL并執行。 -
resultType
屬性:從這條SQL語句中返回所期望類型的類的完全限定名稱(包名+類名)。注意如果是集合情形,那應該是集合可以包含的類型,而不能是集合本身。簡而言之,resultType控制查詢SQL執行后返回值的類型或集合中的泛型,例如查詢emp表中的單條記錄,返回值是一個Emp對象,因此,
resultType="com.tedu.pojo.Emp";
如果查詢emp表中的多條記錄,返回值是一個List,此時resultType的值應該集合中的泛型,因此
resultType="com.tedu.pojo.Emp";
-
resultMap
屬性:復雜對象結構(例如多表關聯查詢等)。 使用resultType
或resultMap
,但不能同時使用。
四、MyBatis增刪改查
(一)新增員工
1、編輯EmpMapper.xml文件, 添加新增員工對應的sql.
<!-- 練習2: 新增員工信息: 趙云 保安 6000
增刪改的標簽上不用指定resultType, 因為返回值都是int類型
-->
<update id="insert" >
insert into emp value(null, '趙云', '保安', 6000)
</update>
2、編寫TestMybatis類,添加testInsert方法,實現新增員工操作。
/** 練習2: 新增員工信息: 趙云 保安 6000 */
@Test
public void testInsert() {
//執行sql語句, 返回執行結果
int rows = session.update("EmpMapper.insert");
//提交事務
session.commit();
System.out.println("影響的行數: "+rows);
}
(二)修改員工
1、編輯EmpMapper.xml文件, 添加新增員工對應的sql。
<!-- 練習3:修改員工信息:趙云 保鏢 20000 -->
<update id="update">
update emp set job='保鏢', salary=20000 where name='趙云'
</update>
2、編寫TestMybatis類,添加testUpdate方法,實現修改員工信息。
/** 練習3: 修改員工信息, 將趙云的job改為'保鏢',salary改為20000 */
@Test
public void testUpdate() {
//執行sql語句, 返回執行結果
int rows = session.update("EmpMapper.update");
//提交事務
session.commit();
System.out.println("影響行數:"+rows);
}
(三)刪除員工
1、編輯EmpMapper.xml文件, 添加新增員工對應的sql。
<!-- 練習4: 刪除name為'趙云'的記錄 -->
<update id="delete">
delete from emp where name='趙云'
</update>
2、編寫TestMybatis類,添加testDelete方法,實現刪除員工。
/** 練習4: 刪除name為'趙云'的記錄 */
@Test
public void testDelete() {
//執行sql語句, 返回執行結果
int rows = session.update("EmpMapper.delete");
//提交事務
session.commit();
System.out.println("影響行數:"+rows);
}
五、mybatis中的占位符
(一)#{}
占位符
在上面的增刪改查操作中,SQL語句中的值是寫死在SQL語句中的,而在實際開發中,此處的值往往是用戶提交過來的值,因此這里我們需要將SQL中寫死的值替換為占位符。
在mybatis中占位符有兩個,分別是 #{}
占位符 和 ${}
占位符:
#{}:
相當于JDBC中的問號(?)占位符,是為SQL語句中的參數值進行占位,大部分情況下都是使用#{}占位符; 并且當#{}占位符是為字符串或者日期類型的值進行占位時,在參數值傳過來替換占位符的同時,會進行轉義處理(在字符串或日期類型的值的兩邊加上單引號)${}
:是為SQL片段進行占位,將傳過來的SQL片段直接拼接在${}占位符所在的位置,不會進行任何的轉義處理。(由于是直接將參數拼接在SQL語句中,因此可能會引發SQL注入攻擊問題)- 需要注意的是:使用${}占位符為SQL語句中的片段占位時,即使只有一個參數,也要先將參數封裝再傳遞!
- 練習5:查詢emp表中指定id的員工信息
在mapper文件中編寫SQL語句:
<!-- 練習5: 查詢emp表中指定id的員工信息 -->
<select id="findById" resultType="com.tedu.pojo.Emp">
select * from emp where id=#{id}
</select>
Java代碼實現:
/** 練習5: 查詢emp表中指定id的員工信息 */
@Test
public void testFindById() {
//執行sql語句, 返回執行結果
Emp emp = session.selectOne( "EmpMapper.findById", 1 );
System.out.println( emp );
}
- 練習6:新增員工信息: 張飛 Java開發工程師 15000
在mapper文件中編寫SQL語句:
<!-- 練習6: 新增員工信息: 張飛 Java開發工程師 15000
如果通過map集合傳輸參數, 需要保證占位符中的變量名
和map集合中的key保持一致
如果通過pojo對象傳輸參數, 需要保證占位符中的變量名
和對象中的屬性名保持一致, 或者在pojo中有對應的
getXxx方法
-->
<update id="insert2">
insert into emp values (null, #{name}, #{job}, #{salary})
</update>
Java代碼實現:
/** 練習6: 新增員工信息: 張飛 Java開發工程師 15000 */
@Test
public void testInsert2() {
//將要傳輸的參數封裝到map集合中
//Map map = new HashMap();
//map.put("name", "張飛");
//map.put("job", "Java開發工程師");
//map.put("salary", 15000);
//也可以將要傳輸的參數封裝到Emp對象中
Emp emp = new Emp();
emp.setName("關羽123");
emp.setJob("保安");
emp.setSalary(8000.0);
//執行sql語句
intsession rows = session.update("EmpMapper.insert2", emp);
//提交事務
session.commit();
System.out.println( "影響的行數: "+rows );
}
- 練習7:修改員工信息: 張飛 架構師 25000
在mapper文件中編寫SQL語句:
<!-- 練習7: 修改員工信息: 張飛 架構師 25000 -->
<update id="update2">
update emp set job=#{job}, salary=#{salary}
where name=#{name}
</update>
Java代碼實現:
/** 練習7: 修改員工信息: 張飛 架構師 25000 */
@Test
public void testUpdate2() {
//將參數封裝到Emp對象中
Emp emp = new Emp();
emp.setName("張飛");
emp.setJob("架構師");
emp.setSalary(25000.0);
//執行sql語句
intsession rows = session.update("EmpMapper.update2", emp);
//提交事務
session.commit();
System.out.println("影響的行數: "+rows);
}
- 練習8:刪除emp表中指定id的員工信息
mapper文件配置:
<!-- 練習8:刪除emp表中指定id的員工信息 -->
<insert id="delete2" parameterType="String">
delete from emp where id=#{id}
</insert>
java代碼示例:
/* 練習8:刪除emp表中指定id的員工信息 */
public void testDelete2() throws IOException{
......
//執行SQL語句
int rows = session.delete("EmpMapper.delete2", 1);
//提交事務
session.commit();
System.out.println("影響行數:"+rows);
}
在上面的增刪改查練習中,當SQL語句中包含的參數值是傳遞過來的,在SQL語句中我們會通過#{}
占位符進行占位,在SQL語句真正執行時,再將傳遞過來的值替換SQL語句中的占位符。
其實,#{}
就是JDBC中的問號(?)占位符,因此為了安全考慮,在執行時會對傳遞過來的字符串和日期類型高的值進行轉譯處理。
例如:查詢指定name的員工信息,SQL語句為:
select * from emp where name=#{name}
其實就等價于JDBC中: select * from emp where name=?
,
如果傳過來的參數值為:王海濤,那么最終執行的SQL語句為:
-- 在參數替換占位符的同時進行了轉義處理(在值的兩邊加上了單引號)
select * from emp where name='王海濤'
(二)${}
占位符
那么如果我們在傳遞的時候不是一個參數值,而是一個SQL片段呢?
例如:在查詢時,我們想動態的傳遞查詢的列:
select #{columns} from emp
此時傳遞過來的應該是一個SQL片段,不同于上面的參數值,如果此時還用#{}
,也會像上面一樣被轉譯處理:select 'id,name,job' from emp
,這不是我們希望看到的!
如果不想讓傳過來的SQL片段被轉譯處理,而是直接拼接在SQL語句中,那么這里可以使用${}
,例如:
select ${columns} from emp
拼接之后:select id,name,job from emp
- 練習9:動態指定要查詢的列
在mapper文件中編寫SQL語句:
<!-- 練習9: 動態指定要查詢的列 -->
<select id="findAll2" resultType="com.tedu.pojo.Emp">
select ${cols} from emp
</select>
java代碼示例:
/** 練習9: 動態指定要查詢的列 */
@Test
public void testFindAll2() {
Map map = new HashMap();
//map.put("cols", "id, name");
//map.put("cols", "id, name, salary");
map.put("cols", "id,name,job,salary");
//執行sql語句, 返回結果
List<Emp> list = session.selectList("EmpMapper.findAll2", map);
//輸出結果
for ( Emp e : list ) {
System.out.println( e );
}
}
- 示例2: 根據name模糊查詢emp表
在mapper文件中編寫SQL語句:
<!-- 練習10: 根據name模糊查詢emp表 -->
<select id="findAll3" resultType="com.tedu.pojo.Emp">
select * from emp
where name like '%${name}%'
</select>
<!-- 練習11: 根據name模糊查詢emp表 -->
<select id="findAll4" resultType="com.tedu.pojo.Emp">
select * from emp
where name like #{name}
</select>
Java代碼實現:
/**
* 練習10: 根據name模糊查詢emp表
* '%王%' '%劉%'
*/
@Test
public void testFindAll3() {
//將參數封裝到map集合中
Map map = new HashMap();
map.put("name", "濤");
//執行sql, 返回結果
List<Emp> list = session.selectList("EmpMapper.findAll3", map);
//輸出結果
for (Emp emp : list) {
System.out.println( emp );
}
}
/**
* 練習11: 根據name模糊查詢emp表
* '%王%' '%劉%'
*/
@Test
public void testFindAll4() {
//將參數封裝到map集合中
Map map = new HashMap();
map.put("name", "%劉%");
//執行sql, 返回結果
List<Emp> list = session.selectList("EmpMapper.findAll4", map);
//輸出結果
for (Emp emp : list) {
System.out.println( emp );
}
}
需要注意的是,在傳遞 ${}
對應的值時,即使只有一個參數,也需要將值存入map集合中!!
總結:在大多數情況下還是使用#{}占位符,而${}多用于為SQL片段進行占位!
智能推薦
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
猜你喜歡
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...
19.vue中封裝echarts組件
19.vue中封裝echarts組件 1.效果圖 2.echarts組件 3.使用組件 按照組件格式整理好數據格式 傳入組件 home.vue 4.接口返回數據格式...