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();
}