MyBatis动态sql以及主配置文件中的内容
Mybatis中传统Dao开发以及使用动态代理优化开发
一、JDBC编程
1. 使用JDBC编程的回顾
public void findStudent() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//注册mysql驱动
Class.forName("com.mysql.jdbc.Driver");
//连接数据的基本信息url ,username,password
String url = "jdbc:mysql://localhost:3306/springdb";
String username = "root";
String password = "123456";
//创建连接对象
conn = DriverManager.getConnection(url, username, password);
//保存查询结果
List<Student> stuList = new ArrayList<>();
//创建Statement, 用来执行sql语句
stmt = conn.createStatement();
//执行查询,创建记录集,
rs = stmt.executeQuery("select *from student");
while (rs.next()) {
Student stu = new Student();
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
//从数据库取出数据转为Student对象,封装到List集合
stuList.add(stu);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭资源
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用JDBC的缺陷
- 代码比较多,开发效率低
- 需要关注Connection ,Statement, ResultSet对象创建和销毁
- 对ResultSet查询的结果,需要自己封装为List
- 重复的代码比较多些
- 业务代码和数据库的操作混在一起
二、MyBatis框架
1. 概述
MyBatis框架:MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。
2. MyBatis解决的主要问题
减轻使用JDBC的复杂性,不用编写重复的创建Connetion , Statement ; 不用编写关闭资源代码。直接使用java对象,表示结果数据。让开发者专注SQL的处理。其他分心的工作由MyBatis代劳。
MyBatis可以完成:
-
注册数据库的驱动,例如
Class.forName(“com.mysql.jdbc.Driver”)
-
创建JDBC中必须使用的
Connection,Statement,ResultSet
对象 -
从xml中获取sql,并执行sql语句,把ResultSet结果转换java对象
List<Student> list = new ArrayLsit<>(); ResultSet rs = state.executeQuery(“select * from student”); while(rs.next){ Student student = new Student(); student.setName(rs.getString(“name”)); student.setAge(rs.getInt(“age”)); list.add(student); }
4.关闭资源ResultSet.close() , Statement.close() , Conenection.close()
三、入门案例
1. 使用MyBatis准备
下载mybatis
https://github.com/mybatis/mybatis-3/releases
2. 搭建MyBatis开发环境
(1)创建mysql数据库和表
数据库名 mybatis;表名 student
(2)创建maven工程
脚手架:
(3)加入maven坐标
pom.xml 加入 maven坐标和插件
<?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.lht</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.complier.source>1.8</maven.complier.source>
<maven.complier.target>1.8</maven.complier.target>
</properties>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</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>
(4)编写Student实体类
创建包com.lht.domain,包中创建Student类
package com.lht.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 +
'}';
}
}
(5)编写Dao接口StudentDao
创建com.lht.dao包,创建StudentDao接口
package com.lht.dao;
import com.lht.domain.Student;
import java.util.List;
//接口操作student类
public interface StudentDao {
//查询student表的所有数据
List<Student> selectStudents();
}
(6)编写Dao接口Mapper映射文件StudentDao.xml
要求:
1.在dao包中创建我呢见StudentDao.xml。
2.要StudentDao.xml文件名和接口StudentDao一样,区分大小写的一样。
<?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.lht.dao.StudentDao">
<!--
select:表示查询操作
id:要执行的sql语法的唯一标识,mybatis会使用这个id的值来占到要执行的sql语句
可以自定义,但是要求使用接口中的额方法名称。
resultType:标识结果类型的,是sql语句执行后得到ResultSet,遍历这个ResultSet得到java对象的类型。
值是类型的全限定名称。
-->
<select id="selectStudents" resultType="com.lht.domain.Student">
select * from student
</select>
</mapper>
<!--
sql映射文件:写sql语句的,mybatis会执行这些sql
1.指定约束文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3-mapper.dtd是约束文件的名称,扩展名是dtd的。
2.约束文件作用:限制,检查在当前文件中出现的标签,属性必须符合mybatis的要求
3.mapper是当前文件的跟标签,这时必须的。
namespace:命名空间,唯一值标表示,可以是自定义的字符串。
要求使用dao接口的全限定名称。
4.在当前文件中,可以使用特定的标签,表示数据库的特定操作
<select>:表示执行操作,select语句
<update>:表示更新数据库的操作,就是在<update>标签中,写的是update的sql语句
<insert>:表示插入,执行insert语句
<delete>:表示删除,执行delete语句
-->
(7)创建MyBatis主配置文件
项目src/main 下创建resources目录,设置resources目录为resources root
创建主配置文件:名称为mybatis.xml
说明:主配置文件名称是自定义,内容如下:
<?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>
<!--
环境配置:数据库的连接信息
default:必须和某个environment的id值一样
告诉mybatis使用哪个数据库的连接信息,也就是访问哪个数据库。
-->
<environments default="mysql">
<!--environment:一个数据库信息的配置,环境
id:一个唯一值,自定义,标识环境的名称
-->
<environment id="mysql">
<!--
transactionManager:mybatis的事务类型
type:JDBC(表示使用jdbc的Connection对象的commit,rollback做事务处理)
-->
<transactionManager type="JDBC"/>
<!--
dataSource:表示数据源,连接数据库的
type:表示数据源的类型,POOLED表示使用连接池
-->
<dataSource type="POOLED">
<!--
driver,user,username,password是固定的
-->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<!--访问数据库的用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--sql mapper(sql映射文件)的位置-->
<mappers>
<!--
一个mapper标签指定一个文件的位置,从类路径开始的路径信息。
target/classes(类路径)
-->
<mapper resource="com/lht/dao/StudentDao.xml"/>
</mappers>
</configuration>
(8)创建测试类MyApp
src/test/java/com/lht/ 创建MyApp.java文件
package com.lht;
import com.lht.domain.Student;
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;
import java.util.List;
public class MyApp {
public static void main(String[] args) throws IOException {
//访问mybatis读取student数据
//1.定义mybatis主配置文件的名称,从类路径的根开始(target/classes)
String config = "mybatis.xml";
//2.读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
//3.创建了SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//5.获取SqlSession对象,从SqlSessionFactory中获取SqlSession
SqlSession sqlSession = factory.openSession();
//6.指定要执行的sql语句的标识,sql映射文件中的namespace + "." + 标签的id值
String sqlId = "com.lht.dao.StudentDao" + "." + "selectStudents";
//7.执行sql语句,通过sqlId找到语句
List<Student> studentList = sqlSession.selectList(sqlId);
//8.输出结果
for(Student stu : studentList){
System.out.println("查询的学生="+stu);
}
//9.关闭SqlSession对象
sqlSession.close();
}
}
(9)配置日志功能
mybatis.xml文件加入日志配置,可以在控制台输出执行的sql语句和参数
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
四、基本的CRUD
1. insert
(1)StudentDao接口中增加方法
public int insertStudent(Student student)
(2)StudentDao.xml加入sql语句
<insert id="insertStudent">
insert into student(id,name,email,age) values(#{id},#{name},#{email},#{age})</insert>
(3)增加测试方法
package com.lht;
import com.lht.domain.Student;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class TestMyBatis {
//测试方法,测试功能
@Test
public void testInsert() throws IOException {
//访问mybatis读取student数据
//1.定义mybatis主配置文件的名称,从类路径的根开始(target/classes)
String config = "mybatis.xml";
//2.读取这个config表示的文件
InputStream in = Resources.getResourceAsStream(config);
//3.创建了SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//4.创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
//5.获取SqlSession对象,从SqlSessionFactory中获取SqlSession
SqlSession sqlSession = factory.openSession();
//6.指定要执行的sql语句的标识,sql映射文件中的namespace + "." + 标签的id值
String sqlId = "com.lht.dao.StudentDao.insertStudent";
//7.执行sql语句,通过sqlId找到语句
Student student = new Student();
student.setId(1003);
student.setName("张飞");
student.setEmail("zhangfei@163.com");
student.setAge(20);
int nums = sqlSession.insert(sqlId,student);
//mybatis默认不是自动提交事务的,所以insert,update,delete后要手工提交事务
sqlSession.commit();
//8.输出结果
System.out.println("执行insert的结果=" + nums);
//9.关闭SqlSession对象
sqlSession.close();
}
}
2. update
(1)StudentDao接口中增加方法
public int updateStudent(Student student);
(2)StudentDao.xml增加sql语句
<update id="updateStudent">
update student set age = #{age} where id=#{id}
</update>
(3)增加测试方法
package com.lht;
import com.lht.domain.Student;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class TestMyBatis {
@Test
public void testUpdate() throws IOException {
String config = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(config);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
Student student = new Student();
student.setId(1004);//要修改的id
student.setAge(20); //要修改的年龄值
//执行更新
int row = sqlSession.update("com.lht.dao.StudentDao.updateStudent",student);
sqlSession.commit();
System.out.println("修改记录的行数:" + row);
sqlSession.close();
}
}
3. delete
(1)StudentDao接口中增加方法
public int deleteStudent(int id);
(2)StudentDao.xml增加sql语句
<delete id="deleteStudent">
delete from student where id=#{studentId}
</delete>
(3)增加测试方法
package com.lht;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class TestMyBatis {
@Test
public void testDelete() throws IOException {
String config = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(config);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
SqlSession sqlSession = factory.openSession();
int id = 1001;
int rows = sqlSession.delete("com.lht.do.StudentDao.deleteStudent",id);
sqlSession.commit();
System.out.println("修改记录的行数:" + rows);
sqlSession.close();
}
}