下面的示例所用的实体类、表和全局配置与上篇博客所述相同。
查询数据的三种方式:
一、selectList():
查询多条数据,每条数据都用一个对象存储,对象的属性值根据表的字段名和对象的属性名自动匹配赋值
1、FlowerMapper.xml文件的配置如下:
<?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="cn.jingpengchong.pojo.Flower">
<select id="selAll" resultType="cn.jingpengchong.pojo.Flower">
select * from flower
</select>
</mapper>
2、测试类文件Test.java如下:
package cn.jingpengchong.test;
import java.io.IOException;
import java.io.InputStream;
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 cn.jingpengchong.pojo.Flower;
public class Test {
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
//查询结果为List集合
List<Flower> list = session.selectList("cn.jingpengchong.pojo.Flower.selAll");
for (Flower flower : list) {
System.out.println(flower.toString());
}
session.close();
}
}
运行结果如下:
二、selectOne():
查询一条数据,如果是除String外的类类型,对象的属性值根据表的字段名和对象的属性名自动匹配赋值,如果是基本数据类型和String类型,直接返回
1、FlowerMapper.xml文件的配置如下:
<?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="cn.jingpengchong.pojo.Flower">
<!-- 查询数据总条数的方法 -->
<select id="selOne" resultType="String">
select name from flower where id = 1
</select>
</mapper>
2、测试类文件Test.java如下:
package cn.jingpengchong.test;
import java.io.IOException;
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;
public class Test {
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
//查询结果为一个变量或对象
String name = session.selectOne("cn.jingpengchong.pojo.Flower.selOne");
System.out.println(name);
session.close();
}
}
运行结果如下:
三、selectMap():
将查询到的结果作为map的value,并指定实体类的一个属性作为key与之关联
1、FlowerMapper.xml文件的配置如下:
<?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="cn.jingpengchong.pojo.Flower">
<!-- 查询数据总条数的方法 -->
<select id="selMap" resultType="cn.jingpengchong.pojo.Flower">
select * from flower
</select>
</mapper>
2、测试类文件Test.java如下:
package cn.jingpengchong.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class Test {
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
//查询结果为Map集合,设置的第二个参数为key,查到的结果为value
Map<Object, Object> map = session.selectMap("cn.jingpengchong.pojo.Flower.selMap", "name");
System.out.println(map);
session.close();
}
}
运行结果如下:
{矮牵牛=Flower [id=1, name=矮牵牛, price=2.5, production=南美阿根廷], 菊花=Flower [id=5, name=菊花, price=2.0, production=亚洲中国], 半枝莲=Flower [id=3, name=半枝莲, price=4.3, production=巴西], 百日草=Flower [id=2, name=百日草, price=5.0, production=墨西哥], 樱花=Flower [id=4, name=樱花, price=5.5, production=亚洲日本]}
增加、删除和修改数据:
增加、删除和修改数据的方法分别是update()、delete()和insert(),在FlowerMapper.xml文件中所对应的标签分别是<insert>、<delete>、<update>,这些标签与<select>不同,它们没有resultType属性;
增删改方法的返回值是int,对于增删改等操作,返回的都是受影响的行数,由于其都是修改表数据的,因此不一定用哪种方法和标签,它们可以混用;
在查询操作中的操作都是“factory.openSession();”,其实openSession()是有参数的,如果不传参则默认是false不自动提交事务,如果传入true,则是自动提交事务;
对于增删改等操作,如果要操作多条数据,并且这些操作需要同步(要么都成功、要么都失败),那么此时就需要设置不自动提交事务,从所有操作中捕获Exception,如果出现了异常则执行事务回滚“session.rollback()”,如果没有异常则提交事务“session.commit()”。
update()、delete()和insert():
这三个方法都是修改表中的数据的,返回值类型也相同,所以增删改用哪种方法都能生效,但是开发中还是要一一对应,不要混用!
例:为了适应市场需求,花店要将矮牵牛涨价1.5,同时将百日草降价1.5。
1、FlowerMapper.xml文件的配置如下:
<?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="cn.jingpengchong.pojo.Flower">
<!-- 此处用<update>、<insert>或<delete>标签都行 -->
<update id="update" parameterType="map">
update flower set price = price + #{price} where name = #{name}
</update>
</mapper>
2、测试类文件Test.java如下:
package cn.jingpengchong.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class Test {
public static void main(String[] args) throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
Map<String,Object> mmp = new HashMap<String,Object>();
mmp.put("name", "矮牵牛");
mmp.put("price", 1.5);
//此处用update()、insert()或delete()方法都行
try {
int index = session.update("cn.jingpengchong.pojo.Flower.update",mmp);
mmp.put("name", "百日草");
mmp.put("price", -1.5);
index = session.update("cn.jingpengchong.pojo.Flower.update",mmp);
} catch (Exception e) {
session.rollback();
e.printStackTrace();
}
session.commit();
session.close();
}
}
执行后表的数据如下:
说明:
<mapper>的标签属性namespace介绍: 尽量写包名+操作的实体类名,以区分不同表的操作和避免方法名重复。
<select>的重要标签属性介绍:
- id:指定方法名;
- resultType:指定返回值类型,基本数据类型和String等类型可以直接写其类型名,自定义类类型需要写“包名+类名”,对于返回值是List的情况,resultType表示的是List当中存放的每个数据的类型。
- parameterType:指定参数类型。
修改数据的方法都可以传递参数:
上面方法的参数列表的第二个都是Object类型,该位置来传参;
FlowerMapper.xml文件中的<select><delete><update>等标签是可以指定参数的,如果该操作需要接收参数,那么可以使用标签属性parameterType来表明该方法需要参数,同时为其指定相应的参数类型,该标签属性同时起到了下转型的作用,因为传入的参数都是Object类型的;
FlowerMapper.xml文件中<select><delete><update>等标签中可以用下面的方式获取传入的参数:
- #{任意内容}:用于获取基本数据类型或对象;
- #{属性名}/${属性名}:用于获取参数对象的指定属性的值;
- #{list集合[下标]}/${list集合[下标]}:用于获取List集合指定下标的值;
- #{map集合的key}/${map集合的key}:用于获取map中指定key的value。
由于上面的方法只能传入一个参数,所以如果要传入多个参数时可以考虑将其放入list或map集合中,例:
<select id="selMap" resultType="cn.jingpengchong.pojo.Flower" parameterType="java.util.HashMap">
select * from flower where id = #{id} and name = #{name}
</select>
Map<String,Object> mmp = new HashMap<String,Object>();
mmp.put("id", 1);
mmp.put("name", "矮牵牛");
Flower flower = session.selectOne("cn.jingpengchong.pojo.Flower.selMap",mmp);
System.out.println(flower);
结果如下:
#{} 和 ${} 的区别:
1、#{} :里面可以写任意的内容来获取传入的参数对象,并且 SQL 使用?占位符的形式插入到SQL语句,如下:
2、${} :里面只能写参数对象的属性名、List集合[下标]和map集合的key,并且其接收的参数不是以占位符?的形式插入到SQL语句,而是把里面的内容作为字符串与SQL语句拼接,如下: