Mybatis
一、环境配置
mybatis官方包下载
- 下载jar包请认准官网。在百度搜索进入mybatis官网 (https://blog.mybatis.org/)。
点击Products
- 点击download
- 进入到下载jar包的链接中,该链接中有很多版本。咱们选择3.4.2,该版本在页面的最下端。点击下载zip文件。
下载方式如动图所示:
4. 解压到本地某个目录,之后建立mybatisLibs文件夹,存放开发用的jar包。
共有三个jar包。mybatis包是核心包,log4j是打印日志的包,mysql-connector-java是mysql的驱动包。前两个在刚下载的zip中。第三个在群文件中。
如果官网连不上,就连接https://github.com/mybatis/mybatis-3/releases
创建工程
- 创建工程,在工程中创建Eclipse的mybatisLibrary。
2、创建数据库表:
建表语句如下:
create table student(
id int not null primary key,
school varchar(30) not null,
department varchar(30) not null,
speciality varchar(30) not null,
class_name varchar(30) not null,
name varchar(30) not null,
gender int not null
);
执行数据库文件
在数据库中插入两条数据
3、编写代码:
工程目录如下所示:
包com.edu.tjdz.geng.model下创建Student类:包含7个属性、全部属性的getter/setter方法和toString方法。
package com.edu.tjdz.geng.model;
public class Student {
private int id;
private String school;
private String department;
private String speciality;
private String className;
private String name;
private int gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getSpeciality() {
return speciality;
}
public void setSpeciality(String speciality) {
this.speciality = speciality;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student [id=" + id + ", school=" + school + ", department=" + department + ", speciality=" + speciality
+ ", className=" + className + ", name=" + name + ", gender=" + gender + "]";
}
}
包com.edu.tjdz.geng.test下创建类Test。当前main方法中包括两部分固定的代码,一是读取mybatis配置文件,做数据库的初始化操作,二是获取SqlSession
package com.edu.tjdz.geng.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 {
//1、读取mybatis配置文件,做数据库的初始化操作
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2、获取SqlSession
SqlSession session = sqlSessionFactory.openSession();
}
}
4、编写配置文件
创建配置文件目录(不再放置到src下了),创建log4j.properties文件和mybatis-config.xml文件
编辑log4j.properties内容
下面黑体部分要替换成你自己的包名
log4j.logger.com.edu.tjdz.geng=DEBUG
log4j.rootLogger=ERROR,stdout
log4j.logger.com.edu.tjdz.geng=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
编辑"mybatis-config.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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--1、配置数据源4个属性-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--2、配置Student类到数据库表student之间的映射文件-->
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>
在conf目录下创建StudentMapper.xml文件。该文件用于将实体类Student与数据表student建立映射关系。映射是通过具体的SQL语句与java程序,使得数据库student中的字段和实体类Student中的属性互相赋值。
用符号来表示的话:Student.私有属性值 <====f(SQL+代码) ====>student.表各个字段值
其中 mapper标签的namespace属性是命名空间,值可以是任意,通常为 包名.实体名+Mapper
select标签中的id为这个sql语句的标识,resultType为设置该语句返回的结果装在哪种类型的变量中。SQL语句当中有一个参数需要用#{参数的}的形式,将会会在代码中为这个参数赋上具体的值。
<?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="com.edu.tjdz.geng.StudentMapper">
<select id="selectStudent" resultType="com.edu.tjdz.geng.model.Student">
select * from student where id = #{id}
</select>
</mapper>
5、完善测试类
在main方法中补充调用操作数据库语句。SqlSession对象session的selectOne方法在加上StudentMapper.xml语句中的标签就完成实体类Student与数据表student建立向实体类Student的映射,即属性的复制。
//3、操作数据库
Student stu1 = (Student) session.selectOne("com.edu.tjdz.geng.StudentMapper.selectStudent", 20180101);
System.out.println(stu1);
6、打印输出。
运行Test类的main方法,结果中有一个属性值为null。这是为什么???请思考
解释:这是由于Student类中的属性className和表student中的字段class_name名字没有完全一致导致的(可以观察其他字段和属性是否都一模一样)。
但是,className的命名方式是遵照了命名类的属性的规则—驼峰原则。class_name的命名方式是遵照命名表的字段的规则–下划线连接。各自的名字都符合命名规范。为了解决这种情况,mybaits专门在配置文件中有一个解决方法。如下所示。大家在配置文件中把这一项添加进去,再运行main方法,观察一下结果。
7、小结
mybatis框架的核心原则是ORM。其中O是object,具体指项目中的实体类,例如Student类。R是指关系型数据库,例如student表。M是指二者之间的映射。
接口绑定
在Spring中,我们操作数据库的函数统一封装到了dao层,在dao.impl层中对各个函数进行具体实现,这是开发B/S架构程序的一种经典方法。引入mybatis框架后,依旧采用这种分层方式。略有不同的是,mybatis与dao层的对接方式。下面通过程序说明如何将mybatis与dao层联合起来。
- 项目工程目录:
- 相比上面的程序,新增了一个包dao.
包com.edu.tjdz.geng.dao内包含了一个StudentDao 接口。接口内有增删改查四种方法
package com.edu.tjdz.geng.dao;
import com.edu.tjdz.geng.model.Student;
public interface StudentDao {
public Student selectStudentById(int id);
public void addStudent(Student stu);
public void deleteStudent(int id);
public void updateStudent(Student stu);
}
如下图所示,按照之前spring的思路,可能接下来要写StudentDaoImpl类,在类内部对四个方法进行实现。如果大家仔细读一下daoImpl方法实现,可以发现方法内部通常分为:a、写SQL语句;b、写SQL语句中的参数;c、调用对应方法这三个流程。然而、我们发现SQL语句已经在StudentMapper.xml这个文件写过了。那么剩下的两步就由Mybatis进行形式上的变化或者优化。
3. 接口绑定方法
mybatis中不需要再写daoImpl实现类。而是在配置文件中进行实现。
修改StudentMapper.xml
大家认真对比一下此处和上面的配置文件哪里发生了变化。其实就是mapper的namespace属性值和select的id属性值发生了变化。mapper的namespace属性值变为StudentDao的全限定名。select的id属性值变为StudentDao方法中查找方法的函数名。
也就是说将接口里面的方法和SQL语句绑定。
<?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="com.edu.tjdz.geng.dao.StudentDao">
<select id="selectStudentById" resultType="com.edu.tjdz.geng.model.Student">
select * from student where id = #{id}
</select>
</mapper>
- 修改Test类中main方法
在代码里可以看到,第4步 session.getMapper(StudentDao.class)可以获取到StudentDao对象。
有了它就可以调用数据库操作方法了。
package com.edu.tjdz.geng.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;
import com.edu.tjdz.geng.dao.StudentDao;
import com.edu.tjdz.geng.model.Student;
public class Test {
public static void main(String[] args) throws IOException {
//1、加载配置文件,创建sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2、获取SqlSession
SqlSession session = sqlSessionFactory.openSession();
//3、获取StudentDao对象
StudentDao stuDao = session.getMapper(StudentDao.class);
//4、调用Dao对象的操作数据库的方法
Student stu = stuDao.selectStudentById(20180101);
System.out.println(stu);
//5、释放SqlSession
session.close();
}
}
- 与此类似,可以再添加增加、删除、修改这三个SQL。
修改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">
<mapper namespace="com.edu.tjdz.geng.dao.StudentDao">
<select id="selectStudentById" resultType="com.edu.tjdz.geng.model.Student">
select * from student where id = #{id}
</select>
<insert id="addStudent" parameterType="com.edu.tjdz.geng.model.Student" >
insert into student(id, school, department, speciality, class_name, name, gender)
values(#{id}, #{school}, #{department},#{speciality}, #{className}, #{name}, #{gender})
</insert>
<update id="updateStudent" parameterType="com.edu.tjdz.geng.model.Student">
update student set class_name = #{className} where id = #{id}
</update>
<delete id="deleteStudent">
delete from student where id= #{id}
</delete>
</mapper>
- 在测试类中调用者四个方法*(我已经将四个方法的测试代码注释,大家调用时将注释删掉即可*)
package com.edu.tjdz.geng.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;
import com.edu.tjdz.geng.dao.StudentDao;
import com.edu.tjdz.geng.model.Student;
public class Test {
public static void main(String[] args) throws IOException {
//1、加载配置文件,创建sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2、获取SqlSession
SqlSession session = sqlSessionFactory.openSession();
//3、获取StudentDao对象
StudentDao stuDao = session.getMapper(StudentDao.class);
/*4.1 查询
Student stu = stuDao.selectStudentById(20180101);
System.out.println(stu);*/
/*4.2 增加
Student stu = new Student();
stu.setId(20180103);
stu.setSchool("XXX学院");
stu.setDepartment("XXX系");
stu.setSpeciality("XXX专业");
stu.setClassName("XXX班级");
stu.setName("C");
stu.setGender(0);
stuDao.addStudent(stu);*/
/*4.3 更新
Student stu = new Student();
stu.setId(20180103);
stu.setClassName("XXXXX班");
stuDao.updateStudent(stu);*/
/*4.4 删除
stuDao.deleteStudent(20180103);
*/
//5.提交(增加、删除、更新必须要commit,否则数据库不更新)
session.commit();
//6、释放SqlSession
session.close();
}
}
增加返回值
通常,为了在前台网页中显示用户增加、删除、更新操作是否成功,我们会利用后台向前台发送一些状态码。这些状态码其实就是某些操作数据库函数的返回值。在mybatis中,框架就有自动返回的功能。下面通过案例来说明。
- 修改StudentDao文件函数
为增、删、改添加返回值。返回值类型为int
package com.edu.tjdz.geng.dao;
import com.edu.tjdz.geng.model.Student;
public interface StudentDao {
public Student selectStudentById(int id);
public int addStudent(Student stu);
public int deleteStudent(int id);
public int updateStudent(Student stu);
}
- 修改测试代码,并运行
package com.edu.tjdz.geng.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;
import com.edu.tjdz.geng.dao.StudentDao;
import com.edu.tjdz.geng.model.Student;
public class Test {
public static void main(String[] args) throws IOException {
//1、加载配置文件,创建sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2、获取SqlSession
SqlSession session = sqlSessionFactory.openSession();
//3、获取StudentDao对象
StudentDao stuDao = session.getMapper(StudentDao.class);
/*4.1 查询
Student stu = stuDao.selectStudentById(20180101);
System.out.println(stu);*/
/*4.2 增加*/
Student stu = new Student();
stu.setId(20180104);
stu.setSchool("XXX学院");
stu.setDepartment("XXX系");
stu.setSpeciality("XXX专业");
stu.setClassName("XXX班级");
stu.setName("D");
stu.setGender(0);
int status = stuDao.addStudent(stu);
System.out.println(status);
/*4.3 更新
Student stu = new Student();
stu.setId(20180103);
stu.setClassName("XXXXX班");
int status = stuDao.updateStudent(stu);*/
/*4.4 删除
int status = stuDao.deleteStudent(20180103);
*/
//5.提交(增加、删除、更新必须要commit,否则数据库不更新)
session.commit();
//6、释放SqlSession
session.close();
}
}
- 这个返回值其实是受数据库中受影响的行数。
补充说明:配置dtd文件提示
部分人的Eclipse中可能在mybaits两个配置文件中敲alt+/没有提示,这是由于eclipse中缺少解析对应xml的文件。如果电脑连接网络,eclipse会自动下载用到的dtd文件。如果没有网络就需要手动。下面对如何手动配置进行说明。
1、找到dtd文件。
以压缩文件的方式打开mybatis-3.4.2.jar,dtd文件在mybatis-3.4.2.jar文件下的org/apache/ibatis/builder/xml/目录下。把它提取到某个路径下
2、在eclipse中配置dtd。这里以配置mybatis-3-config.dtd为例说明。
在配置时,key的值是mybaits-config.xml文件中第四行,也是就是图中标蓝的那一行。
二、配置文件说明
mybatis-congfig.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标签以及子标签
在configuration标签中添加子标签。mybatis-congfig.xml中configuration标签的子标签共有9中。
咱们常用到三种。
<?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>
<!--1、开关标签-->
<settings>
<!--1.1、打开数据表下划线到驼峰原则的映射开关-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--2、环境标签,通过defalut属性的值选择内部某一个具体的环境-->
<environments default="development">
<!--2.1、开发环境-->
<environment id="development">
<!--2.1.1、设置事务管理器,选择默认的即可-->
<transactionManager type="JDBC"/>
<!--2.1.2、设置事该环境下的数据源,默认即可-->
<dataSource type="POOLED">
<!--2.1.2.1、设置数据源的四大配置项-->
<property name="driver" value="......"/>
<property name="url" value="......"/>
<property name="username" value="......"/>
<property name="password" value="......"/>
</dataSource>
</environment>
<!--2.2、测试环境-->
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="......"/>
<property name="url" value="......"/>
<property name="username" value="......"/>
<property name="password" value="......"/>
</dataSource>
</environment>
</environments>
<!--3、配置多项mapper,每一个mapper对应一个实体类-->
<mappers>
<!--3.1、resource属性值为mapper.xml文件名,通常命名为:实体类名+Mapper.xml,例如StudentMapper.xml-->
<mapper resource="XXXMapper.xml"/>
</mappers>
</configuration>
XXXMapper.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标签以及子标签
在mapper子标签中配置各种映射元素。
<?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">
<!--1、mapper标签中的namespace属性值为对应的某个实体类的Dao接口的全限定名(包名+接口名) -->
<mapper namespace="com.edu.tjdz.geng.Dao.StudentDao">
<!--1.1 select元素id属性为Dao中对应的函数名,resultType为该函数的返回值类型 -->
<select id="selectStudentById" resultType="com.edu.tjdz.geng.model.Student">
<!--1.1.1 Sql语句中参数通过#{参数名}来设置 -->
select * from student where id = #{id}
</select>
<!--1.2 insert元素id属性为Dao中对应的函数名,parameterType为该函数的返回值类型 -->
<insert id="insertStudent" parameterType="com.edu.tjdz.geng.model.Student">
insert into student(id, school, department, speciality, class_name, name, gender) values(#{id},#{school},#{department}, #{speciality}, #{className}, #{name}, #{gender})
</insert>
<!--1.3 update元素id属性为Dao中对应的函数名,parameterType为该函数的返回值类型-->
<update id="updateStudent" parameterType="com.edu.tjdz.geng.model.Student">
update student set class_name = #{className} where id = #{id}
</update>
<!--1.4 delete元素id属性为Dao中对应的函数名,parameterType为该函数的返回值类型-->
<delete id="deleteStudent">
delete from student where id= #{id}
</delete>
</mapper>