ORMapping:對象關係映射
關係指關係型資料庫的映射
Java到MySQL的映射,開發者可以以面向對象的思想進行開發。
」優點SQL寫在XML文件裡,降低耦合度,便於統一管理和優化,並可重用。提供映射標籤,支持對象與資料庫的ORM欄位關係映射。缺點SQL語句編寫工作量較大,尤其是欄位多,關聯表多時,更是複雜。SQL語句依賴資料庫,不同資料庫SQL語句存在細微差異,不能隨意更換資料庫。開發方式初步使用導入依賴
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!--mysql驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>CREATE TABLE t_account(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(11) ,
pwd VARCHAR(11),
age INT
)@Data
public class Account {
private Integer id;
private String username;
private String pwd;
private Integer age;
}
全局配置核心文件SqlMapperConfig.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">
<configuration>
<!--配置mybatis運行環境-->
<environments default="development">
<environment id="development">
<!--配置jdbc事務管理-->
<transactionManager type="JDBC"/>
<!--配置JDBC數據源連接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisExercise?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="77549252"/>
</dataSource>
</environment>
</environments>
</configuration>
使用原生接口1.Mybatis框架需要開發者自定義SQL語句,寫在Mapper.xml文件中,實際開發中,會為每個實體類創建對應的Mapper.xml,定義管理該對象數據的SQL。
★namespace通常設置為文件所在包+文件名的形式。id是實際調用Mybatis方法時需要用到的參數。parameterType是調用對應方法時參數的數據類型」<?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.Long.Mapper.XML.AccountMapper">
<!-- <select id=""></select>-->
<insert id="add" parameterType="com.Long.Entity.Account">
insert into t_account(username,pwd,age) values (#{username},#{pwd},#{age});
</insert>
<!-- <delete id=""></delete>-->
<!-- <update id=""></update>-->
</mapper>2.AccountMapper.xml註冊到全局配置核心文件SqlMapperConfig.xml文件中
<!--註冊AccountMapper.xml-->
<mappers>
<!--這裡路徑用/-->
<mapper resource="com/Long/Mapper/XML/AccountMapper.xml"></mapper>
</mappers>3.pom.xml配置java目錄下的xml文件生效,默認只是resource目錄下xml文件生效
<!--配置java目錄下xml文件生效-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>4.測試
public class testMybatis {
public static void main(String[] args) {
//加載Mybatis配置文件
InputStream InputStream = testMybatis.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
SqlSession sqlSession = Factory.openSession();
String statement="com.Long.Mapper.XML.AccountMapper.add";
Account account =new Account(1,"張三","123456",18);
//提交事務
sqlSession.commit(); //查詢不需要,增刪改必須提交
//關閉連接池
sqlSession.close();
}
}
通過Mapper代理實現自定義接口(重要)自定義Mapper接口
public interface AccountMapper {
int add(Account account);
int update(Account account);
int deleteById(Integer id);
List<Account> findAll();
Account findById(Integer id);
}2.創建對應的Mapper.xml,定義接口方法對應的SQL語句。
標籤可選insert,delete,update,select。
Mybatis框架會根據規則自動創建接口實現類的代理對象。(代理的是接口,代理對象為實現類)
映射規則:
parameterType屬性值和接口中對應方法傳遞的參數類型一致。resultType屬性值和接口中對應方法返回值類型一致(只有查用寫,增刪改都是返回int)。@Test
public void test2() {
InputStream InputStream = testMybatis.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
SqlSession sqlSession = Factory.openSession();
//獲取實現接口的代理對象
AccountMapper mapper = sqlSession.getMapper(AccountMapper.class);
//增
Account account1 = new Account(1,"小風","14525",18);
mapper.add(account1);
sqlSession.commit();
//查
List<Account> accountList = mapper.findAll();
for (Account account:accountList
) {
System.out.println(account);
}
//刪
mapper.deleteById(1);
sqlSession.commit();
//查
System.out.println(mapper.findById(2));
//改
Account account2 = new Account(3, "小雨", "145256", 18);
mapper.update(account2);
sqlSession.commit();
//關閉連接池
sqlSession.close();
}
★總結」先解析resource文件夾下Config.xml文件配置的環境(如何連接資料庫)和註冊的mapper.xml文件。
Mapper.xml文件配置實體類(JavaBean)屬性與資料庫欄位如何進行映射。
級聯查詢class表
student表
Java實體類映射【Student】和【Classes】
@Data
public class Student {
private Integer id;
private String name;
private Classes classes;
}@Data
public class Classes {
private Integer id;
private String name;
private List<Student> students;
}
連接查詢一對一連接student表和class表,查詢id為1的學生(包含所在班級名稱)
SQL語句
select * from student s,class c where s.cid=c.id and s.id =1;xml配置文件
<mapper namespace="com.Long.Mapper.StudentMapper">
<resultMap id="studentMap" type="com.Long.Entity.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="classes" javaType="com.Long.Entity.Classes">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
</association>
</resultMap>
<select id="findByIdAndClass" parameterType="Integer" resultMap="studentMap">
select s.id,s.name,c.id as cid,c.name as cname from student s,class c where s.id = #{id} and s.cid = c.id
</select>
★總結
」查詢操作返回值映射resultType屬性
直接映射,即根據資料庫欄位名稱和Java對象屬性名稱和類型一一映射,resultmap屬性
根據column屬性(資料庫欄位名稱)和property屬性(Java對象屬性名)進行名稱映射的。包含多個欄位的java對象需要association標籤包含多個欄位的java集合需要association標籤一對多連接student表和class表,查詢id為2的班級中所有學生信息
SQL語句
select s.id,s.name ,c.id,c.name from student s,class c where c.id =2 and s.cid = c.idxml配置文件
<mapper namespace="com.Long.Mapper.StudentMapper">
<resultMap id="studentMap" type="com.Long.Entity.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="classes" javaType="com.Long.Entity.Classes">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
</association>
</resultMap>
<select id="findByIdAndClass" parameterType="Integer" resultMap="studentMap">
select s.id,s.name ,c.id,c.name from student s,class c where s.id = #{id} and s.cid = c.id;
</select>測試
@Test
public void test3() {
InputStream InputStream = Student.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
SqlSession sqlSession = Factory.openSession();
//獲取實現接口的代理對象
ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);
System.out.println(mapper.findStudentsByClassId(2)); //返回的集合不用for循環遍歷
sqlSession.close();
}
多對多(一對多的升級)逆向工程(代碼自動生成)★傳統的開發中上述的三個組件需要開發者手動創建,逆向工程可以幫助開發者來自動創建三個組件,減輕開發者的工作量,提高工作效率。
」MyBatis 框架需要(三個組件):
MyBatis Generator,簡稱 MBG,是⼀個專門為 MyBatis 框架開發者定製的代碼⽣成器,可自動生成MyBatis 框架所需上述三組件,也可支持基本的 CRUD 操作,但是⼀些相對複雜的 SQL 需要開發者自己來完成。
相關jar包<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>創建 MBG 配置文件 config.xml
1、jdbcConnection 配置資料庫連接信息。
2、javaModelGenerator 配置 JavaBean 的生成策略。
3、sqlMapGenerator 配置 SQL 映射文件生成策略。
4、javaClientGenerator 配置 Mapper 接口的生成策略。
5、table 配置目標數據表(tableName:表名,domainObjectName:JavaBean 類名)。
resouce目錄下的config.xml配置文件<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<jdbcConnection
driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatisExercise?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"
userId="root"
password="77549252"
/>
<javaModelGenerator targetPackage="com.Long.Entity"
targetProject="Genertor/src/main/java"/>
<sqlMapGenerator targetPackage="com.Long.Mapper.XML"
targetProject="Genertor/src/main/java"/>
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.Long.Mapper" targetProject="Genertor/src/main/java">
</javaClientGenerator>
<table tableName="t_account" domainObjectName="Account"/>
</context>
</generatorConfiguration>
Genertor類測試public class Genertor {
public static void main(String[] args) {
List<String> warings = new ArrayList<String>();
boolean overwrite = true;
String genCig = "/config.xml";
File configFile = new File(Genertor.class.getResource(genCig).getFile());
ConfigurationParser configurationParser = new
ConfigurationParser(warings);
Configuration configuration = null;
try {
configuration = configurationParser.parseConfiguration(configFile);
} catch (IOException e) {
e.printStackTrace();
} catch (XMLParserException e) {
e.printStackTrace();
}
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = null;
try {
myBatisGenerator = new
MyBatisGenerator(configuration, callback, warings);
} catch (InvalidConfigurationException e) {
e.printStackTrace();
}
try {
myBatisGenerator.generate(null);
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
目錄結構延遲加載 (懶加載)★延遲加載也叫懶加載、惰性加載,使⽤延遲加載可以提高程序的運行效率,針對於數據持久層的操左, 在某些特定的情況下去訪問特定的資料庫,在其他情況下可以不訪問某些表,從⼀定程度上減少了 Java 應用與資料庫的交互次數。
」查詢學生和班級的時,學生和班級是兩張不同的表,如果當前需求只需要獲取學生的信息,那麼查詢學生單表即可。
如果需要通過學生獲取對應的班級信息,則必須查詢兩張表。
不同的業務需求,需要查詢不同的表,根據具體的業務需求來動態減少數據表查詢的工作就是延遲加載。
之前查詢任務實現懶加載連接student表和class表,查詢id為1的學生(包含所在班級名稱)
select * from student s,class c where s.cid=c.id and s.id =1;select * from student where id =1;
當需要班級信息時,需要執行下面SQL語句,id參數為第一條語句查詢到的cid
select * from class where id =#{id};
懶加載目的:不需要獲取班級信息的需求時不需要執行第二條sql語句,增加效率,根據需求可以動態改變。
resouce目錄下的config.xml配置文件配置懶加載
<settings>
<!-- 列印SQL-->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!-- 開啟延遲加載 -->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>StudentMapper接口和ClassesMapper接口各定義查找方法
// ClassesMapper接口
public interface ClassesMapper {
Classes findById(Integer id);
}public interface StudentMapper {
Student findById(Integer id);
}配置文件配置兩條SQL語句的關係
StudentMapper.xml文件下配置
<mapper namespace="com.Long.Mapper.StudentMapper">
<resultMap id="studentMap" type="com.Long.Entity.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="classes" javaType="com.Long.Entity.Classes"
select="com.Long.Mapper.ClassesMapper.findById" column="cid"/>
</resultMap>
<select id="findById" parameterType="Integer" resultMap="studentMap">
select * from student where id =#{id};
</select>
</mapper>ClassesMapper.xml文件下配置
<mapper namespace="com.Long.Mapper.ClassesMapper">
<select id="findById" parameterType="Integer" resultType="com.Long.Entity.Classes">
select * from class where id =#{id};
</select>
</mapper>測試
@Test
緩存★
public void test3() {
InputStream InputStream = test.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
SqlSession sqlSession = Factory.openSession();
StudentMapper StudentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = StudentMapper.findById(1);
System.out.println(student.getName()); //懶加載下不需要加載班級信息,執行1條SQL語句
// System.out.println(student.getClasses()); //懶加載下需要加載班級信息,執行2條SQL語句
sqlSession.close();
}使用緩存可以減少 Java 應用與資料庫的交互次數,從而提升程序的運行效率。比如查詢出 id = 1 的對象,第⼀次查詢出之後會⾃動將該對象保存到緩存中,當下⼀次查詢時,直接從緩存中取出對象即可,無需再次訪問資料庫。
」分類1、⼀級緩存:SqlSession 級別,默認開啟,並且不能關閉。操作資料庫時需要創建SqlSession對象,在對象中有⼀個HashMap用於存儲緩存數據,不同的SqlSession 之間緩存數據區域是互不影響的。
⼀級緩存的作用域是SqlSession範圍的,當在同⼀個SqlSession中執行兩次相同的 SQL 語句事,第⼀次執行完畢會將結果保存到緩存中,第二次查詢時直接從緩存中獲取。
需要注意的是,如果SqlSession執行了 DML 操作(insert、update、delete),MyBatis 必須將緩存清空以保證數據的準確性。
驗證@Test
public void test4() {
InputStream InputStream = test.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
SqlSession sqlSession = Factory.openSession();
StudentMapper StudentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = StudentMapper.findById(1);
System.out.println(student.getName());
sqlSession.close();
SqlSession sqlSession1 = Factory.openSession(); //創建不同的SqlSession
StudentMapper StudentMapper1 = sqlSession1.getMapper(StudentMapper.class);
Student student1 = StudentMapper1.findById(1);
System.out.println(student1.getName());
sqlSession1.close();
}@Test
public void test4() {
InputStream InputStream = test.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
SqlSession sqlSession = Factory.openSession();
StudentMapper StudentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = StudentMapper.findById(1);
Student student1 = StudentMapper.findById(1);
System.out.println(student.getName());
System.out.println(student1.getName());
sqlSession.close();
}
2、二級緩存:Mapper級別,默認關閉,可以開啟。使用二級緩存時,多個SqlSession使用同⼀個Mapper的 SQL 語句操作資料庫,得到的數據會存在二級緩存區。同樣是使用HashMap進行數據存儲,相比較於⼀級緩存,二級緩存的範圍更大,多個SqlSession 可以共用二級緩存,★二級緩存是多個 SqlSession 共享的,其作用域是Mapper的同⼀個namespace,不同的SqlSession兩次執行相同的 namespace 下的 SQL 語句,參數也相等,則第⼀次執行成功之後會將數據保存到二級緩存中,第二次可直接從二級緩存中取出數據。
」Mybatis自帶二級緩存Resource目錄下的config.xml文件配置
<!-- 開啟⼆級緩存 -->
<setting name="cacheEnabled" value="true"/>Entity包下的實體類實現序列化接口
@Data
public class Student implements Serializable {
private Integer id;
private String name;
private Classes classes;
}驗證
@Test
public void test4() {
InputStream InputStream = test.class.getClassLoader().getResourceAsStream("SqlMapperConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory Factory = sqlSessionFactoryBuilder.build(InputStream);
SqlSession sqlSession = Factory.openSession();
StudentMapper StudentMapper = sqlSession.getMapper(StudentMapper.class);
Student student = StudentMapper.findById(1);
System.out.println(student.getName());
sqlSession.close();
SqlSession sqlSession1 = Factory.openSession(); //創建不同的SqlSession
StudentMapper StudentMapper1 = sqlSession1.getMapper(StudentMapper.class);
Student student1 = StudentMapper1.findById(1);
System.out.println(student1.getName());
sqlSession1.close();
}
ehcache二級緩存pom.xml導入相關jar包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.4.3</version>
</dependency>添加Resource目錄下的ehcache.xml,配置相關配置。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore/>
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>爆紅請參考
https://blog.csdn.net/qq_45738810/article/details/107908914?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161218684316780266289407%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=161218684316780266289407&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~times_rank-1-107908914.pc_search_result_no_baidu_js&utm_term=ehcache.xml
Resource目錄下的config.xml文件配置
<!-- 開啟⼆級緩存 -->
<setting name="cacheEnabled" value="true"/>Mapper.xml配置緩存策略
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<!-- 緩存創建之後,最後⼀次訪問緩存的時間至緩存失效的時間間隔 -->
<property name="timeToIdleSeconds" value="3600"/>
<!-- 緩存⾃創建時間起⾄失效的時間間隔 -->
<property name="timeToLiveSeconds" value="3600"/>
<!-- 緩存回收策略,LRU表示移除近期使⽤最少的對象 -->
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>Entity包下的實體類不需要實現序列化接口
@Data
動態SQL標籤★
public class Student {
private Integer id;
private String name;
private Classes classes;
}使用動態SQL可簡化代碼的開發,減少開發者的工作量,程序可以自動根據業務參數來決定SQL的組成。
」AccountMapper AccountMapper = sqlSession.getMapper(AccountMapper.class);
Account account = new Account(1,"小明","123",22);
System.out.println(AccountMapper.findByAccount(account));
Account accountOne = new Account("小明","123");
System.out.println(AccountMapper.findByAccount(accountOne));<!--動態執行該SQL語句,當需要根據id和username查時不需要額外的語句-->
<select id="findByAccount" parameterType="com.Long.Entity.Account" resultType="com.Long.Entity.Account">
select * from t_account where id =#{id} and username =#{username} and pwd=#{pwd} and age =#{age};
</select>上述代碼無動態SQL語句時,當只知道帳戶姓名和密碼時確匹配失敗,原因在於SQL語句多餘傳了默認值。
if 標籤★if 標籤可以自動根據表達式的結果來決定是否將對應的語句添加到 SQL 中,如果條件不成立則不添加, 如果條件成立則添加。
」where 標籤 (和if標籤連用)注意:where 標籤不會檢測SQL語句末尾多餘的and並刪除,因此and寫在前面
★where 標籤可以自動判斷是否要刪除語句塊中的 and 關鍵字,如果檢測到 where 直接跟 and 拼接,則自動刪除 and,通常情況下 if 和 where 結合起來使用。
」<select id="findByAccount" parameterType="com.Long.Entity.Account" resultType="com.Long.Entity.Account">
select * from t_account
<where>
<if test="id!=null">
id =#{id}
</if>
<if test="username!=null">
and username =#{username}
</if>
<if test="pwd!=null">
and pwd=#{pwd}
</if>
<if test="age!=null">
and age =#{age}
</if>
</where>
</select>
choose 、when 、otherwise 標籤★有時候,我們不想使用所有的條件,而只是想從多個條件中選擇一個使用。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。choose執行過程中按順序判斷 when 中的條件出否成立,如果有一個成立,則 choose 結束。當 choose 中所有 when的條件都不滿則時,則執行 otherwise 中的 sql。
」<!--動態執行該SQL語句,當需要根據id和username查時不需要額外的語句-->
<select id="findByAccount" parameterType="com.Long.Entity.Account" resultType="com.Long.Entity.Account">
select * from t_account
<where>
<choose>
<when test="id!=null">
id =#{id}
</when>
<when test="username!=null">
and username =#{username}
</when>
<when test="pwd!=null">
and pwd=#{pwd}
</when>
<when test="age!=null">
and age =#{age}
</when>
<otherwise>
<!--如果傳入參數都為null那麼就返回id=1的數據-->
id = 1
</otherwise>
</choose>
</where>
</select>
trim 標籤★trim 標籤中的 prefix 和 suffix 屬性會被用於生成實際的 SQL 語句,會和標籤內部的語句進行拼接,如果語句前後出現了 prefixOverrides或者suffixOverrides 屬性中指定的值,MyBatis 框架會自動將其刪除。
」用trim標籤實現where標籤的作用
<!--where後面發現緊跟著and就自動刪除-->
<trim prefix="where" prefixOverrides="and">
set 標籤★set 標籤用於 update 操作,會自動根據參數選擇生成 SQL 語句。
」靜態更新SQL的問題Account account = new Account(1,"小明","123",22);
System.out.println(AccountMapper.findByAccount(account));
account.setAge(18); //僅更改了年齡但SQL語句中其他屬性進行了重複賦值
AccountMapper.update(account);
System.out.println(account);<mapper namespace="com.Long.Mapper.AccountMapper">
<update id="update" parameterType="com.Long.Entity.Account">
update t_account set age=#{age},username =#{username},pwd=#{pwd} where id =#{id}
</update>
增加set標籤<mapper namespace="com.Long.Mapper.AccountMapper">
<update id="update" parameterType="com.Long.Entity.Account">
update t_account
<set>
<choose>
<when test="username!=null">
and username =#{username}
</when>
<when test="pwd!=null">
and pwd=#{pwd}
</when>
<when test="age!=null">
and age =#{age}
</when>
</choose>
</set>
where id = #{id}
</update>
foreach 標籤★foreach 標籤可以迭代生成⼀系列值,這個標籤主要用於 SQL 的 in 語句。
」舉例
僅查詢id=1,2,4的帳戶信息
靜態SQL語句select * from t_account where id in(1,2,4);
動態SQL(字符串拼接)<select id="findByIds" parameterType="com.Long.Entity.Account" resultType="com.Long.Entity.Account">
select * from t_account
<where>
<foreach collection="ids" open="id in (" close=")" item="id"
separator=",">
#{id}
</foreach>
</where>
</select>
測試ArrayList<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(4);
Account account = new Account();
account.setIds(ids);
System.out.println(AccountMapper.findByIds(account));