mybatis的学习探讨(中 )

原文: https://mojun.blog.csdn.net/article/details/52735315

继续探讨mybatis的学习,今天要讲的知识点无非就是对数据库的CRUD操作。前天讲到的是没有以对象Object形式进行的简单查询,这次讲的是以实体类的形式对数据库进行操作。

现在数据库中有3个表,分别是:


person (玩家表,user_qq(pk),user_name,age, sex )


1234 tom 30 man


1235 mary 18 woman


record (游戏记录表,中间表。id(pk),user_qq,game_id,game_score)


1 1234 103 99


2 1234 104 89


3 1235 102 100


game (游戏详情表,id(pk),game_id,game_name)


1 102 lol英雄联盟


2 103 刀塔


3 104 魔兽世界


注:主键自增


第一步: 分析关系



从上面的数据表中可以看出:


1.person 和 record 呈 1:n的关系


2.record 和 game 呈 n:1 的关系。


3.自然得到: person 和 game 呈 n:n的关系: 一个人可以玩多款游戏,一款游戏也可以被多个人玩。



第二步: 分别建立实体类 Person Record Game


举个例子,做法和都一致:(实体类)


package xyz.dream.data.model;


class Person{


private int userQq;


private String userName;


priavte int age;


private String sex;


//自己添加 字段 set get方法,重写toString方法方便测试,


}


第三步: 介绍一下 DataBaseMapper.xml 中的新标签: <resultMap>


这个标签是用来对你查询到的结果集和实体类之间字段的映射关系:(例如)


//指定唯一 id //指定 数据类型,写上完全限定名


<resultMap id=”PersonResultMap” class=”xyz.dream.data.model.Person”>


<id column=”user_qq” property=”userQq”/> <!– 主键映射 –>


<result column=”user_name” property=”userName”/> <!– 普通字段映射–>


<result column=”age” property=”age”/>


<result column=”sex” property=”sex”/>


</resultMap>


测试一: 单表查询(<select>标签的使用)(返回Person对象的集合)


1./ id 唯一标识 / 2./resultMap 引用上面的resultMap映射 关系 /


<select id=”selectPersonListById” resultMap=”PersonResultMap” >


select from person


</select>


测试代码: ————————————————————————————


List<Person> persons=session.selectList(“selectPersonListById”);


System.out.println(persons);// 查询返回结果



测试二: 单表插入数据(<insert>标签的使用)(传递Person 对象),不返回插入后的记录id


/传递参数类型指定,插入无返回值指定/


<insert id=”insertPersonByObjectPerson” parameterType=”xyz.dream.data.model.Person” >


insert into person (user_qq,user_name,age,sex) values (


#{userQq},#{userName},#{age},#{sex} )


</insert>



测试代码:————————————————————————————


//插入一个用户 user_qq:1236 user_name:张三 age:20 sex:女


Person person=new person;


person.setUserQq(1236);


person.setUserName(“张三”);


person.setAge(20);


person.setSex(“女”);


int status=session.insert(“insertPersonByOjectPerson”,person);


session.commit();//提交事务


System.out.println(status);//插入成功返回 1




测试 三: 单表插入数据(<insert><selectKey>标签的使用)(传Person对象),返回插入记录数。


测试二基础上,在<insert>标签内添加以下标签:


// order :{ AFTER:代表Mysql }


<selectKey keyProperty=”userQq” order=”AFTER” resultType=”java.lang.Integer”>


select LAST_INSERT_ID() //固定写法


</selectKey>


测试代码: ————————————————————————————


//不指定userQq 主键自增


Person person=new person();


person.setUserName(“张三”);


person.setAge(20);


person.setSex(“女”);


int status=session.insert(“insertPersonByOjectPerson”,person);


System.out.println(status);//插入成功返回 1


System.out.println(person.getUserQQ); //显示1237 ,若是不添加返回主键 记录,此时显示为 null


session.commit();//提交事务




测试四 : 多记录插入(<foreach>标签的使用) ,传入数据为集合 List<person>


<insert id=”insertManyPerson” paramterType=”java.util.Map” >


insert into person values


/集合persons,item 是单个person ,separator=”,”分隔符号为逗号/


<foreach collection=”persons” item=”person” separator=”,”>


(#{userQq},#{userName},#{age},#{sex})


</foreach>


<!– 以上语句其实是在做这个一件事: insert into person 循环打印 (#{userQq},#{userName},#{age},#{sex}),并且使用”,”隔开,每一个#{}里面的值替换为每个person的值。–>


</insert>


测试代码:————————————————————————————


//一次性 插入20条数据


Map<String,Object> map=new hashMap<String,Object>();


List<Person> personList=new ArrayList<Person>();


for(int i=1;i<=20;i++){


Person person=new Person();


person.setUserQq(i);


person.setUserName(“新插入”+i);


person.setAge(18+i);


person.setSex(“男”);


}


map.put(“persons”,personList); //把personList 以persons为参数传递过去,参数名称必须和标签<foreach >中的collection一样,否则出错!!


int status=session.insert(“insertManyPersons”,map);


System.out.println(status);//显示查询结果 1成功 0失败


session.commit();//提交事务


测试五: 更新数据(<update>标签的使用)


<update id=”updateByUserQq” parameterType=”xyz.dream.data.model.Person” >


update person set user_name=#{userName} where user_qq=#{userQq}


</update>


测试代码:————————————————————————————


Person person=new Person();


person.setUserQq(1234);


person.setUserName(“新更新的名字”);


int status=session.update(“updateByUserQq”,person);//更新数据


session.commit();//提交事务


提示: 此时更新数据库,大家会发现一个严重的问题:之前 1234这个用户的其他数据都变为了空null,只有user_qq=1234user_name=”新更新的名字”,其它字段都为空。因为我们传递参数的时候没有指定其它字段的值,所以这样的更新有严重缺陷的。测试六带你解决这个问题,动态sql语句。




测试六: 动态更新 (<set>标签的使用)


<update id=”updateByUserQq” parameterType=”xyz.dream.data.model.Person” >


update person


<set>


person.user_qq=#{userQq} , /保证执行的sql语句不会出错,假如其余3个字段都为空null,则真正的sql语句会变成这: update person ,<set>标签只是帮我们做了个判断师傅生成接下来的语句。不必担心”,”分隔的问题,mybatis会解决这个问题。例如:


只有 userName不为空,其它都为空,大家会觉得生成的sql语句是这样的: update person set user_qq=#{userQq},userName=#{userName} , where userQq={userQq} userName=#{userName}, 对于一个逗号。框架会处理这个问题,不必担心*/


<if test=” userName!=null”>


user_name=#{userName},


</if>


<if test=” age!=null”>


age=#{age},


</if>


<if test=” sex!=null”>


sex=#{sex}


</if>


</set>


where user_qq=#{userQq}


</update>


测试代码:————————————————————————————


Person person=new Person();


person.setUserQq(1235);


person.setUserName(“新更新的名字2”);


int status=session.update(“person.updateByUserQq”,person);//更新数据


session.commit();//提交事务


提示: 这样一来的话,不会影响未更新的数据,不会让已有数据清空。



测试七: 动态sql语句,数据删除(<delete> <where>)


<delete id=”deletePersonByUserQq” parameterType=”xyz.dream.data.model.Person”>


delete from person


<where>


<if test=”userQq!=null”>


user_qq=#{userQq},


</if>


<if test=” userName!=null”>


user_name=#{userName},


</if>


<if test=” age!=null”>


age=#{age},


</if>


<if test=” sex!=null”>


sex=#{sex}


</if>


</where>


</delete>


测试代码:————————————————————————————


Person person=new Person();


person.setUserQq(1234);


int status=person.delete(“person.deletePersonByUserQq”,person);


session.commit();//事务提交


提示 : 查看数据库,1234这个用户被删除了。不知道大家发现没有,我的sql语句有漏洞。之前这个<where>标签应该在update讲的,但是不太好再改了,大家明白意思就是了。假如我传入的person的任何字段都是空的,则 sql语句变为 delete from person. 是不是很恐怖!整个表的数据都会删了!所以大家明白我这个<where>标签和<set>标签的含义就行了,delete的时候要特别注意这个<where>的使用。


今天讲讲完了关于单表的CRUD 操作,下次讲关于多表联合查询的内容。