1. 为什么需要学习mybatis
原生的jdbc
public static void main(String[] args) throws Exception {
// 1.导入jar,注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象
String url = "jdbc:mysql://127.0.0.1:3306/db_stu";
Connection conn = DriverManager.getConnection(url, "root", "root");
// 3.获取执行SQL语句
Statement stat = conn.createStatement();
// 拼写SQL语句
String sql = "select * from sort";
// 4.调用执行者对象方法,执行SQL语句获取结果集
// 返回的是ResultSet接口的实现类对象,实现类在mysql驱动中
ResultSet rs = stat.executeQuery(sql);
// System.out.println(rs);//com.mysql.jdbc.JDBC4ResultSet@18cef0a
// 5.处理结果集
// ResultSet接口的方法 boolean next() 有结果集true,没有结果集返回false
while (rs.next()) {
// 获取每列的数据,使用的是ResultSet接口的方法getXXX
int sid = rs.getInt("sid");// 相当于rs.getInt(1);这个方法有弊端
String sname = rs.getString("sname");
double sprice = rs.getDouble("sprice");
String sdesc = rs.getString("sdesc");
System.out.println(sid+"\t"+sname+"\t"+sprice+"\t"+sdesc);
}
// 6.关闭资源
rs.close();
stat.close();
conn.close();
}
原生jdbc的弊端
1.重复代码重复写,代码冗余,开发低
2.sql硬编码,耦合到java代码不便于维护
3.resultset结果集需要手动映射,开发效率极低
4.手动释放资源
dbutils
QueryRunner runner = new QueryRunner();
String sql = "INSERT into orders values(?,?,?,?,?,?,?)";
Object[] params = new Object[{order.getId(),order.getUid(),order.getAid(),
order.getOcount(),order.getOtime(),order.getOstate(),order.getMoney()}];
int update = runner.update(JDBCUtils.getConn(), sql, params);
弊端
1.每次都需要首先sql语句和创建对象,代码冗余,开发效率慢
2.sql硬编码,耦合到java代码不便于维护
3.需要手动释放资源
mybatis官方介绍
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
2.mybatis是什么
1.orm(Object-relational mapping对象实体映射)介绍
相信大家都清楚,我们所有的操作都是我们的实体属性都是和数据库中的表的字段想对应的,那么怎么把数据库中的字段映射到我们的Java实体中来呢?这就需要用到orm,但是前面我们都是使用的jdbc或者dbutils工具,都显得比较冗余,这是我们的orm的框架都开始浮出水面,但是市面上这样的框架比较多,那么我们如何选择呢
2.框架的选择
目前市面上主要是mybatis和Hibernate,那么选择哪一个呢
mybatis | Hibernate |
---|---|
简单,轻量级,利用第三方工具可自动生成sql | 相对复杂,学习成本高,自动生成sql |
使用SQL, SQL可能依赖于数据库,但一般项目更换数据库的概率不大 | 使用独立于数据库的HQL,不依赖数据库 |
由结果集映射到Java对象,可做到与表结构无关 | Hibernate将Java对象映射到数据库表 |
在MyBatis中使用存储过程非常容易 | 在Hibernate中使用存储过程有点困难 |
不仅仅只有一些的区别,在sql方面,mybatis使用的是xml文档来管理,大大的降低了耦合性,并且mybatis是半自动化的sql,可扩展性更强。Hibernate则是全自动化的sql,我们对于简单的sql不需要我们去手写,其内部自动生成,并且采用的是select (*) 我们页无法进行优化…
从这些种种比较来看,mybatis更有利于我们学习,并且还拥有mybatis-plus为我们自动生成简单的sql语句
3.mybatis入门案例
1.所需jar依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- mysql的驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
2.mybatis-config.xml配置
<?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="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///db_stu"/>
<property name="username" value="root"/>
<property name="password" value="admin123"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 映射文件配置,resource表示类路径位置,url表示绝对位置 -->
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
了解部分
// 参数意义
public Configuration() {
typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
typeAliasRegistry.registerAlias("LRU", LruCache.class);
typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);
typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);
typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
languageRegistry.register(RawLanguageDriver.class);
}
3.映射文件配置
<?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">
<!--sql语句的拼写-->
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
4.使用xml构建 SqlSessionFactory
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取一个session会话(获取一个跟数据库的连接)
SqlSession session = sqlSessionFactory.openSession();
//mybatis生成的代理对象
mapperProxy = session.getMapper(IUserMapper.class);
User user = new User();
user.setUsername("admin");
user.setPassword("123");
user.setEmail("123@163.com");
int i = mapperProxy.saveUser(user);
System.out.println(i);
// 提交
session.commit();
// 关闭
session.close();
扩展.不使用xml构建 SqlSessionFactory
DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
本质上使用xml构建中包含了不适用xml构建的这种
映射文件的注意点
对应的xml文件应该要放到resources下
namespace:命名空间,这里指的是对应的接口的全限定类名
方法的id,唯一,是对应的接口中的方法名称,这里不用全限定名
parameterType:传入参数类型,全限定类名
resultType:返回结果类型,需要全限定类名
4.mybatis核心配置(configuration)文件讲解
properties(属性)
<!-- 加载外部的数据库连接信息,利于修改连接信息 -->
<properties resource="db.properties"></properties>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${pwd}"/>
</dataSource>
settings(设置)
<settings>
<!-- 指定日志类型-->
<setting name="logImpl" value="LOG4J"/>
<!-- 自动开启驼峰命名,即下划线换成驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
typeAliases(类型别名)
<!-- 设置类型别名 -->
<typeAliases>
<!-- 指明使用该包下的全限定名是可直接使用类名-->
<package name="com.qfedu.bean"/>
</typeAliases>
typeHandlers(类型处理器)
mybatis默认能够自动处理的类型
objectFactory(对象工厂)// 很少使用
plugins(插件)
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用最多的就是分页插件 -->
<property name="param1" value="value1"/>
</plugin>
</plugins>
mappers(映射器)*
<mappers>
<!-- 使用较广的两种方式 -->
<package name="org.mybatis.builder"/>
<!-- resource 是指相对位置-->
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
</mappers>
扩展
如果你一定要把xml放在对应的java代码中需要加上插件,否则无法编译进
<build>
<resources>
<!--指定xml文件位置-->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
5.映射文件配置
1.insert和update自增主键的获取
<!-- public int saveStudent(Student student);-->
<insert id="saveStudent" parameterType="student" useGeneratedKeys="true" keyProperty="stuId">
insert into tb_stu (stu_Id,stu_pwd)values(#{stuAccount},#{stuPwd})
</insert>
值得注意的是上述方式在mysql中可以,但是在oracle中并不可行
<insert id="saveCourse" parameterType="course" >
<selectKey keyProperty="stuId" resultType="string" order="BEFORE">
SELECT UUID()
</selectKey>
insert into tb_stu (stu_id,stu_name)values(#{stuId},#{stuName}
)
</insert>
2.当参数为多个参数时如何获取
// 因为多个参数时在mybatis中是以map方式存储。其中key为param(1,2,3...),其value为具体的值,
public int saveStu(@Param("stuId") String stuId,@Param("stuPwd") String stuPwd);
<insert id="saveStudent3">
insert into tb_stu (stu_ID,stu_pwd)values(#{stuId},#{stuPwd})
</insert>
3.sql片段
<!-- 定义sql片段,通常用于sql片段 -->
<sql id="insertSql">
tb_stu (stu_account,stu_pwd,create_date)
</sql>
<!--public int saveStudent2(String stuAccount,String stuPwd);-->
<insert id="saveStudent2">
insert into
<!-- 引用sql片段 -->
<include refid="insertSql"/>
values(#{param1},#{param2}
,#{param3})
</insert>