1.0 使用 Dao 的实现类,操作数据库
1.0.1 Dao 开发
(0)定义接口StudentDao 及创建接口的映射文件StudentDao .xm
package com.zep.dao;
import com.zep.domain.Student;
import java.util.List;
public interface StudentDao {
List<Student> selectStudents();
int insertStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int id);
}
<?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="com.zep.dao.StudentDao">
<select id="selectStudents" resultType="com.zep.domain.Student">
select * from student order by id;
</select>
<insert id="insertStudent">
insert into student values(#{
id},#{
name},#{
email},#{
age})
</insert>
<update id="updateStudent">
update student set age = #{
age} where id=#{
id}
</update>
<delete id="deleteStudent">
delete from student where id=#{
studentId}
</delete>
</mapper>
(1) 创建 Dao 接口实现类
public class StudentDaoImpl implements StudentDao
(2) 实现接口中 select 方法
@Override
public List<Student> selectStudents() {
// 1.获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.zep.dao.StudentDao.selectStudents";
// 2.执行sql语句,使用SqlSession类的方法
List<Student> students = sqlSession.selectList(sqlId);
/*for (Student student : students) {
System.out.println(student);
}*/
// 3.关闭
sqlSession.close();
return students;
}
测试查询操作:
MyBatisTest 类中创建 StudentDaoImpl 对象
public class TestMybatis {
@Test
public void testSelectStudents() {
StudentDaoImpl dao = new StudentDaoImpl();
List<Student> students = dao.selectStudents();
for (Student student : students) {
System.out.println(student);
}
}
}
(3) 实现接口中 insert 方法
@Override
public int insertStudent(Student student) {
// 1.获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.zep.dao.StudentDao.insertStudent";
// 2.执行sql语句,使用SqlSession类的方法
int nums = sqlSession.insert(sqlId,student);
// 3.提交事务
sqlSession.commit();
// 4.关闭
sqlSession.close();
return nums;
}
测试 insert
@Test
public void testInsertStudent() {
StudentDaoImpl dao = new StudentDaoImpl();
Student student = new Student();
student.setId(1003);
student.setName("zep");
student.setEmail("[email protected]");
student.setAge(22);
int nums = dao.insertStudent(student);
System.out.println("添加对象的数量:" + nums);
}
(4) 实现接口中 update 方法
@Override
public int updateStudent(Student student) {
SqlSession session = MybatisUtils.getSqlSession();
int nums = session.update(
"com.zep.dao.StudentDao.updateStudent",student);
session.commit();
session.close();
return nums;
}
测试 update
@Test
public void testUpdateStudent() {
StudentDaoImpl dao = new StudentDaoImpl();
Student student = new Student();
student.setId(1004);
student.setAge(222);
int nums = dao.updateStudent(student);
System.out.println("使用Dao修改数据:" + nums);
}
(5) 实现接口中 delete 方法
@Override
public int deleteStudent(int id) {
SqlSession session = MybatisUtils.getSqlSession();
int nums = session.delete(
"com.zep.dao.StudentDao.deleteStudent",id);
session.commit();
session.close();
return nums;
}
测试 delete
@Test
public void testDeleteStudent() {
StudentDaoImpl dao = new StudentDaoImpl();
int nums = dao.deleteStudent(1005);
System.out.println("使用Dao删除的数据:" + nums);
}
项目完整代码如下:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zep</groupId>
<artifactId>ch02-mybatis-dao</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Student .java:
package com.zep.domain;
// 推荐和表名一样,容易记忆
public class Student {
// 定义属性,目前要求是 属性名和列名保持一致
private Integer id;
private String name;
private String email;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
mybatis.xml:
扫描二维码关注公众号,回复:
12829925 查看本文章
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--mybatis.xml 文件加入日志配置,可以在控制台输出执行的 sql 语句和参数-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/zep/dao/StudentDao.xml"/>
</mappers>
</configuration>
MybatisUtils .java:
package com.zep.utils;
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 java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory factory = null;
/*静态代码块:执行优先级高于非静态的初始化块,它会在类初始化的时候执行一次,执行完成便销毁*/
//使用 静态块 创建一次 SqlSessionFactory
static {
String config = "mybatis.xml"; //需要和你的项目中的文件名一样
try {
//读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//创建SqlSessionFactory对象,使用SqlSessionFactoryBuilder
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
// 获取SqlSession对象的方法
public static SqlSession getSqlSession() {
SqlSession sqlSession = null;
if (factory != null) {
sqlSession = factory.openSession(); // 非自动提交事务
}
return sqlSession;
}
}
StudentDao .java:
package com.zep.dao;
import com.zep.domain.Student;
import java.util.List;
public interface StudentDao {
List<Student> selectStudents();
int insertStudent(Student student);
int updateStudent(Student student);
int deleteStudent(int id);
}
StudentDao.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="com.zep.dao.StudentDao">
<select id="selectStudents" resultType="com.zep.domain.Student">
select * from student order by id;
</select>
<insert id="insertStudent">
insert into student values(#{id},#{name},#{email},#{age})
</insert>
<update id="updateStudent">
update student set age = #{age} where id=#{id}
</update>
<delete id="deleteStudent">
delete from student where id=#{studentId}
</delete>
</mapper>
StudentDaoImpl .java:
package com.zep.dao.Impl;
import com.zep.dao.StudentDao;
import com.zep.domain.Student;
import com.zep.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudents() {
// 1.获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.zep.dao.StudentDao.selectStudents";
// 2.执行sql语句,使用SqlSession类的方法
List<Student> students = sqlSession.selectList(sqlId);
/*for (Student student : students) {
System.out.println(student);
}*/
// 3.关闭
sqlSession.close();
return students;
}
@Override
public int insertStudent(Student student) {
// 1.获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
String sqlId = "com.zep.dao.StudentDao.insertStudent";
// 2.执行sql语句,使用SqlSession类的方法
int nums = sqlSession.insert(sqlId,student);
// 3.提交事务
sqlSession.commit();
// 4.关闭
sqlSession.close();
return nums;
}
public int updateStudent(Student student) {
SqlSession session = MybatisUtils.getSqlSession();
int nums = session.update(
"com.zep.dao.StudentDao.updateStudent",student);
session.commit();
session.close();
return nums;
}
@Override
public int deleteStudent(int id) {
SqlSession session = MybatisUtils.getSqlSession();
int nums = session.delete(
"com.zep.dao.StudentDao.deleteStudent",id);
session.commit();
session.close();
return nums;
}
}
TestMybatis .java:
package com.zep;
import com.zep.dao.Impl.StudentDaoImpl;
import com.zep.domain.Student;
import org.junit.Test;
import java.util.List;
public class TestMybatis {
@Test
public void testSelectStudents() {
//com.zep.dao.StudentDao
StudentDaoImpl dao = new StudentDaoImpl();
/**
* 调用List<Student> students = dao.selectStudents();
* 1.dao对象,类型是StudentDao,可以获取到它的全限定类名为:com.zep.dao.StudentDao
* 这个全限定名称和StudentDao.xml文件中mapper的namespace的值是一样的
*
* 2.方法名称,selectStudents,这个方法就是StudentDao.xml文件中mapper标签下的子标签中id的值selectStudents
*
* 3.通过dao中方法的返回值也可以确定Mybatis要调用的SqlSession的方法
* 如果返回值是List,调用的是SqlSession.selectList()方法。
* 如果返回值是int,或者是非List的,看mapper文件中的标签是<insert>,<update>
* 就会调用SqlSession的insert(),update()等方法
*
* mybatis的动态代理:mybatis根据dao的方法调用,获取执行sql语句的信息。
* mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建这个类的对象来完成
* SqlSession调用方法,访问数据库。
*/
List<Student> students = dao.selectStudents();
for (Student student : students) {
System.out.println(student);
}
}
@Test
public void testInsertStudent() {
StudentDaoImpl dao = new StudentDaoImpl();
Student student = new Student();
student.setId(1005);
student.setName("zep");
student.setEmail("[email protected]");
student.setAge(22);
int nums = dao.insertStudent(student);
System.out.println("添加对象的数量:" + nums);
}
@Test
public void testUpdateStudent() {
StudentDaoImpl dao = new StudentDaoImpl();
Student student = new Student();
student.setId(1004);
student.setAge(222);
int nums = dao.updateStudent(student);
System.out.println("使用Dao修改数据:" + nums);
}
@Test
public void testDeleteStudent() {
StudentDaoImpl dao = new StudentDaoImpl();
int nums = dao.deleteStudent(1005);
System.out.println("使用Dao删除的数据:" + nums);
}
}
1.0.2 传统 Dao 开发方式的分析
在前面例子中自定义 Dao 接口实现类时发现一个问题:Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper (StudentDao.xml)中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。
所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式。
Mapper 动态代理
方式无需程序员实现 Dao 接口,不需要我们自己编写Dao接口的实现类。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的