Mybatis相当于是增强版的JDBC,因为JDBC的开发步骤超过3步了,所以将这些步骤封装起来提高开发效率。
【注意】Mybatis配置文件中不区分大小写
0. 准备工作 新建com.aaron.domain包,其中每一个类对应了数据库的一张表,类的属性与数据表的数据类型要严格一致。
新建com.aaron.dao包,其中为每一个数据表创建一个dao接口,取名规范为【表名+Dao】。
注意dao接口中不要有重载函数
1. 创建mapper文件 在dao包中,为每一个dao接口创建一个同名的xml文件,比如(StudentDao.xml),将一下配置语句粘贴进去(这些配置文件在mybatis官方文档中可找到)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?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 ="org.mybatis.example.BlogMapper" > <select id ="selectBlog" resultType ="Blog" > select * from Blog where id = #{id} </select > </mapper >
【获取全限定名称的快捷方法】
2. 创建主配置文件 当前模块的根目录下(与com同级)创建resources文件夹,在其中创建mybatis.xml文件
创建resources文件夹的方法:
先创建一个与com同级的叫resources的package,然后打开project structure
将下列内容复制进去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <?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" /> <dataSource type ="POOLED" > <property name ="driver" value ="${driver}" /> <property name ="url" value ="${url}" /> <property name ="username" value ="${username}" /> <property name ="password" value ="${password}" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="org/mybatis/example/BlogMapper.xml" /> 或者<package name ="org.mybatis.dao" > </mappers > </configuration >
3. 通过mybatis的SqlSession对象执行sql语句 3.1 查询语句 1 2 3 4 5 6 7 8 9 10 11 12 InputStream in = Resources.getResourceAsStream("mybatis.xml" );SqlSessionFactory factory = new SqlSessionFactoryBuilder ().build(in);SqlSession sqlSession = factory.openSession();String sqlId = "com.aaron.dao.Student.getAllStudents" ;List<Student> studentList = sqlSession.selectList(sqlId); sqlSession.close();
【注意】每次操作数据库都要创建一个新的sqlSession对象,且sqlSession对象不是线程安全的,因此最好在方法内将sqlSession作为局部变量声明并使用然后关闭,即在方法内部通过factory.openSession()获取到sqlSession并执行完sql语句后在方法内将其close掉。这样就能保证它的使用是线程安全的。
【条件查询】
先加一个mapper
1 2 3 <select id ="findAllUser" resultType ="com.aaron.domain.user_info" > select * from mydata where username = #{username} </select >
条件查询代码
1 2 3 4 5 6 7 InputStream in = Resources.getResourceAsStream("mybatis.xml" );SqlSessionFactory factory = new SqlSessionFactoryBuilder ().build(in);SqlSession sqlSession = factory.openSession(); String sqlId = "com.aaron.dao.StudentDao.findAllStudent" ;user_info user = sqlSession.selectOne(sqlId, new user_info (100 ,"aaron" ,123 ,11 )); sqlSession.close();
3.2 更新语句 先去配置文件里把mapper加上
1 2 3 <insert id ="insertStudent" > insert into mydata values(#{id}, #{username}, #{password}, #{score}) </insert >
然后修改一下代码
1 2 3 4 5 6 7 8 9 InputStream in = Resources.getResourceAsStream("mybatis.xml" );SqlSessionFactory factory = new SqlSessionFactoryBuilder ().build(in);SqlSession sqlSession = factory.openSession(); String sqlId = "com.aaron.dao.StudentDao.insertStudent" ; int result = sqlSession.insert(sqlId, new user_info (2 ,"lisa" ,123 ,20 )); sqlSession.commit(); sqlSession.close();
4. 配置日志 开启日志后,每次对数据库进行操作都会把操作细节信息打印到控制台上。
将下列语句加入到mybatis主配置文件的configuration标签内
1 2 3 <settings > <setting name ="logImpl" value ="STDOUT_LOGGING" /> </settings >
5. 包装成工具类 上面用mybatis访问数据库的语句中存在一些重复代码,我们可以将它们进一步封装来简化调用操作。
首先创建与dao和domain平级的包utils,里面新建MyBatisUtils类,然后包装工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class MyBatisUtils { static SqlSessionFactory factory = null ; static { InputStream in = null ; try { in = Resources.getResourceAsStream("mybatis.xml" ); } catch (IOException e) { e.printStackTrace(); } factory = new SqlSessionFactoryBuilder ().build(in); } public static SqlSession getSqlSession () { SqlSession sqlSession = null ; if (factory != null ){ sqlSession = factory.openSession(); } return sqlSession; } }
这样之前的getAllUserInfo代码就可简化成
1 2 3 4 5 6 SqlSession sqlSession = MyBatisUtils.getSqlSession();String sqlId = "com.aaron.dao.user_infoDao.getAllUserInfo" ;List<user_info> user_infoList = sqlSession.selectList(sqlId); sqlSession.close();
6. idea设置文件默认模板 不需要每次创建mybatis主配置文件和mapper文件时都去官方文档中copy一份,第一次配置时顺带把模板配置好就一劳永逸了。
之后就可直接new出模板文件了
7. 再简化 包装了MyBatis工具类后,我们的操作已经非常简便了
1 2 3 4 5 6 SqlSession sqlSession = MyBatisUtils.getSqlSession();String sqlId = "com.aaron.dao.user_infoDao.getAllUserInfo" ;List<user_info> user_infoList = sqlSession.selectList(sqlId); sqlSession.close();
其实sqlId是可以通过反射拿到的,MyBatis有函数帮我们实现了这一点,所以上面这个方法可以修改成
1 2 3 SqlSession sqlSession = MyBatisUtils.getSqlSession();user_infoDao dao = sqlSession.getMapper(user_infoDao.class);List<user_info> user_infoList = dao.findAllUser();
就相当于我们提供user_infoDao这个接口,MyBatis帮我们创建了一个同名的实现类,实现了user_infoDao接口中所有的函数。
对数据表修改的例子(要手动commit)
1 2 3 4 SqlSession sqlSession = MyBatisUtils.getSqlSession();user_infoDao dao = sqlSession.getMapper(user_infoDao.class);int re = dao.addUser(new user_info (22 ,"tesla" ,123 ,80 ));sqlSession.commit();
8. 动态sql 可根据条件拼接sql语句(主要是拼接where后的部分),使用动态sql的接口方法传入参数必须为【对象类型】。
8.1 if 1 2 3 4 5 6 7 8 9 10 11 <select id ="findAllUser" resultType ="com.aaron.domain.user_info" > select * from mydata where <if test =" username!=null and username!='' " > username = #{username} </if > <if test ="score > 0" > or score > #{score} </if > </select >
上面语句中,如果username条件不过,语句会报错,因为拼接后的字符串相当于select * from mydata where or score > #{score}
,where可以解决这个问题
8.2 where 解决上面的问题,用where将if括住
1 2 3 4 5 6 7 8 9 10 11 12 <select id ="findAllUser" resultType ="com.aaron.domain.user_info" > select * from mydata <where > <if test =" username!=null and username!='' " > username = #{username} </if > <if test ="score > 0" > or score > #{score} </if > </where > </select >
这下如果username判断为false也不会报错了,因为where会自动将拼接后无效的语句删除,本例加了where标签后,即使username和score同时判断为false也不会报错,where会将最后拼接的语句修正为select * from mydata
其他还有foreach用于in关键字等,用到再查。
错误处理 在pom.xml中,build标签内插入如下代码
1 2 3 4 5 6 7 8 <resources > <resource > <directory > src/main/java</directory > <includes > <include > **/*.xml</include > </includes > </resource > </resources >
然后右键,maven,reload project即可。