接上一篇 mybatis学习笔记(一):第一个 Mybatis 例子,Mybatis 的基本用法
修改 StudentMapper.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">
<!-- namespace 是名称空间,理论上可以随便写,但必须保证唯一 -->
<mapper namespace="studentNamespace">
<!--
resultMap 标签:映射实体与表的关系;
当实体类中的属性名 和 表中的字段名 不一样的时候,<resultMap> 标签表示的映射关系必须要写;
但是如果 实体类中的属性名 和 表中的字段名 完全一样的时候,<resultMap> 标签可以省略不写;
id:为实体与表的映射 取一个任意的唯一编号;
type:实体的全路径名;
注意:
映射实体类与表的关系时,此处并没有指定表的名字,
是因为下面的 insert 语句中指出了要操作的表的名字;
-->
<resultMap id="studentMap" type="com.mybatis.demo.Student">
<!--
id 标签:映射主键属性;
property:表示实体类中的属性;
column:表示表中的主键;
-->
<id property="id" column="id"/>
<!--
result 标签:映射非主键属性;
property:表示实体类中的属性;
column:表示表中的字段;
-->
<result property="name" column="name"/>
<result property="sal" column="sal"/>
</resultMap>
<!--
insert 标签:表示标签中要写的是插入 sql 语句;
id:为插入 sql 语句取一个任意唯一的编号;
parameterType:表示 dao 中调用执行此 SQL 语句时传入的参数类型;如果是类的话,必须使用全路径名;
如果 SQL 语句不需要接收参数,可以不写 parameterType 属性;
在 sql 语句中用占位符取值 (#{id}, #{name}, #{sal}),实际上是调用 Student 对象的 getter 方法取值;
Student 对象是 dao 中调用此 SQL 语句时传入的;
-->
<insert id="add" parameterType="com.mybatis.demo.Student">
insert into students(id, name, sal) values (#{id}, #{name}, #{sal})
</insert>
<!--
select 标签:根据 id 查询单个学生;
resultType:表示 dao 中调用执行此 SQL 语句的方法返回的类型;
resultMap:表示将查询出来的记录,根据 id 为 studentMap 的 <resultMap> 标签中的映射关系,自动封装到对应的实体类中;
当实体类中的属性名 和 表中的字段名 不一样的时候,必须要写这个属性,而且 <resultMap> 表示的映射关系也必须要写;
但是如果 实体类中的属性名 和 表中的字段名 完全一样的时候,这个属性可以省略,并且 <resultMap> 这个标签也可以省略;
注意:如果参数不是一个实体类,只是一个普通变量,比如 int、double、String 等,
占位符中的变量理论上可以随便写,即 #{id} 写成 #{xxxyyy} 也可以;
但是建议写成和方法的形参一样,便于阅读;
-->
<select id="findById" parameterType="int" resultType="com.mybatis.demo.Student" resultMap="studentMap">
select * from students where id = #{id}
</select>
<!--
select 标签:查询所有学生;
resultType:表示 dao 中调用执行此 SQL 语句的方法返回的类型;
理论上应该返回 List 集合的类型,但这里只需要写 list 集合中的 元素类型即可;
-->
<select id="findAll" resultType="com.mybatis.demo.Student">
select * from students
</select>
<!--
update 标签:表示标签中要写的是修改 sql 语句;
-->
<update id="update" parameterType="com.mybatis.demo.Student">
update students set name=#{name},sal=#{sal} where id=#{id}
</update>
<!--
delete 标签:表示标签中要写的是删除 sql 语句;
-->
<delete id="delete" parameterType="com.mybatis.demo.Student">
delete from students where id=#{id}
</delete>
<!--
注意:insert、update、delete 标签只是一个模板,在操作数据库时,是以 SQL 语句为核心的;
即在做 增、删、改 时,insert、update、delete 标签可通用;
但是,做查询操作时,只能用 select 标签;
建议做什么操作用什么标签;
即下面将 delete 语句写在 insert 标签中的做法也是可以的。
-->
<insert id="delete2" parameterType="com.mybatis.demo.Student">
delete from students where id=#{id}
</insert>
</mapper>
修改 StudentDao.java 测试文件为:
package com.mybatis.demo;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* 持久层:测试 增、删、改、查
*/
public class StudentDao {
/**
* 增加学生
*/
public void add(Student student) throws Exception{
// 获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSession();
try {
/**
* 执行 insert 操作;
* insert 的 sql 语句是从 StudentMapper.xml 映射文件中读取的;
* 参数为:名称空间.insert标签的id;
* 即 执行 insert 操作的 sql 语句是从 id 为 add 的 <insert/> 标签中读取的;
*/
int num = sqlSession.insert("studentNamespace.add", student);
System.out.println("本次操作影响了 " + num + "行");
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback(); // 回滚事务
}finally {
sqlSession.commit(); // 提交事务
MybatisUtils.closeSqlSession(); // 关闭
}
}
/**
* 根据 id 查询单个学生
*/
public Student findById(int id) throws Exception{
// 获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSession();
try {
/**
* 执行 selectOne 操作:查询一条数据
*/
return sqlSession.selectOne("studentNamespace.findById", id);
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback(); // 回滚事务
throw e;
}finally {
sqlSession.commit(); // 提交事务
MybatisUtils.closeSqlSession(); // 关闭
}
}
/**
* 查询所有学生(查询操作可以不在事务的环境下执行)
*/
public List<Student> findAll() throws Exception{
// 获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSession();
try {
/**
* 执行 selectList 操作:查询批量数据
*/
return sqlSession.selectList("studentNamespace.findAll");
}catch (Exception e){
e.printStackTrace();
throw e;
}finally {
MybatisUtils.closeSqlSession(); // 关闭
}
}
/**
* 修改学生
*/
public void update(Student student) throws Exception{
// 获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSession();
try {
/**
* 执行 update 操作:更新数据
*/
int num = sqlSession.update("studentNamespace.update", student);
System.out.println("本次操作影响了 " + num + "行");
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback(); // 回滚事务
}finally {
sqlSession.commit(); // 提交事务
MybatisUtils.closeSqlSession(); // 关闭
}
}
/**
* 删除学生
*/
public void delete(Student student) throws Exception{
// 获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSession();
try {
/**
* 执行 delete 操作:删除数据
*/
int num = sqlSession.delete("studentNamespace.delete", student);
System.out.println("本次操作影响了 " + num + "行");
}catch (Exception e){
e.printStackTrace();
sqlSession.rollback(); // 回滚事务
}finally {
sqlSession.commit(); // 提交事务
MybatisUtils.closeSqlSession(); // 关闭
}
}
/**
* 测试
*/
public static void main(String[] args) throws Exception{
StudentDao dao = new StudentDao();
// 增加数据
// dao.add(new Student(1, "哈哈", 7000D));
// dao.add(new Student(2, "嘿嘿", 8000D));
// dao.add(new Student(3, "呵呵", 9000D));
// dao.add(new Student(4, "嘻嘻", 8800D));
// 根据 id 查询单个学生
// Student student = dao.findById(3);
// System.out.println(student);
// 查询所有学生
// List<Student> all = dao.findAll();
// for (Student student : all)
// System.out.println(student);
// 更新数据
// Student student = dao.findById(2);
// student.setName("张三");
// dao.update(student);
// 删除数据
Student student = dao.findById(2);
dao.delete(student);
}
}