Mybatis入门使用总结

来源:互联网 发布:网络语言暴力论文观点 编辑:程序博客网 时间:2024/05/16 11:42

1.什么是Mybatis

Mybatis原来是apache的一个开源项目ibatis,2010年这个项目由apache softwarefoundation迁移到了google code,并且改名为Mybatis。2013年11月迁移到了github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQLMaps和DataAccess Objects(DAO)。Mybatis实际也是一个orm解决方案之一。

2.mybatis入门程序

使程序与Mybatis可以顺利建立连接作为入门程序。

首先需要导入相关jar包:


工程目录,包括后面的程序:


从上图可以看出还需要编写一下log4j.properties便于我们查看日志。

测试连接的小程序:

/* * 工具类 * */public class MybatisUtil {private static ThreadLocal<SqlSession> threadLocal =new ThreadLocal<SqlSession>();private static SqlSessionFactory sqlSessionFactory;/* * 加载位于src/mybatis.xml配置文件 * */static{try {Reader reader =Resources.getResourceAsReader("mybatis.xml");sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();throw new RuntimeException(e);}}//禁止外部访问private MybatisUtil(){}/* * 获取SqlSession * */public static SqlSession getSqlSession(){//从当前线程中获取sqlSession对象SqlSession sqlSession =threadLocal.get();if(sqlSession ==null){//如果sqlSessionFactory对象不为空情况下,那么获取SqlSession对象。 sqlSession =sqlSessionFactory.openSession();//将sqlSession与当前线程绑定在一起threadLocal.set(sqlSession);}//直接返回sqlSession对象return sqlSession;}/* * 关闭SqlSession与当前线程分离 * */public static void closeSqlSession(){//从当前线程中获取sqlSession对象SqlSession sqlSession =threadLocal.get();if(sqlSession !=null){//关闭sqlSession对象sqlSession.close();//分开当前线程与sqlSession对象的关系,目的是让GC尽早回收threadLocal.remove();}}public static void main(String[] args) {Connection conn =MybatisUtil.getSqlSession().getConnection();System.out.println(conn !=null ?"连接成功":"连接失败");MybatisUtil.closeSqlSession();}}

Mybatis.xml是Mybatis的总配置文件:

<?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><!-- 加载类路径下的属性文件 --><properties resource="db.properties"></properties><!-- 设置类型别名 --><typeAliases><typeAlias type="cn.spy.model.Student" alias="Student"/></typeAliases><environments default="mysql_developer"><!-- mysql环境信息 --><environment id="mysql_developer"><!-- mybatis使用jdbc事务管理方式 --><transactionManager type="jdbc"></transactionManager><!-- mybatis使用连接池方式来获取连接 --><dataSource type="pooled"><!-- 配置与数据库交互的四个必要属性 --><property name="driver" value="${mysql.driver}"/><property name="url" value="${mysql.url}"/><property name="username" value="${mysql.username}"/><property name="password" value="${mysql.password}"/></dataSource></environment></environments><!-- 加载映射文件 --><mappers><mapper resource="cn\spy\model\StudentMapper.xml"/></mappers></configuration>
其实我们完全可以直接Mybatis中数据库必须配置的四个属性的位置,直接配置数据库的驱动,连接,用户名和密码。这样做不便于以后的修改。则直接采用properties文件配置。

db.properties数据库配置文件:

mysql.driver=com.mysql.jdbc.Drivermysql.url=jdbc:mysql://localhost:3306/basicjdbc?characterEncoding=utf-8mysql.username=rootmysql.password=
至于Mybatis.xml中的配置别名和加载Student类的映射配置文件可以暂时忽略,因为此处不用。

运行结果:


阅读上面的代码会发现,其实Mybatis是采用配置文件的形式来配置数据库连接的信息。然后采用Reader的形式去读取配置文件,来获取连接的信息。从而交给SqlSessionFactory来建立连接。第二点就是采用ThreadLocal这么一个类来实现,在我的多线程通信的博文中说过ThreadLocal类主要解决的就是每个线程绑定自己的值,就是用来存储每个线程的私有数据。所以使用ThreadLocal就是把当前线程与SqlSession对象绑定一起了。然后作为工具类实现了一个获取连接和关闭连接的方法,便于后面使用。

3.Mybatis实现CRUD

pojo(Student):

public class Student {private Integer id;private String name;private double sal;public Student(){}public Student(Integer id, String name, double sal) {this.id = id;this.name = name;this.sal = sal;}               getter、setter方法......        @Overridepublic String toString() {return "Student [id=" + id + ", name=" + name + ", sal=" + sal + "]";}}
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"><!-- namespace属性是名称空间,必须唯一 --><mapper namespace="studentNamespace"><!-- resultMap:映射实体与表 type属性:表示实体全路径名id属性:为实体与表的映射取一个唯一的编号--><resultMap type="Student" id="studentMap"><!-- id标签:映射主键属性result标签:映射非主键属性property属性:实体的属性名column属性:表的字段名 --><id property="id" column="id"/><result property="name" column="name"/><result property="sal" column="sal"/></resultMap><!-- insert标签:要书写insert这么一个语句id属性:为insert这么一个sql语句取一个任意唯一的名字parameterType:要执行的dao中的方法的参数,如果是类的话,那么必须使用全路径类。 --><insert id="add" parameterType="Student">insert into students(id,name,sal) values(#{id},#{name},#{sal});</insert><!-- 根据id查询学生类 --><select id="findById" parameterType="int" resultType="Student">select id,name,sal from students where id=#{id};</select><!-- 查询所有的学生类 理论上resultType要写List<Student>但这里只需书写List中的类型即可,即只需书写Student的全路径名--><select id="findAll" resultType="Student">select * from students;</select><!-- 更新学生表记录 --><update id="update" parameterType="Student">update students set name=#{name},sal=#{sal} where id=#{id};</update><!-- 删除学生记录 --><delete id="delete" parameterType="Student">delete from students where id=#{id};</delete></mapper>
解释:Mybatis采用模型对象的映射文件,作为数据库操作语句的对象。使用resultMap这个标签来封装。至于说明都在代码的注释上,如果还有不明白,那么可以看Mybatis文档给出了例子。。

由于Mybatis是一个orm框架,所以必然是作为数据库操作的一个框架。那么对应还需要dao层的代码。

dao接口:

public interface IStudentDao {public void add(Student student) throws Exception;public void delete(Student student) throws Exception;public void update(Student student) throws Exception;public Student selectOneById(int id) throws Exception;public List<Student> selectAll() throws Exception; }

dao实现类:

public class StudentDaoImpl implements IStudentDao{@Overridepublic void add(Student student) throws Exception {// TODO Auto-generated method stubSqlSession sqlSession =null;try{sqlSession =MybatisUtil.getSqlSession();//开启事务//读取StudentMapper.xml映射文件中的SQL语句sqlSession.insert("studentNamespace.add",student);//事务提交sqlSession.commit();}catch(Exception e){e.printStackTrace();//事务回滚sqlSession.rollback();throw e;}finally{MybatisUtil.closeSqlSession();}}@Overridepublic void delete(Student student) throws Exception {SqlSession sqlSession =null;try{sqlSession =MybatisUtil.getSqlSession();//开启事务//读取StudentMapper.xml映射文件中的SQL语句sqlSession.delete("studentNamespace.delete",student);//事务提交sqlSession.commit();}catch(Exception e){e.printStackTrace();//事务回滚sqlSession.rollback();throw e;}finally{MybatisUtil.closeSqlSession();}}@Overridepublic void update(Student student) throws Exception {SqlSession sqlSession =null;try{sqlSession =MybatisUtil.getSqlSession();sqlSession.update("studentNamespace.update",student);sqlSession.commit();}catch(Exception e){e.printStackTrace();//事务回滚sqlSession.rollback();throw e;}finally{MybatisUtil.closeSqlSession();}}@Overridepublic Student selectOneById(int id) throws Exception {SqlSession sqlSession =null;try{sqlSession =MybatisUtil.getSqlSession();Student student =sqlSession.selectOne("studentNamespace.findById", id);sqlSession.commit();return student;}catch(Exception e){e.printStackTrace();//事务回滚sqlSession.rollback();throw e;}finally{MybatisUtil.closeSqlSession();}}@Overridepublic List<Student> selectAll() throws Exception {SqlSession sqlSession =null;try{sqlSession =MybatisUtil.getSqlSession();return sqlSession.selectList("studentNamespace.findAll");}catch(Exception e){e.printStackTrace();//事务回滚sqlSession.rollback();throw e;}finally{MybatisUtil.closeSqlSession();}}}

解释:发现获取连接和释放连接都是采用之前写的例子Mybatis工具类。然后获取到sqlSession对象。通过sqlSession做操作。对于操作方法中第一个参数的解释:名称空间.配置文件操作标签的id。这样就使sqlSession可以找到StudentsMapper对应的sql语句。而从配置文件中也可以大概分析出采用了模板方法模式。虽然crud都是一套固定的标签,然而每一个使用者用到sql语句可能会不同,由于每个人需要的查询不同,并且可以得到需要的不同查询结果。

注意:

在同样的程序中为什么我的程序却跑不起来呢。需要一点配置在Mybatis.xml总配置文件中。

   配置StudentMapper映射,让Mybatis.xml加载:

<!-- 加载映射文件 --><mappers><mapper resource="cn\spy\model\StudentMapper.xml"/></mappers>
细节在入门例子中有配置。

   然而mybatis.xml配置文件中使用别名的配置是为了简化开发,减少写太长的类路径。

4.Mybatis实现分页

pojo类、mybatis.xml等前面例子一样的。主要是StudentMapper.xml、dao实现类的编写。

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"><!-- namespace属性是名称空间,必须唯一 --><mapper namespace="studentNamespace"><!-- resultMap:映射实体与表 type属性:表示实体全路径名id属性:为实体与表的映射取一个唯一的编号--><resultMap type="Student" id="studentMap"><!-- id标签:映射主键属性result标签:映射非主键属性property属性:实体的属性名column属性:表的字段名 --><id property="id" column="id"/><result property="name" column="name"/><result property="sal" column="sal"/></resultMap>       <!-- 分页查询学生记录 -->    <select id="selectByPaging" parameterType="map" resultMap="studentMap">        select id,name,sal from students limit #{pstart},#{psize};    </select></mapper>

dao接口:

public interface IStudentDao {    public List<Student> selectByPaging(int start ,int size) throws Exception;}

dao实现类:

public class StudentDaoImpl implements IStudentDao{      @Override    public List<Student> selectByPaging(int start ,int size) throws Exception {        SqlSession sqlSession =null;        try{            sqlSession =MybatisUtil.getSqlSession();            Map<String,Object> map =new LinkedHashMap<String,Object>();            map.put("pstart", start);            map.put("psize", size);            return sqlSession.selectList("studentNamespace.selectByPaging", map);        }catch(Exception e){            e.printStackTrace();            //事务回滚            sqlSession.rollback();            throw e;        }finally{            MybatisUtil.closeSqlSession();        }    }} 
测试:

public static void main(String[] args) throws Exception {      IStudentDao studentDao =new StudentDaoImpl();              System.out.println("-------------第一页");        List<Student> list1 =studentDao.selectByPaging(0, 4);        for(Student stu:list1){            System.out.println(stu);        }}
结果:


数据库:


解释:Mybatis主要就是使用sql语句进行操作的。而mysql对于分页查询提供了limit关键字,方便了查询。而传入的第几条记录开始和每页显示的记录数,使用map传入。而StudentMapper.xml中使用

parameterType="map" resultMap="studentMap"
来传参和设置返回结果。

5.Mybatis实现有条件分页查询

有条件分页查询,就是使用分页查询,但是使用了条件进行过滤,而我此处玩下模糊查询做为条件。

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"><!-- namespace属性是名称空间,必须唯一 --><mapper namespace="studentNamespace"><!-- resultMap:映射实体与表 type属性:表示实体全路径名id属性:为实体与表的映射取一个唯一的编号--><resultMap type="Student" id="studentMap"><!-- id标签:映射主键属性result标签:映射非主键属性property属性:实体的属性名column属性:表的字段名 --><id property="id" column="id"/><result property="name" column="name"/><result property="sal" column="sal"/></resultMap>       <!-- 有条件分页 -->    <select id="selectByConditionalPaging" parameterType="map" resultMap="studentMap">        select id,name,sal from students where name like #{pname} limit #{pstart},#{psize};    </select></mapper> 
dao接口:

public interface IStudentDao {       public List<Student> selectByConditionalPaging(String name ,int start ,int size) throws Exception;}
dao实现类:

public class StudentDaoImpl implements IStudentDao{      @Override    public List<Student> selectByConditionalPaging(String name, int start,            int size) throws Exception {        SqlSession sqlSession =null;        try{            sqlSession =MybatisUtil.getSqlSession();            Map<String,Object> map =new LinkedHashMap<String,Object>();            map.put("pname", "%"+name+"%");            map.put("pstart", start);            map.put("psize", size);            return sqlSession.selectList("studentNamespace.selectByConditionalPaging", map);        }catch(Exception e){            e.printStackTrace();            //事务回滚            sqlSession.rollback();            throw e;        }finally{            MybatisUtil.closeSqlSession();        }    }}
测试:

public static void main(String[] args) throws Exception {IStudentDao studentDao =new StudentDaoImpl();        System.out.println("-------------第一页");     List<Student> list1 =studentDao.selectByConditionalPaging("魏大勋", 0, 4);     for(Student stu:list1){        System.out.println(stu);     }}
结果:


6.Mybatis工作流程

(1)通过Reader对象读取src目录下的mybatis.xml配置文件(该文本的位置和名字可任意)

(2)通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象

(3)从当前线程中获取SqlSession对象

(4)事务开始,在mybatis中默认

(5)通过SqlSession对象读取StudentMapper.xml映射文件中的操作编号,从而读取sql语句

(6)事务提交,必写

(7)关闭SqlSession对象,并且分开当前线程与SqlSession对象,让GC尽早回收

-----------------------------------------


至于Mybatis的两个配置文件,上面都有注解就不再赘述了。







0 0
原创粉丝点击