1.mybatis简介
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
2>jdbc的一些问题
数据连接创建创建、释放资源频繁造成系统资源浪费
SQL语句在代码中硬编码,代码不易维护,SQL改变后java代码变化较大
使用preparedStatement向占有位符号传参数存在硬编码,sql语句的where条件不一定
对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护
3>mybatis架构(划重点)
mybatis配置:
SqlMapConfig.xml:mybatis的全局配置文件,配置了mybatis的运行环境等信息
mapper.xml:sql映射文件,文件中配置了操作数据库的sql语句,此文件需要在SqlMapConfig.xml中加载
SqlSessionFactory:由mybatis环境信息构造的会话工厂
sqlSession:操作数据库需要通过sqlSession进行
Executor:mybatis底层自定义的执行器,Executor:mybatis接口有两个实现(基本执行器,缓存执行器)
Mapped Statement:框架的一个底层封装对象,包装了mybatis配置信息及sql映射信息,一个sql对应一个Mapped Statement对象
2.搭建mybatis程序
mybatis的代码由github.com管理
下载地址:https://github.com/mybatis/mybatis-3/releases
1>创建java工程,导入mybatis的核心包、依赖包、数据库驱动包
2>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>
<!-- 读取配置文件:properties\typeAliases\environments\mappers标签的顺序不能改变 -->
<properties resource="db.properties"/>
<!-- 配置别名 -->
<typeAliases>
<!-- 扫描整个包路径 -->
<package name="com.imwj.pojo"/>
</typeAliases>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url"
value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- 扫描整个包路径 -->
<package name="com.imwj.mapper"/>
</mappers>
</configuration>
db.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
3>log4j.propeties日志
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4>创建user实体类(实现Serializable :序列化)
public class User implements Serializable {
private Integer id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
5>sql映射文件:UserMapper.xml,UserMapper接口
<?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">
<!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用:直接扫描到指定类(指定resultType类型) -->
<mapper namespace="com.imwj.mapper.UserMapper">
<!-- 根据id查询 -->
<select id="findById" parameterType="Integer" resultType="User">
select * from user where id = #{id}
</select>
<!-- 查询所有用户 -->
<select id="findAll" resultType="User">
select * from user
</select>
<!-- 根据name模糊查询 -->
<select id="findAllByLikeName" parameterType="String" resultType="User">
select * from user where username like "%"#{haha}"%"
</select>
<!-- 添加用户 -->
<insert id="save" parameterType="User">
<!-- 返回自动增长的id -->
<selectKey keyProperty="id" resultType="Integer" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
<!-- 修改用户 -->
<update id="updateById" parameterType="User">
update user
set username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address}
where id = #{id}
</update>
<!-- 删除用户 -->
<delete id="deleteById" parameterType="Integer">
delete from user where id = #{id}
</delete>
</mapper>
public interface UserMapper {
//增
public void save(User user);
//删
public void deleteById(Integer id);
//改
public void updateById(User user);
//查
public User findById(Integer id);
//查所有
public List<User> findAll();
//模糊查询
public List<User> findAllByLikeName(String username);
}
6>将UserMapper.xm添加在SqlMapConfig.xml
<mappers>
<!-- 扫描整个包路径 -->
<package name="com.imwj.mapper"/>
</mappers>
7>测试文件
@Test
/**
* 根据id查询用户
* @throws IOException
*/
public void fun1() throws IOException{
//得到sqlSessionFactory,然后生产session
String resourec = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resourec);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession();
//原方法(不推荐使用):User user = sqlSession.selectOne("namespace名.findById", 1);
//动态代理产生daoImpl类,然后自动调用sql语句并封装参数
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findById(1);
System.out.println(user);
//释放资源,或者commit提交数据
sqlSession.close();
}
小结:
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中
selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常
selectList可以查询一条或多条记录。
3.一些配置参数
1>Mapper接口开发需要遵循以下规范:四条
接口 方法名 == User.xml 中 id 名
返回值类型 与 Mapper.xml文件中返回值类型要一致
方法的入参类型 与Mapper.xml中入参的类型要一致
命名空间 绑定此接口:UserMapper.xml中<mapper namespace="com.imwj.mapper.UserMapper">
2>动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定
3>SqlMapConfig.xml配置文件(划重点)
内容顺序如下:
properties属性:可以引用java属性文件中的配置信息,如:数据库连接信息db.properties
<!-- 读取配置文件 -->
<properties resource="db.properties"/>
typeAliases:类别名
<!-- 配置别名 -->
<typeAliases>
<!--配置单个别名:不推荐 <typeAlias type="com.imwj.pojo.User" alias="User"/> -->
<!-- 扫描整个包路径:自定义别名,还有就是基本类型和包装类型的别名Integer -->
<package name="com.imwj.pojo"/>
</typeAliases>
mappers:映射器
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
<mappers>
<!--导入单个映射文件:不推荐 <mapper resource="sqlmap/UserMpper.xml"/> -->
<!-- 扫描整个包路径 -->
<package name="com.imwj.mapper"/>
</mappers>