什么是MyBatis?
答:它是一个持久层框架
说的太简单了吗?那让我们来看一下官方的文档描述:
MyBatis有什么作用呢?
1.持久层的零实现
2.可以自动将数据封装到对象里面不需要手工编写映射的关系
MyBatis基于XML配置文件的配置流程图:
配置流程步骤及代码:
1.导入包:
2.创建总的配置文件
注意,要在设置中设置两个规则文件,第一个是用于总配置文件中,第二个是用于配置映射文件中,在配置中遇到PUBLIC ID
可在MyBatis的官方文档中找到
PUBLIC ID
总配置文件编写代码:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "mybatis-3-config.dtd" > <configuration> <!--environments标签用于配置数据库连接信息,可以配置多个数据库的连接信息 default属性:环境集里面可以配置多个数据库连接环境,但是必须要指定默认的环境,指定的是环境environment标签的ID --> <environments default="sms"> <!-- environment环境标签 ,用于配置一个数据库连接的信息--> <environment id="sms"> <!-- 指定使用的事务类型 --> <!-- 观点:任何框架的内置属性都可以在代码里面找到 --> <!-- 大部分配置文件的解释类都是在configuration、builder这个两个单词或者单词的缩写的包里面 在org.apache.ibatis.session.Configuration配置类里面找到对应的代码查看 JDBC : 使用JDBC的事务处理 MANAGER: 不需要事务处理 --> <transactionManager type="JDBC"></transactionManager> <!-- dataSource标签:作用,配置数据库连续信息 type:配置数据源的类型 JNDI :使用JNDI数据源,就是在web服务器配置数据源,让程序调用 POOLED : 使用默认内置的连接池 UNPOOLED:使用直连数据库,不需要连接池 --> <dataSource type="POOLED"> <!-- 配置四要素 --> <property name="driver" value="org.gjt.mm.mysql.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/sms" /> <property name="username" value="root" /> <property name="password" value="123456" /> </dataSource> </environment> </environments>
创建一个MyBatisUtils工具类,用来加载总配置文件
package cn.gzsxt.utils; import java.io.IOException; import java.io.Reader; 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 MybatisUtils { //注意事项,我们正常情况下,一个项目只有一个数据源。因为如果出现多个数据源,数据库的连接就可能来自于不同的数据源 //这样可以导致数据库连接无法同步,从而导致事务失效! //要求:对外只开放一个会话工厂。 public static final SqlSessionFactory SSF=createSSF(); //声明一个线程变量 private static final ThreadLocal<SqlSession> THREAD_LOCAL=new ThreadLocal<>(); //1.获得会话工厂 private static SqlSessionFactory createSSF(){ try { //读取配置文件 Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); //创建会话工厂构建类对象 SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); //构建会话工厂 return builder.build(reader); } catch (IOException e) { e.printStackTrace(); } return null; } //2.获得会话 //需求:同访问的一条线程,获得的会话是相同的 //答:可以通过线程变量实现(ThreadLoad) //ThreadLoad对象的作用,就是可以实现,同一条线程共享一个变量。 public static SqlSession getSession(){ //如果线程变量没有对象,我们获得会话对象,并且放在线程变量里面 if (THREAD_LOCAL.get()==null) { SqlSession session = SSF.openSession(); //将对象放在线程变量里面 THREAD_LOCAL.set(session); } //如果已经有该会话。直接返回线程变量的会话对象。 return THREAD_LOCAL.get(); } //使用了线程变量,在关闭会话的时候,需要清除线程变量的对象;。 public static void close(){ if (THREAD_LOCAL.get()!=null) { SqlSession session = THREAD_LOCAL.get(); session.close(); THREAD_LOCAL.remove(); } } public static void main(String[] args) { System.out.println(MybatisUtils.getSession()); System.out.println(MybatisUtils.getSession()); } }
创建实体类
package cn.gzsxt.pojo; import java.io.Serializable; import java.util.Date; public class Student implements Serializable { private static final long serialVersionUID = 1734561915065710177L; private Long studentId;//bigint(20) not null auto_increment comment '学生编号', private String studentName;//varchar(50) null default null comment '姓名', private String studentPwd;//varchar(50) null default null comment '密码', private Integer studentStatus;//int(11) null default null comment '状态', private Date createDate;//datetime null default null comment '创建时间', private String studentAccount;//varchar(50) null default null comment '学生帐号', public Long getStudentId() { return studentId; } public void setStudentId(Long studentId) { this.studentId = studentId; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public String getStudentPwd() { return studentPwd; } public void setStudentPwd(String studentPwd) { this.studentPwd = studentPwd; } public Integer getStudentStatus() { return studentStatus; } public void setStudentStatus(Integer studentStatus) { this.studentStatus = studentStatus; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public String getStudentAccount() { return studentAccount; } public void setStudentAccount(String studentAccount) { this.studentAccount = studentAccount; } }
创建映射文件StudentMapper.xml和操作接口,建议将两者放在同一个包下,方便查找
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd" > <mapper namespace="cn.gzsxt.mapper.StudentMapper"> <!-- 编写插入的SQL语句 id:唯一标识符,必须和映射接口的方法名一一对应。就意味着映射接口的方法不能有重载 --> <insert id="insert"> INSERT INTO tb_student(STUDENT_NAME, STUDENT_PWD, STUDENT_STATUS, CREATE_DATE, STUDENT_ACCOUNT) VALUES (#{studentName}, #{studentPwd}, #{studentStatus}, #{createDate}, #{studentAccount}) </insert> </mapper>
package cn.gzsxt.mapper; import cn.gzsxt.pojo.Student; public interface StudentMapper { /** * 插入记录到学习表 * @param student * @return */ int insert(Student student); }
用总配置文件加载映射文件
<!-- 配置指定加载的映射文件 --> <mappers> <mapper resource="cn/gzsxt/mapper/xml/StudentMapper.xml"/> </mappers>
编写一个测试类测试
package cn.gzsxt.test; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import cn.gzsxt.mapper.StudentMapper; import cn.gzsxt.pojo.Student; import cn.gzsxt.utils.MybatisUtils; public class StudentMapperTest { @Test public void insert(){ //获得会话对象 SqlSession session = MybatisUtils.getSession(); //构建映射接口的动态对象 StudentMapper studentMapper = session.getMapper(StudentMapper.class); //调用插入方法 Student student=new Student(); student.setStudentName("张三1"); int insert = studentMapper.insert(student); //提交 session.commit(); System.out.println(insert); //关闭 MybatisUtils.close(); } }