MyBatis学习存档(4)——进行CRUD操作
使用MyBatis進(jìn)行數(shù)據(jù)庫(kù)的CRUD操作有2種方式:一種如之前所說(shuō)的接口+xml,而另一種是通過(guò)對(duì)接口上的方法加注解(@Select @Insert @Delete @Update)
但是通常情況下不建議使用注解進(jìn)行操作,原因在于MyBatis最強(qiáng)大的特性在于其動(dòng)態(tài)sql,若使用注解則無(wú)法使用動(dòng)態(tài)sql
因此此處僅僅對(duì)注解進(jìn)行簡(jiǎn)單的舉例
一、注解
<?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.mapper.UsersMapper" ><resultMap id="BaseResultMap" type="com.pojo.Users" ><id column="id" property="id" jdbcType="INTEGER" /><result column="name" property="name" jdbcType="VARCHAR" /><result column="password" property="password" jdbcType="VARCHAR" /></resultMap><sql id="Base_Column_List" >id, name, password</sql><select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >select <include refid="Base_Column_List" />from userswhere id = #{id,jdbcType=INTEGER}</select><update id="updateByPrimaryKeySelective" parameterType="com.pojo.Users" >update users<set ><if test="name != null" >name = #{name,jdbcType=VARCHAR},</if><if test="password != null" >password = #{password,jdbcType=VARCHAR},</if></set>where id = #{id,jdbcType=INTEGER}</update><update id="updateByPrimaryKey" parameterType="com.pojo.Users" >update usersset name = #{name,jdbcType=VARCHAR},password = #{password,jdbcType=VARCHAR}where id = #{id,jdbcType=INTEGER}</update> </mapper> UsersMapper.xml package com.mapper;import org.apache.ibatis.annotations.Select;import com.pojo.Users;public interface UsersMapper {@Select("select id, name, password from users where id = #{id}")Users selectByPrimaryKey(Integer id);int updateByPrimaryKeySelective(Users record); } UsersMapper.java依舊以之前反向生成的UsersMapper為例,為顯得簡(jiǎn)潔些,僅保留了2個(gè)方法:selectByPrimaryKey和updateByPrimaryKeySelective
打上注解的方法selectByPrimaryKey,其注解效果和xml中的一致,但updateByPrimaryKeySelective方法卻無(wú)法打上注解,原因無(wú)它,該方法使用了動(dòng)態(tài)sql,而注解中無(wú)法使用動(dòng)態(tài)sql
二、接口+xml
為了之后好舉例,此處重新創(chuàng)建了一個(gè)名為student的表,并反向生成了映射文件和實(shí)體類(lèi),并進(jìn)行了些許改動(dòng)
2.1 創(chuàng)建student表并反向生成映射文件和實(shí)體類(lèi)
sql語(yǔ)句如下:
CREATE TABLE student(id INT PRIMARY KEY identity(1,1), name VARCHAR(20), class VARCHAR(20));反向生成步驟不再多說(shuō)
2.2 更改映射文件和實(shí)體類(lèi)
反向生成后會(huì)發(fā)現(xiàn)實(shí)體類(lèi)Student報(bào)錯(cuò)了,點(diǎn)開(kāi)發(fā)現(xiàn)在class處報(bào)錯(cuò)——class是java的關(guān)鍵字
所以我們應(yīng)當(dāng)將class改成clazz,這樣就不會(huì)報(bào)錯(cuò)了
僅僅更改實(shí)體類(lèi)是不夠的,還需將映射xml中對(duì)應(yīng)的字段進(jìn)行修改
最后對(duì)接口及xml進(jìn)行一定的更改,最終結(jié)果如下
package com.mapper;import com.pojo.Student;public interface StudentMapper {//通過(guò)id刪除學(xué)生int deleteById(Integer id);//添加學(xué)生int insertStudent(Student record);//通過(guò)id查找學(xué)生 Student selectById(Integer id); } StudentMapper.java <?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.mapper.StudentMapper" ><resultMap id="BaseResultMap" type="com.pojo.Student" ><id column="id" property="id" jdbcType="INTEGER" /><result column="name" property="name" jdbcType="VARCHAR" /><result column="class" property="clazz" jdbcType="VARCHAR" /></resultMap><sql id="Base_Column_List" >id, name, class</sql><!-- 通過(guò)id查找學(xué)生 --><select id="selectById" resultMap="BaseResultMap" parameterType="java.lang.Integer" >select <include refid="Base_Column_List" />from studentwhere id = #{id,jdbcType=INTEGER}</select><!-- 通過(guò)id刪除學(xué)生 --><delete id="deleteById" parameterType="java.lang.Integer" >delete from studentwhere id = #{id,jdbcType=INTEGER}</delete><!-- 添加學(xué)生 --><insert id="insertStudent" parameterType="com.pojo.Student" >insert into student (name, class)values (#{name,jdbcType=VARCHAR}, #{clazz,jdbcType=VARCHAR})</insert> </mapper> StudentMapper.xml package com.pojo;public class Student {private Integer id;private String name;private String clazz;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 == null ? null : name.trim();}public String getClazz() {return clazz;}public void setClazz(String clazz) {this.clazz = clazz == null ? null : clazz.trim();}@Overridepublic String toString() {return "Student [id=" + id + ", name=" + name + ", clazz=" + clazz + "]";} } Student.java2.3 對(duì)數(shù)據(jù)庫(kù)進(jìn)行CRUD操作
1、首先添加一個(gè)學(xué)生,代碼如下:
package com.test;import java.io.InputStream;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;import com.mapper.StudentMapper; import com.pojo.Student;public class TestInsert {public static void main(String[] args) throws Exception {//mybatis的核心配置文件String resource = "mybatis-config.xml";//使用MyBatis提供的Resources類(lèi)加載mybatis的配置文件InputStream is = Resources.getResourceAsStream(resource);//構(gòu)建SqlSession的工廠SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);//開(kāi)啟SqlSessionSqlSession session = factory.openSession();//通過(guò)映射接口執(zhí)行操作StudentMapper mapper = session.getMapper(StudentMapper.class);//new一個(gè)名叫張三 一年1班的學(xué)生Student stu = new Student();stu.setName("張三");stu.setClazz("一年1班");try {mapper.insertStudent(stu);//提交 session.commit();} catch (Exception e){//回滾 session.rollback();System.out.println("添加失敗");} finally {session.close();}System.out.println("添加成功");}}結(jié)果:可以從日志中看到sql語(yǔ)句及傳入的參數(shù),最后輸出“添加成功”
在數(shù)據(jù)庫(kù)里查看下添加的結(jié)果:確實(shí)多了一條數(shù)據(jù)
為了之后方便操作,在此可以多添加幾條數(shù)據(jù):
2、查詢指定id的學(xué)生,代碼如下:
package com.test;import java.io.InputStream;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;import com.mapper.StudentMapper; import com.pojo.Student;public class TestSelect {public static void main(String[] args) throws Exception {//mybatis的核心配置文件String resource = "mybatis-config.xml";//使用MyBatis提供的Resources類(lèi)加載mybatis的配置文件InputStream is = Resources.getResourceAsStream(resource);//構(gòu)建SqlSession的工廠SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);//開(kāi)啟SqlSessionSqlSession session = factory.openSession();//通過(guò)映射接口執(zhí)行操作StudentMapper mapper = session.getMapper(StudentMapper.class);Student student = mapper.selectById(1);System.out.println(student);session.close();}}結(jié)果如下:
3、刪除指定id的學(xué)生,代碼如下:
package com.test;import java.io.InputStream;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;import com.mapper.StudentMapper;public class TestDelete {public static void main(String[] args) throws Exception {//mybatis的核心配置文件String resource = "mybatis-config.xml";//使用MyBatis提供的Resources類(lèi)加載mybatis的配置文件InputStream is = Resources.getResourceAsStream(resource);//構(gòu)建SqlSession的工廠SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);//開(kāi)啟SqlSessionSqlSession session = factory.openSession();//通過(guò)映射接口執(zhí)行操作StudentMapper mapper = session.getMapper(StudentMapper.class);try {mapper.deleteById(5);//提交 session.commit();} catch (Exception e){//回滾 session.rollback();System.out.println("刪除失敗");} finally {session.close();}System.out.println("刪除成功");}}結(jié)果如下:
現(xiàn)在再看數(shù)據(jù)庫(kù)中的數(shù)據(jù),發(fā)現(xiàn)id為5的學(xué)生已經(jīng)不見(jiàn)了:
4、更改指定id的學(xué)生姓名
此時(shí),StudentMapper里并沒(méi)有update相關(guān)的方法,所以需要手動(dòng)添加方法。現(xiàn)在接口中定義updateStudentById方法,然后在xml中編寫(xiě)相應(yīng)的節(jié)點(diǎn):使用update節(jié)點(diǎn),id與方法名一致,傳入?yún)?shù)類(lèi)型為Student類(lèi),節(jié)點(diǎn)內(nèi)為sql語(yǔ)句
package com.mapper;import com.pojo.Student;public interface StudentMapper {//通過(guò)id刪除學(xué)生int deleteById(Integer id);//添加學(xué)生int insertStudent(Student record);//通過(guò)id查找學(xué)生 Student selectById(Integer id);//更改指定id學(xué)生的姓名int updateStudentById(Student student); } StudentMappe.java <?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.mapper.StudentMapper" ><resultMap id="BaseResultMap" type="com.pojo.Student" ><id column="id" property="id" jdbcType="INTEGER" /><result column="name" property="name" jdbcType="VARCHAR" /><result column="class" property="clazz" jdbcType="VARCHAR" /></resultMap><sql id="Base_Column_List" >id, name, class</sql><!-- 通過(guò)id查找學(xué)生 --><select id="selectById" resultMap="BaseResultMap" parameterType="java.lang.Integer" >select <include refid="Base_Column_List" />from studentwhere id = #{id,jdbcType=INTEGER}</select><!-- 通過(guò)id刪除學(xué)生 --><delete id="deleteById" parameterType="java.lang.Integer" >delete from studentwhere id = #{id,jdbcType=INTEGER}</delete><!-- 添加學(xué)生 --><insert id="insertStudent" parameterType="com.pojo.Student" >insert into student (name, class)values (#{name,jdbcType=VARCHAR}, #{clazz,jdbcType=VARCHAR})</insert><!-- 更改指定id學(xué)生的姓名 --><update id="updateStudentById" parameterType="com.pojo.Student">update student set name = #{name} where id = #{id}</update> </mapper> StudentMapper.xml編寫(xiě)測(cè)試類(lèi),先從數(shù)據(jù)庫(kù)中查詢獲得需要修改的學(xué)生信息,再更改其姓名,最后提交
package com.test;import java.io.InputStream;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;import com.mapper.StudentMapper; import com.pojo.Student;public class TestUpdate {public static void main(String[] args) throws Exception {//mybatis的核心配置文件String resource = "mybatis-config.xml";//使用MyBatis提供的Resources類(lèi)加載mybatis的配置文件InputStream is = Resources.getResourceAsStream(resource);//構(gòu)建SqlSession的工廠SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);//開(kāi)啟SqlSessionSqlSession session = factory.openSession();//通過(guò)映射接口執(zhí)行操作StudentMapper mapper = session.getMapper(StudentMapper.class);Student student = mapper.selectById(4);System.out.println(student);student.setName("趙六");try{mapper.updateStudentById(student);//提交 session.commit();} catch (Exception e){//回滾 session.rollback();System.out.println("更改失敗");}System.out.println("更改成功");session.close();}}結(jié)果和數(shù)據(jù)庫(kù)如下:
5、現(xiàn)更改需求:更改指定id學(xué)生所在的班級(jí)
又多了一個(gè)update的需求,需要再新增一個(gè)方法嗎?并不需要,只需在updateStudentById方法對(duì)應(yīng)的映射sql中進(jìn)行更改就可以了,這時(shí)就可以用到動(dòng)態(tài)sql了
<!-- 更改指定id學(xué)生的姓名 --><update id="updateStudentById" parameterType="com.pojo.Student">update student<set><if test="name != null">name = #{name} ,</if><if test="clazz != null">class = #{clazz} ,</if></set>where id = #{id}</update>將update節(jié)點(diǎn)改為上述,再編寫(xiě)測(cè)試類(lèi)
package com.test;import java.io.InputStream;import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;import com.mapper.StudentMapper; import com.pojo.Student;public class TestUpdate {public static void main(String[] args) throws Exception {//mybatis的核心配置文件String resource = "mybatis-config.xml";//使用MyBatis提供的Resources類(lèi)加載mybatis的配置文件InputStream is = Resources.getResourceAsStream(resource);//構(gòu)建SqlSession的工廠SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);//開(kāi)啟SqlSessionSqlSession session = factory.openSession();//通過(guò)映射接口執(zhí)行操作StudentMapper mapper = session.getMapper(StudentMapper.class);Student student = new Student();student.setId(4);student.setClazz("三年1班");System.out.println(student);try{mapper.updateStudentById(student);//提交 session.commit();} catch (Exception e){//回滾 session.rollback();System.out.println("更改失敗");}System.out.println("更改成功");session.close();}}先new一個(gè)Student,再set它的id和class,此時(shí)name為null,執(zhí)行update操作
可以看見(jiàn)執(zhí)行的sql為update student SET class = ? where id = ??
如果我們將name的值set為aaa,再看執(zhí)行的sql語(yǔ)句:
可以看見(jiàn)執(zhí)行的sql為update student SET name = ? , class = ? where id = ??
這就是動(dòng)態(tài)sql,除了if外,還有choose (when, otherwise),trim (where, set),foreach,這些節(jié)點(diǎn)的使用方式與JSTL標(biāo)簽的使用類(lèi)似
三、動(dòng)態(tài)sql
3.1 if
最簡(jiǎn)單的節(jié)點(diǎn),只需配置test屬性即可,test內(nèi)為布爾表達(dá)式,為true時(shí)if語(yǔ)句塊中的sql語(yǔ)句才會(huì)存在,且不會(huì)對(duì)sql進(jìn)行任何變動(dòng),因此有時(shí)會(huì)出現(xiàn)多逗號(hào)、and、or、where的情況,通常與對(duì)應(yīng)的節(jié)點(diǎn)使用,如set、where等
3.2 choose (when, otherwise)
choose節(jié)點(diǎn)下有2個(gè)子節(jié)點(diǎn)when和otherwise,when節(jié)點(diǎn)中有1個(gè)屬性test,和if的類(lèi)似
該節(jié)點(diǎn)的語(yǔ)法與if...else if...else類(lèi)似
<choose><when test="表達(dá)式1">sql語(yǔ)句1</when><when test="表達(dá)式2">sql語(yǔ)句2</when><otherwise>sql語(yǔ)句3</otherwise> </choose>例如上述例子,當(dāng)表達(dá)式1為true時(shí),有且僅有sql語(yǔ)句1會(huì)被執(zhí)行,不會(huì)有2和3;當(dāng)表達(dá)式1、2都不滿足時(shí),就會(huì)執(zhí)行sql語(yǔ)句3
3.3 trim
有4個(gè)屬性:prefix、suffix、prefixOverrides、suffixOverrides。它可以更靈活地去除多余關(guān)鍵字,可以替代where和set
以2.5中的sql語(yǔ)句為例,可變更如下,效果是一樣的:
<!-- 更改指定id學(xué)生的姓名 --><update id="updateStudentById" parameterType="com.pojo.Student">update student<trim prefix="set" suffixOverrides="," suffix="where id = #{id}"> <if test="name != null">name = #{name},</if><if test="clazz != null">class = #{clazz},</if></trim></update>3.4 foreach
用于迭代一個(gè)集合,通常用于in條件,其屬性如下:
item:集合名稱(chēng)(傳入的變量名)
index:指定迭代次數(shù)的名稱(chēng)
collection:必須指定,表示傳入的集合是什么類(lèi)型的
list
array
map-key
open:語(yǔ)句的開(kāi)始
separator:每次循環(huán)的分割符
close:語(yǔ)句的結(jié)束
轉(zhuǎn)載于:https://www.cnblogs.com/s1165482267/p/8038590.html
總結(jié)
以上是生活随笔為你收集整理的MyBatis学习存档(4)——进行CRUD操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 使用 Skeleton Screen 提
- 下一篇: GC 年轻代 老年代 持久代