MyBatis框架入门第一篇
什么是MyBtis框架?MyBatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
为什么要学习MyBatis框架?
- 使用传统JDBC访问数据库
- 使用JDBC访问数据库有重复的代码(例如注册驱动、获取连接、获取传输器、释放资源等)
- JDBC自身没有连接池,需要频繁的创建链接和关闭链接,效率低
- SQL语句是写在程序中的,一旦修改SQL,需要对程序重新编译
- 对查询SQL语句返回的结果集对象,需要手动去处理,有时会特别麻烦
- 使用MyBatis框架访问数据库
- MyBatis对JDBC进行了封装,简化了之前重复的代码
- MyBatis自身支持连接池(也可以配置其他的连接池),因此可以提高程序的效率
- MyBatis是将SQL语句卸载Mapper语句中,MyBtis框架会帮我们处理,将结果集对象转换成java对象
创建库db1create database if not exists db10 charset utf8;选择db1use db1在db1库中创建student表 CREATE TABLE `student` ( `id` varchar(20) NOT NULL DEFAULT '', `name` varchar(20) NOT NULL DEFAULT '', `birth` varchar(20) NOT NULL DEFAULT '', `sex` varchar(10) NOT NULL DEFAULT '', PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;在student表中插入若干条数据INSERT INTO `student` VALUES ('01', '赵雷', '1990-01-01', '男');INSERT INTO `student` VALUES ('02', '钱电', '1990-12-21', '男');INSERT INTO `student` VALUES ('03', '孙风', '1990-05-20', '男');INSERT INTO `student` VALUES ('04', '李云', '1990-08-06', '男');INSERT INTO `student` VALUES ('05', '周梅', '1991-12-01', '女');INSERT INTO `student` VALUES ('06', '吴兰', '1992-03-01', '女');INSERT INTO `student` VALUES ('07', '郑竹', '1989-07-01', '女');INSERT INTO `student` VALUES ('08', '王菊', '1990-01-20', '女');
创建maven工程,导入所需要的jar包
- 选中Maven,直接点击Next即可
![de1753999bef51262783c38da31eb8af.png](https://img-blog.csdnimg.cn/img_convert/de1753999bef51262783c38da31eb8af.png)
- 依次填写groupid和artifactid后点击next即可
输入项目名称MyBatis,点击Next即可
这样就创建好了一个名称为Mybatis的maven项目,结构如下图:
在pom.xml文件中导入所需要的的jar包
org.mybatis mybatis 3.1.1 mysql mysql-connector-java 5.1.47 log4j log4j 1.2.16 org.projectlombok lombok 1.18.8
添加mybatis-config.xml文件(核心配置文件)
在resources文件包下创建db.properties文件
在resources文件包下创建mybatis-config.xml文件
<?xml version="1.0" encoding="UTF-8"?>/span> PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <properties resource="db.properties">properties> <environments default="develop"> <environment id="develop"> <transactionManager type="JDBC">transactionManager> <dataSource type="POOLED" > <property name="driver" value="${database.driver}">property> <property name="url" value="${database.url}">property> <property name="username" value="${database.username}">property> <property name="password" value="${database.password}">property> dataSource> environment> environments> <mappers> <mapper resource="mapper/StudentMapper.xml">mapper> mappers> configuration>
创建Student实体类,并提供对应的get,set,toString方法,可以使用lombok注解代替
package com.cn.pojo;import lombok.Data;@Datapublic class Student { private String id; private String name; private String birth; private String sex; public Student() { } public Student(String id, String name, String birth, String sex) { this.id = id; this.name = name; this.birth = birth; this.sex = sex; }}
创建StudentMapper接口类,并提供getStudentById方法
package com.cn.mapper;import com.cn.pojo.Student;public interface StudentMapper { public Student getStudentById(String id);}
创建StudentMapper.xml文件(实体类的映射文件)
<?xml version="1.0" encoding="utf-8" ?>/span> "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.cn.mapper.StudentMapper"> <select id="getStudentById" parameterType="String" resultType="com.cn.pojo.Student"> SELECT * FROM Student where id = #{id}; select>mapper>
编写测试类,并测试
package com.cn.utils;import com.cn.mapper.StudentMapper;import com.cn.pojo.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.Reader;public class Test1 { public static void main(String[] args) throws IOException { //1.读取mybatis的核心配置文件(mybatis-config.xml) Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); //2.通过配置信息获取一个SqlSessionFactory工厂对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader); //3.通过工厂获取一个SqlSession对象 SqlSession sqlSession = factory.openSession(); //4.通过namespace+id找到要执行的sql语句并执行sql语句 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); Student student = mapper.getStudentById("01"); //5.输出结果 System.out.println(student); }}
结果输出为:
代码优化
编写MyBatisUtil工具类
测试类中的代码如果CRUD方法很多的话就会造成重复代码(读取配置文件、获取SqlSessionFactory对象)冗余,因此我们需要把代码优化封装成一个工具类,代码如下:package com.cn.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.Reader;import java.sql.Connection;public class MyBatisUtils { private static ThreadLocal threadLocal = new ThreadLocal(); private static SqlSessionFactory sqlSessionFactory; //静态块加载配置文件 static { try { Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } catch (IOException e) { e.printStackTrace(); } } //禁止外界通过new方法创建 private MyBatisUtils(){}; /** * 获取sqlSession * @return */ public static SqlSession getSqlSession(){ SqlSession sqlSession = threadLocal.get(); if(sqlSession == null){ //设置事务自动提交 sqlSession = sqlSessionFactory.openSession(true); threadLocal.set(sqlSession); } return sqlSession; } /** * 关闭sqlSession */ public static void closeSqlSession(){ SqlSession sqlSession = threadLocal.get(); if (sqlSession != null){ sqlSession.close(); threadLocal.remove(); } } /** * 测试 * @param args */ public static void main(String[] args) { Connection connection = MyBatisUtils.getSqlSession().getConnection(); System.out.println(connection); }}
输出结果为:
测试类的代码可以修改为:
package com.cn.utils;import com.cn.mapper.StudentMapper;import org.apache.ibatis.session.SqlSession;import java.io.IOException;public class Test1 { public static void main(String[] args) throws IOException { SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); System.out.println(studentMapper.getStudentById("01")); }}
MyBatis工作流程
通过Resources读取MyBatis的核心配置文件(mybatis-config.xml)
通过新建SqlSessionFactoryBuilder对象创建SqlSessionFactory对象
通过工厂对象获取一个 SqlSession对象
事务默认开启
通过SqlSession读取映射文件中的操作id,从而执行Sql语句
提交事务
关闭资源
完成CRUD操作
增加学生
编辑StudentMapper接口类,并提供add方法
void add(Student student);
编辑StudentMapper.xml文件,提供增加学生的Sql语句
<insert id="add" parameterType="com.cn.pojo.Student"> INSERT INTO Student(id,name,birth,sex) VALUES (#{id}, #{name}, #{birth}, #{sex}); insert>
编写测试类,并测试
@Test public void add(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student student = new Student("09","小明","1990-05-20","男"); studentMapper.add(student); }
查看数据库,成功插入一条数据
因为之前在工具类MyBatisUtil中设置了事务自动提交,所以这里我们在修改了数据库信息后不需要在提交事务。
删除学生
编辑StudentMapper接口类,并提供deleteById方法
void deleteById(String id);
编辑StudentMapper.xml文件,提供删除学生的Sql语句
<delete id="deleteById" parameterType="string"> DELETE FROM Student WHERE id = #{id}; delete>
编写测试类,并测试
@Test public void deleteById(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); studentMapper.deleteById("09"); }
查看数据库,成功删除一条数据
修改学生
编辑StudentMapper接口类,并提供update方法
void update(Student student);
编辑StudentMapper.xml文件,提供修改学生的Sql语句
<update id="update" parameterType="com.cn.pojo.Student"> UPDATE Student SET name=#{name}, birth=#{birth}, sex=#{sex} where id=#{id};update
编写测试类,并测试
@Test public void update(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); Student student = mapper.getStudentById("08"); student.setName("小强"); student.setBirth("1991-02-20"); student.setSex("男"); mapper.update(student); }
查看数据库,成功修改id为08的一条数据
<delete id="deleteById" parameterType="string"> DELETE from Student where id = #{id}; delete>
<update id="update" parameterType="com.cn.pojo.Student"> UPDATE Student SET name=#{name}, birth=#{birth}, sex=#{sex} where id=#{id};update>
${}占位符
${}占位符的作用就是如果传递过来的不是参数值,而是一个Sql片段,目的就是要拼接在Sql语句中
查询所有学生的姓名和生日
编辑StudentMapper接口类,并提供find方法
List find(Map map);
编辑StudentMapper.xml文件,提供查询学生指定信息的Sql语句
<select id="find" resultType="com.cn.pojo.Student"> SELECT ${cols} FROM Student select>
编写测试类,并测试
@Test public void find(){ SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Map map = new HashMap(); map.put("cols","name,birth"); List list = studentMapper.find1(map); for (Student s : list) { System.out.println(s); } }
输出结果为:
需要注意的是,在传递${}占位符对应的值时,需要将值传入到Map集合中。
动态Sql语句 if,where元素if元素用于对某一字段进行判断,也就是根据判断传过来的参数是否为空,从而决定是否将该片段包含在Sql语句中
where元素用于对包含在内的Sql语句进行检索,需要是剔除多余的连接词(例如and或者or),并且在需要时添加where语句
编辑StudentMapper接口类,并提供findAllByBirth方法
List findAllByBirth(Map map);
编辑StudentMapper.xml文件,提供查询学生的Sql语句
<select id="findAllByBirth" resultType="com.cn.pojo.Student"> SELECT * from Student <where> <if test="min != null" > and birth ]]> #{min} if> <if test="max != null" > and birth #{max} if> where> select>
被
这个标记所包含的内容将表示为纯文本,比如
表示文本内容
“
在xml文档中,"
、"
>"
、"&"
等字符是不能直接存入的,否则xml语法检查时会
报错
,如果想在xml中使用这些符号,必须将其转义为实体, 上面使用的是标记符号,也可以使用转义字符如"<",">","&",这样才能保存到xml文档中
编写测试类,并测试
@Test public void findAllByBirth(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); HashMap map = new HashMap(); map.put("min","1990-01-01"); map.put("max","1990-12-31"); Listlist = mapper.findAllByBirth(map); for (Student student : list) { System.out.println(student); } }
输出结果为:
编辑StudentMapper接口类,并提供update1方法
void update1(Student student);
编辑StudentMapper.xml文件,提供编辑学生的Sql语句
<update id="update1" parameterType="com.cn.pojo.Student"> UPDATE student <set> <if test="name != null"> name=#{name}, if> <if test="birth != null"> birth=#{birth}, if> <if test="sex != null"> sex=#{sex}, if> set> where id = #{id}; update>
编写测试类,并测试
@Test public void update1(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); Student student = mapper.getStudentById("11"); student.setName("红红"); student.setBirth("1993-02-20"); student.setSex("男"); mapper.update1(student); }
查看数据库,成功修改id为11的一条数据
foreach元素用于迭代传递给Sql语句中的array、list、map元素
编辑StudentMapper接口类,并提供deleteByIds方法
void deleteByIds(Integer[] ids);
编辑StudentMapper.xml文件,提供删除学生的Sql语句
<delete id="deleteByIds" parameterType="string"> DELETE from Student where id in <foreach collection="array" open="(" separator="," close=")" item="id" > #{id} foreach> delete>
编写测试类,并测试
@Test public void deleteByIds(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); Integer[] ids = {01,03,05,07}; mapper.deleteByIds(ids); }
查看数据库,成功修改id为01,03,05, 07的数据
到目前为止MyBatis框架入门第一篇就已经讲解完毕,下一篇文章我们开始对MyBatis框架的缓存机制和逆向工程进行入门讲解。