原文: https://blog.csdn.net/xyz_dream/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 操作,下次讲关于多表联合查询的内容。