(一)本文简介
本文主要记录一下mybatis的常用操作:增、删、改、查(列表查询、关联查询),基本的实现思路都是分两步进行
1.mapper文件中利用标签定义操作语句,如果是查询语句并且返回结果是多条数据的同时也要定义结果集的映射关系,所有操作相关的标签都是定义在<mapper>与</mapper>之间的下文将不再重复
2.在接口中定义与之匹配的方法,注意接口的方法和参数,一定要与 mapper文件中的标签ID、parameterType保持一至
3.定义测试方法(即具体实现代码),所有的测试方法都是基于上一章中测试类TestPerson添加的方法。
(二)新增操作
1.在mapper文件中定义插入语句,如
<!-- inset:标签是用于执行插入数据语句inset into id:标签的唯一标识,在接口方式调用时与接口中的方法名称一至 parameterType:参数类型,在接口方式调用时与接口中的参数类型一至 useGeneratedKeys:MyBatis是否获取由数据库自动生成的主键,true表示获取数据库生成的主键值 keyProperty:主键名称,返回的主键值设置到实体哪个属性中,这个方便插入数据后知道生成的主键ID,与上面属性配套使用 --> <insert id="addPerson" parameterType="com.lql.study.model.Person" useGeneratedKeys="true" keyProperty="pid"> insert into person(name,sex,age,remark) values(#{name},#{sex},#{age},#{remark}) </insert>
2.接口定义插入的方法
public void addPerson(Person p);
3.测试方法
public int addPerson() { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); Person p=new Person(); p.setName("测试三"); p.setAge(12); p.setSex("女"); p.setRemark("测试"); op.addPerson(p); session.commit();//注意一定要提交否则不会插入到数据库内 System.out.println("新增的用户ID:"+p.getPid()); session.close(); return p.getPid(); }
(三)修改操作
1.在mapper文件中定义修改语句,如
<!-- update:标签是用于执行数据库更新语句update id:标签的唯一标识,在接口方式调用时与接口中的方法名称一至 parameterType:参数类型,在接口方式调用时与接口中的参数类型一至 --> <update id="updatePerson" parameterType="com.lql.study.model.Person" > update person set name=#{name},age=#{age},sex=#{sex},remark=#{remark} where pid=#{pid} </update>
2.接口中定义修改方法
public void updatePerson(Person p);
3.测试方法
public void updatePerson(int pid) { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); Person p=selectById(pid); p.setAge(66); p.setRemark("修改了年龄"); op.updatePerson(p); session.commit();//注意一定要提交否则在数据库中不起作用 session.close(); }
(三)删除操作
1.在mapper文件中定义删除语句,如
<!-- delete:标签是用于执行数据库删除语句delete from id:标签的唯一标识,在接口方式调用时与接口中的方法名称一至 parameterType:参数类型,在接口方式调用时与接口中的参数类型一至 --> <delete id="deletePerson" parameterType="int"> delete from person where pid=#{pid} </delete>
2.在接口中定义删除方法
public void deletePerson(int pid);
3.测试方法
public void deletePerson(int pid) { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); op.deletePerson(pid); session.commit();//注意一定要提交否则在数据库中不起作用 session.close(); }
(四)列表查询
1.在mapper文件中定义查询语句和结果集映射,如
<!-- 为了返回list 类型而定义的returnMap --> <resultMap type="com.lql.study.model.Person" id="resultListPerson"> <id column="pid" property="pid" /> <result column="name" property="name" /> <result column="sex" property="sex" /> <result column="age" property="age" /> <result column="remark" property="remark" /> <result column="createtime" property="createtime" /> </resultMap> <!-- 返回list 的select 语句,注意 resultMap 的值是指向前面定义好的 #{0} 、#{1} 代表参数索应号与接口方法中的参数序列一至 --> <select id="selectPerson" resultMap="resultListPerson"> select * from person where sex=#{0} and age>=#{1} </select>
2.接口中定义查询方法
public List<Person> selectPerson(String sex,int age);
3.测试方法
public void queryPersonBySex(String sex,int age) { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); List<Person> persons=op.selectPerson(sex,age); if(persons.size()>0) { for(int i=0;i<persons.size();i++) { System.out.println(persons.get(i).getName()+","+persons.get(i).getSex()+" ,"+persons.get(i).getAge()); } } session.close(); }
(五)关联查询,一对多查询
数据库中存在一张score表用于存储每人每个科目的成绩,结构如下
其体类定义如下
package com.lql.study.model; /** * Score entity. @author MyEclipse Persistence Tools */ public class Score implements java.io.Serializable { // Fields private Integer sid; private Person person; private Double score; private String subject; // Constructors /** default constructor */ public Score() { } /** full constructor */ public Score(Person person, Double score, String subject) { this.person = person; this.score = score; this.subject = subject; } // Property accessors public Integer getSid() { return this.sid; } public void setSid(Integer sid) { this.sid = sid; } public Person getPerson() { return this.person; } public void setPerson(Person person) { this.person = person; } public Double getScore() { return this.score; } public void setScore(Double score) { this.score = score; } public String getSubject() { return this.subject; } public void setSubject(String subject) { this.subject = subject; } }
1.定义查询语句与结果集映射
方法一
<!-- person 联合score进行查询 方法之一的配置 (多对一的方式) 查询结果是一个List<Score>的集合 --> <resultMap id="resultPersonScore" type="com.lql.study.model.Score"> <!-- 定义每一个score的属性值与查询结果集对应字段的映射关系 --> <id property="sid" column="sid" /> <result property="score" column="score" /> <result property="subject" column="subject" /> <!-- association 定义score中person实体的映射关系 --> <association property="person" javaType="com.lql.study.model.Person" > <id property="pid" column="pid" /> <result column="name" property="name" /> <result column="sex" property="sex" /> <result column="age" property="age" /> <result column="remark" property="remark" /> <result column="createtime" property="createtime" /> </association> </resultMap> <!-- 查询语句--> <select id="queryPersonScore" parameterType="string" resultMap="resultPersonScore"> select p.pid,p.name,p.sex,p.age,p.remark,p.createtime,s.sid,s.score,s.subject from person p,score s where p.pid=s.pid and p.name=#{name} </select>
方法2,对于resultMap还有另外一种用法,就是使用前面定义的person列表结果resultMap减少重复的代码,例如
<resultMap id="resultPersonScore-2" type="com.lql.study.model.Score"> <!-- 定义每一个score的属性值与查询结果集对应字段的映射关系 --> <id property="sid" column="sid" /> <result property="score" column="score" /> <result property="subject" column="subject" /> <!--association 定义score中person实体的映射关系 --> <association property="person" javaType="com.lql.study.model.Person" resultMap="resultListPerson" > </association> </resultMap>
2.接口定义查询方法使之与mapper文件对应
public List<Score> queryPersonScore(String name);
3.测试方法,即具体实现
public void queryScoreByName(String name) { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); List<Score> scores=op.queryPersonScore(name); if(scores.size()>0) { for(int i=0;i<scores.size();i++) { System.out.println(scores.get(i).getPerson().getName()+","+scores.get(i).getSubject()+" ,"+scores.get(i).getScore()); } } session.close(); }
完整的测试类代码如下
package com.lql.study.action; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.List; 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.lql.study.model.Person; import com.lql.study.model.Score; public class TestPerson { //mybatis的配置文件 private String resource = "mybatis-config.xml"; private SqlSessionFactory sessionFactory; public TestPerson() throws IOException { //使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件) Reader reader = Resources.getResourceAsReader(resource); //构建sqlSession的工厂 this.sessionFactory = new SqlSessionFactoryBuilder().build(reader); } public Person selectById(int pid) { //创建能执行映射文件中sql的sqlSession SqlSession session = sessionFactory.openSession(); /*** 映射sql的标识字符串, * * com.lql.study.model.personMapper是personMapper.xml文件中mapper标签的namespace属性的值, * getPerson是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL * */ /** String statement = "com.lql.study.model.personMapper.getPerson";//映射sql的标识字符串由映射文件里的namespace+select id组成 执行查询返回一个唯一person对象的sql //selectOnet顾名思义是查询单个对象,46是输入参数,查询person中pid=46的记录 Person person1 = session.selectOne(statement,46); System.out.println(person1.getName()); **/ //以下是接口方法方式 IPersonOption op=session.getMapper(IPersonOption.class); Person person2=op.getPerson(pid); System.out.println(person2.getName()); session.close(); return person2; } public void queryPersonBySex(String sex,int age) { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); List<Person> persons=op.selectPerson(sex,age); if(persons.size()>0) { for(int i=0;i<persons.size();i++) { System.out.println(persons.get(i).getName()+","+persons.get(i).getSex()+" ,"+persons.get(i).getAge()); } } session.close(); } public int addPerson() { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); Person p=new Person(); p.setName("测试三"); p.setAge(12); p.setSex("女"); p.setRemark("测试"); op.addPerson(p); session.commit();//注意一定要提交否则不会插入到数据库内 System.out.println("新增的用户ID:"+p.getPid()); session.close(); return p.getPid(); } public void updatePerson(int pid) { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); Person p=selectById(pid); p.setAge(66); p.setRemark("修改了年龄"); op.updatePerson(p); session.commit();//注意一定要提交否则在数据库中不起作用 session.close(); } public void deletePerson(int pid) { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); op.deletePerson(pid); session.commit();//注意一定要提交否则在数据库中不起作用 session.close(); } public void queryScoreByName(String name) { SqlSession session = sessionFactory.openSession(); IPersonOption op=session.getMapper(IPersonOption.class); List<Score> scores=op.queryPersonScore(name); if(scores.size()>0) { for(int i=0;i<scores.size();i++) { System.out.println(scores.get(i).getPerson().getName()+","+scores.get(i).getSubject()+" ,"+scores.get(i).getScore()); } } session.close(); } public static void main(String[] args) { try { TestPerson test= new TestPerson(); test.queryPersonBySex("男",3); int pid=test.addPerson(); test.updatePerson(pid); test.deletePerson(pid); test.queryScoreByName("柳时镇"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }