Mybatis框架第一讲(Mybatis介绍、JDBC操作数据库存在的问题、Mybatis的执行原理、Mybatis入门案例、 log4j日志文件、JUnit说明)

    技术2024-10-16  3

    1 Mybatis介绍

    Mybatis是Apache下的一个开源的免费的半自动化的ORM框架,前身名叫IBatis

    优势:简化了对数据库的操作,让程序员专注于对sql的编写,不再将大量的时间放在业务逻辑上 不用mybatis时的模糊查询:

    //模糊查询时,条件的不同会有不同的业务,此处的业务代码会非常的繁琐,可以使用Mybatis中的动态sql处理 String sql = "select * from t_user limit ?,?"; if(user0!=null) { if(user0.getUname()!=null) { sql = "select * from t_user where uname like concat('%',?,'%') limit ?,?"; ps = conn.prepareStatement(sql); ps.setString(1, user0.getUname()); ps.setInt(2, pageCount*(pageIndex-1)); ps.setInt(3, pageCount); } }else { ps = conn.prepareStatement(sql); ps.setInt(1, pageCount*(pageIndex-1)); ps.setInt(2, pageCount); }

    ORM:持久化,例如:数据的存储等 半自动化:程序员可以自己编写对应的sql

    问题:随着社会的发展及医疗等等的提升,现在社会人口的老龄化日趋严重、消费的方式等等的多样化,每个人对应的数据量也就越来越多,对应的需求方式也就更加的多样化。

    对比Hibernate框架,全自动的ORM框架,它的sql是自动生成的,程序员不能自己控制

    面试题:Hibernate和Mybatis的区别—框架选型的时候为什么要选Mybatis?

    2 JDBC操作数据库存在的问题:

    问题1:在使用JDBC操作时,需要频繁的链接和关闭数据库? 方案:使用数据库连接池进行管理 c3p0、druid等

    硬编码和软编码的区别:

    int a = 1; int b = 2; if(a == 2){}//如果用到的是常量值--硬编码 if(a == b){}//使用的两个变量的值都是可变的---软编码

    问题2:存在大量的硬编码,如果sql存在问题,那就需要修改sql,只要修改了Java的代码,那就需要重新编译。 方案:将所有的sql语句放在配置文件中(xml)

    问题3:结果集处理存在大量的重复性工作,不利于后期的维护 方案:指定映射规则,将查询的结果集与实体类中的属性进行映射

    问题4:条件的不同,会带来不同的业务需求,不利于后期的维护 方案:使用动态sql

    面试题:Mybatis的实现原理 利用反射及xml解析实现

    3 Mybatis的执行原理

    面试题:简单描述下Mybatis的执行流程 回答:mybatsi是一个半自动化的ORM框架,通过SqlMapConfig.xml文件配置数据源和映射文件等,然后通过SqlSessionFactory对象创建SqlSession对象,执行sql语句,处理结果集

    4 Mybatis入门案例

    步骤:

    1、导入jar包 mybatis.jar mysql-connector-java.jar log4j.jar

    2、创建配置文件 配置数据源、加载映射文件

    3、三层结构 对应要实现的业务

    4、创建映射文件 具体要实现的功能对应的sql语句 Dao层接口IuserMapper.java代码

    package cn.yunhe.dao; import java.util.List; import cn.yunhe.beans.User; /** * 重写:在继承或实现的过程中,方法名一样、参数列表一致、返回值类型一样、子类修饰符权限要大于或等于父类中的权限 */ public interface IUserMapper { /** * 查询用户列表 * @return */ List<User> queryUsers(); /** * 查询指定用户的信息 * @param uid * @return */ User queryUserById(int uid); }

    配置文件SqlMapConfig.xml代码

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration SYSTEM "http://mybatis.org/dtd/mybatis-3-config.dtd" PUBLIC "-//mybatis.org//DTD Config 3.0//EN"> -<configuration> <!-- 配置环境 --> -<environments default="development"> -<environment id="development"> <!-- 配置事务管理方式:使用JDBC的默认事务管理 --> <transactionManager type="JDBC"/> <!-- 配置数据源 --> -<dataSource type="POOLED"> <property value="com.mysql.jdbc.Driver" name="driver"/> <property value="jdbc:mysql:///shop" name="url"/> <property value="root" name="username"/> <property value="77777777" name="password"/> </dataSource> </environment> </environments> <!-- 加载映射文件 1、如果有多个映射文件就对应多个mapper标签 2、使用package批量加载(后期说) --> -<mappers> <mapper resource="./userMapper.xml"/> </mappers> </configuration>

    映射文件userMapper.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:命名空间,作为该映射文件的唯一标识后期会有多个接口对应不同的映射文件,那么不同的映射文件之间可能会需要互相调用里面的功能 --> -<mapper namespace="test"> <!-- id:作为唯一标识 parameterType:指定参数的类型,基本数据类型都支持,可以直接用 resultType:指定返回值的类型-包名+类名注意点:sql语句的结尾不能有分号 #{val} 占位符,参数名可以任意写,建议和要传递的参数名保持一致 --> pe="cn.yunhe.beans.User" id="queryUsers">select uid,uname,upwd,phone,address,hireDate from t_user </select> <!-- 查询指定ID的用户信息 --> <select resultType="cn.yunhe.beans.User" id="queryUserById" parameterType="int">select uid,uname,upwd,phone,address,hireDate from t_user where uid=#{uid} </select> </mapper>

    测试类代码 selectOne和selectList的区别: ​ selectOne是查询单条语句使用的,selectList用于查询多条语句,会自动识别返回的数据条数。 ​ 可以使用selectList接收selectOne的结果,但是不能使用selectOne去接收selectList的结果

    package cn.yunhe.test; import java.io.IOException; import java.io.InputStream; import java.util.List; 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 org.junit.Test; import cn.yunhe.beans.User; public class IUserMapperTest { @Test public void testQueryUsers() throws IOException { //1、自动从资源文件的根目录下进行查找 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //2、创建SqlSessionFactory对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //3、创建SqlSession对象 SqlSession sqlSession = factory.openSession(); //执行对应的功能 List<User> userList = sqlSession.selectList("test.queryUsers"); System.out.println(userList); //4、关闭sqlSession对象 sqlSession.close(); inputStream.close(); } @Test public void testQueryUserById() throws IOException { //1、自动从资源文件的根目录下进行查找 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //2、创建SqlSessionFactory对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //3、创建SqlSession对象 SqlSession sqlSession = factory.openSession(); //执行功能 User user = sqlSession.selectOne("test.queryUserById", 1); System.out.println(user); //4、关闭sqlSession对象 sqlSession.close(); inputStream.close(); } }

    5 log4j日志文件

    使用方法: 1 导入jar包 2编辑配置文件 log4j配置文件 log4j.properties

    # debug<info<warn<error<fatal log4j.rootLogger=debug,apdConsole,apdFile #改成debug,执行程序后,可以在控制台输出当前的sql语句和参数,以及结果,方便调试 log4j.appender.apdConsole=org.apache.log4j.ConsoleAppender log4j.appender.apdConsole.layout=org.apache.log4j.PatternLayout log4j.appender.apdConsole.layout.ConversionPattern=%r [%t] [%p] - %c -%l -%m%n # ConsoleAppender\u4EE3\u8868\u8F93\u51FA\u5230\u63A7\u5236\u53F0\uFF0CFileAppender\u4EE3\u8868\u8F93\u51FA\u5230\u6587\u4EF6 log4j.appender.apdFile=org.apache.log4j.FileAppender # \u65E5\u5FD7\u6587\u4EF6\u7684\u4F4D\u7F6E log4j.appender.apdFile.File=e://iLearning.log # PatternLayout\u4EE3\u8868\u7528\u6307\u5B9A\u7684Pattern\uFF08\u683C\u5F0F\uFF09\u8F93\u51FA\u65E5\u5FD7 log4j.appender.apdFile.layout=org.apache.log4j.PatternLayout # %m\u8F93\u51FA\u4EE3\u7801\u4E2D\u6307\u5B9A\u7684\u4FE1\u606F\uFF0C\u5982logger.error(message)\u4E2D\u7684message # %M\u8F93\u51FA\u4EE3\u7801\u4E2D\u7684\u65B9\u6CD5\u540D # %n\u4EE3\u8868\u8F93\u51FA\u4E00\u4E2A\u6362\u884C\u7B26 # %d\u8F93\u51FA\u65E5\u5FD7\u65F6\u95F4\u70B9\u7684\u65E5\u671F\u6216\u65F6\u95F4\uFF0C\u9ED8\u8BA4\u683C\u5F0F\u4E3AISO8601\uFF0C\u4E5F\u53EF\u4EE5\u5728\u5176\u540E\u6307\u5B9A\u683C\u5F0F\uFF0C\u6BD4\u5982\uFF1A%d{HH:mm:ss,SSS} # %l\u8F93\u51FA\u65E5\u5FD7\u4E8B\u4EF6\u7684\u53D1\u751F\u4F4D\u7F6E\uFF0C\u5305\u62EC\u7C7B\u76EE\u540D\u3001\u53D1\u751F\u7684\u7EBF\u7A0B\uFF0C\u4EE5\u53CA\u5728\u4EE3\u7801\u4E2D\u7684\u884C\u6570\u3002\u4E3E\u4F8B\uFF1ATestlog4.main(TestLog4.java:10) log4j.appender.apdFile.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss:SSS}][%l-%M] -%m%n

    6 JUnit说明

    JUnit:单元测试,可以单独运行指定的方法,不需要通过主函数,通常用于测试某个功能模块 使用:将JUnit的jar包添加到项目中 1、下载JUnit的jar包放到lib目录中右键关联到项目中 2、在项目中右键添加jar包,找到JUnit选择JUnit4添加到项目中即可 注意:方法不能静态的、方法不能有参数

    //@Before修饰的方法,会在所有@Test方法执行前执行 @Before public void before() throws IOException { //1、自动从资源文件的根目录下进行查找 inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //2、创建SqlSessionFactory对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); //3、创建SqlSession对象 sqlSession = factory.openSession(); } //@After修饰的方法会在所有@Test方法执行完后执行 @After public void close() throws IOException { //关闭连接 sqlSession.close(); inputStream.close(); }
    Processed: 0.034, SQL: 9