MyBatis基础(1)

来源:互联网 发布:java 树结构实现 编辑:程序博客网 时间:2024/06/06 20:19
MyBatis基础
1. 对原生态jdbc程序中问题的总结
(1)数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁地连接和关闭,造成数据库资源浪费,影响数据库性能
解决方案:使用数据库连接池管理数据库连接
(2)将sql语句硬编码到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护
解决方案:将sql语句配置在xml文件中,即使sql变化,不需要对java代码进行重新编译
(3)向PreparedStatement中设置参数,对占位符位置和设置值,硬编码在java中,不利于系统维护
解决方案:将sql语句及占位符和参数全部配置在xml中
(4)从ResultSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,不利于系统维护
解决方案:将查询结果结果集,自动映射成java对象

2. MyBatis框架
1. 是什么
MyBatis让程序将主要精力放在sql上,通过MyBatis提供的映射方式,自动灵活生成(半自动化,大部分需要编写sql)满足需要的sql语句
MyBatis可以将向PreparedStatement中的输入参数自动进行映射,将查询结果集灵活映射成java对象(输出映射)
2. 框架
(1)SqlMapConfig.xml(MyBatis的全局配置文件)
配置了数据源、事务等MyBatis运行环境
配置映射文件(配置sql语句)
Mapper.xml
(2)SqlSessionFactory(会话工厂),根据配置文件创建工厂
创建SqlSession
(3)SqlSession(会话),是一个面向用户(程序员对接口)
操作数据库(增、删、改、查)
(4)Executor(执行器),是一个接口(基本执行器、缓存执行器)
SqlSession内部通过执行器操作数据库
(5)MappedStatement(底层封装对象)
对数据库存储封装,包括sql语句、输入参数、输出结果类型
输入参数类型:
Java简单类型、HashMap、PoJo自定义类型
输出结果类型:
Java简单类型、HashMap、PoJo自定义类型
3. 开发
(1)导入Jar包
(2)创建log4j.properties文件
(3)创建SqlMapConfig.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>
<!-- 与Spring整合后,下面的配置将被废除 -->
  <environments default="development">
    <environment id="development">
      <!-- 使用JDBC事务管理 ,事务由mybatis控制-->
      <transactionManager type="JDBC"/>
      <!-- 数据库连接池 -->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///mybatis?character"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
  </environments>
</configuration>

4. CRUD操作
(1) 映射文件
在映射文件中配置sql语句
映射文件命名规则:User.xml,使用Mapper代理开发映射文件的名称为:xxxMapper.xml,如UserMapper.xml;ItemsMapper.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">
 <!-- 对sql进行分类化管理,理解sql隔离 -->
<mapper namespace="test">
  <!-- 在映射文件中配置sql语句 -->
  <!-- 配置Sql查询语句 
  id:标示映射文件的sql
  将sql语句封装到mapperedStatement对象中,所以ID也被称为Statement的ID
  parameterType:指定输入参数的类型
  #{} 标示占位符
  #{id}:id表示接收输入的参数,如果输入参数是简单类型,#{}中的参数名可以是任意的
  resultType:指定sql输出结果所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象
  -->
  <select id="findUserById" parameterType="int" resultType="cn.mybatis.entity.User">
  SELECT * FROM USER WHERE id=#{id}
  </select>
</mapper>
(2) 创建实体类
(3) 在SqlMapConfig.xml文件中加载
 <!-- 加载映射文件 -->
  <mappers>
    <mapper resource="config/User.xml"/>
  </mappers>
(4) 测试
(a)根据ID查询用户信息
// 加载MyBatis的配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建会话工厂,传入MyBatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession操作数据库
// 第一个参数:映射文件中Statement的ID,值为:namespace + "." + statement的ID
// 第二个参数:指定和映射文件中所匹配的parameterType类型的参数
User user = sqlSession.selectOne("test.findUserById", 3);
System.out.println(user);
// 释放资源
sqlSession.close();
(b)根据用户名模糊查询
配置文件:
<!-- 根据用户名模糊查询 
  ${}:表示拼接字符串,将接收到的参数的内容拼接到sql中
  ${value}:接收输入参数的内容,如果传入的是简单类型,${}中只能使用value
  -->
  <select id="findUserByName" parameterType="java.lang.String" resultType="cn.mybatis.entity.User">
  SELECT * FROM USER WHERE username LIKE '%${value}%'
  </select>
代码:
SqlSession sqlSession = new SqlSessionFactoryBuilder().
build(Resources.getResourceAsStream("SqlMapConfig.xml")).openSession();
List<User> lists = sqlSession.selectList("test.findUserByName", "xiao"); 
System.out.println(lists);
sqlSession.close();
(c)添加用户
配置文件:
<!-- 添加用户 
  parameterType:指定输入参数类型是POJO类型
  #{}中指定POJO的属性名,接收POJO的属性值,MyBatis是通过OGNL获取对象的属性值
  -->
  <insert id="insertUser" parameterType="cn.mybatis.entity.User">
  insert into user(id,username,password) values(#{id},#{username},#{password})
  </insert>
代码:
SqlSession sqlSession = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("SqlMapConfig.xml")).openSession();
User user = new User();
user.setUsername("mybatis");
user.setPassword("mybatis");
sqlSession.insert("test.insertUser", user);
// 提交事务
sqlSession.commit();
sqlSession.close();
获取主键值:
<!-- 将insert插入数据的主键返回
SELECT LAST_INSERT_ID():mysql函数,得到刚刚insert的记录的主键值,只适用于自增主键
keyProperty:将查询到的主键值设置到keyProperty指定的对象的哪个属性
order:SELECT LAST_INSERT_ID() 执行顺序,相对于insert语句来说的执行顺序
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
<!-- 使用Mysql的UUID()生成主键
执行过程:
首先通过uuid函数得到主键,将主键的值设置到user对象的id属性中,
其次在insert执行时,从user对象中取出ID值
-->
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer">
SELECT uuid()
</selectKey>
(d)删除用户
(e)更新用户

总结:
#{}和${}:
#{}:表示一个占位符
接受输入参数,类型可以是简单类型、pojo、hashmap,如果是简单类型,#{}可以写成value或者其他名称
${}接受pojo对象值,通过OGNL读取对象中的属性值,通过"属性.属性.属性......"的方式获取属性值
${}:表示一个拼接符,会产生sql注入,不建议使用
接受输入参数,类型可以是简单类型、pojo、hashmap,如果是简单类型,${}}只能写成value
${}接受pojo对象值,通过OGNL读取对象中的属性值,通过"属性.属性.属性......"的方式获取属性值

3. MyBatis和Hibernate本质区别和应用场景
hibernate:是一个标准的ORM,不需要写SQL,sql语句自动生成,对sql语句进行优化、修改比较困难
应用场景:
适用于需求变化较少的中小型项目,如:后台管理系统,ERP、CRM、OA
MyBatis:是一个不完全的ORM专注sql本身,需要编写sql,sql优化、修改方便,也可以实现映射(输入映射、输出映射)
应用场景:
适用于需求变化较多的项目,如:互联网项目