Mybatis初级讲解

1. 总结jdbc开发的问题
1.      频繁创建数据库连接对象、释放,容易造成系统资源浪费,影响系统性能。企业项目中可以使用连接池解决这个问题,但是使用Jdbc需要自己实现连接池。mybatis已经提供了连接池。
2.      sql语句定义、参数设置、结果集处理存在硬编码。企业项目中,sql语句变化的可能性较大,一旦发生变化,需要修改Java代码,系统需要重新编译,重新发布。不好维护。
3.      结果集处理存在重复代码,处理麻烦。如果可以映射为java对象会比较方便。
 
2.   mybatis介绍
mybatisApache软件基金会下的一个开源项目,前身是Ibatis框架。2010年这个项目由apache 软件基金会迁移到google code下,改名为mybatis201311月又迁移到了githubhttps://github.com/mybatis/mybatis-3/releases)。
mybatis是一个持久层的框架,是对JDBC操作数据库的封装,使开发者只需要关注业务本身,不需要花费精力去处理加载驱动、创建数据库连接对象、创建statement语句对象、参数设置、结果集处理等一系列繁杂的过程代码。
mybatis通过xml或注解进行配置,将java对象与sql语句中的参数自动映射生成最终执行的sql语句,并将sql语句执行结果自动映射java对象,返回给业务层(service)应用。
 
3.   mybatis入门程序
3.1. 需求
实现用户表(user)增、删、改、查操作。
1.      根据用户Id查询用户
2.      根据用户名称模糊查询用户
3.      新增用户
4.      根据用户Id修改用户
5.      根据用户Id删除用户
 
3.2. 需求实现
3.2.1. 配置pom.xml文件,加入mybatis依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
 
<groupId>cn.itheima</groupId>
<artifactId>mybatis-first</artifactId>
<version>0.0.1-SNAPSHOT</version>
 
<packaging>jar</packaging>
 
<name>mybatis-first</name>
<url>http://maven.apache.org</url>
 
<properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <!-- mysql版本 -->
     <mysql.version>5.1.30</mysql.version>
     <!-- junit版本 -->
     <junit.version>4.12</junit.version>
     <!-- mybatis版本号 -->
     <mybatis.version>3.4.5</mybatis.version>
     <!-- log4j日志包版本 -->
     <slf4j.version>1.7.7</slf4j.version>
     <log4j.version>1.2.17</log4j.version>
</properties>
 
<dependencies>
     <!-- mysql数据库依赖 -->
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>${mysql.version}</version>
     </dependency>
     <!-- mybatis核心包 -->
     <dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis</artifactId>
         <version>${mybatis.version}</version>
     </dependency>
     <!-- log4j日志包 -->
     <dependency>
         <groupId>log4j</groupId>
         <artifactId>log4j</artifactId>
         <version>${log4j.version}</version>
     </dependency>
     <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-api</artifactId>
         <version>${slf4j.version}</version>
     </dependency>
     <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-log4j12</artifactId>
         <version>${slf4j.version}</version>
     </dependency>
     <!-- junit依赖 -->
     <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>${junit.version}</version>
         <scope>test</scope>
     </dependency>
</dependencies>
</project>
 
3.2.2. 准备配置文件
3.2.2.1. sqlMapConfig.xml
说明:mybatis框架核心配置文件。
<?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>
 
<!-- 运行环境配置 -->
<!-- default属性:指定使用哪一个运行环境 -->
<environments default="development">
     <!-- id属性:唯一标识一个运行环境 -->
     <environment id="development">
         <!-- 事务管理器配置,JDBC:mybatis默认使用jdbc事务 -->
        <transactionManager type="JDBC" />
        
         <!-- 数据源配置,POOLED:mybatis提供的连接池 -->
         <dataSource type="POOLED">
             <property name="driver" value="com.mysql.jdbc.Driver" />
             <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />
             <property name="username" value="root" />
             <property name="password" value="admin" />
         </dataSource>
     </environment>
</environments>
</configuration>
 
3.2.2.2. log4j.properties
# 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
 
3.2.3. 准备用户pojo
public class User {
  private Integer id; // int(11) NOT NULL AUTO_INCREMENT,
  private String username; // varchar(32) NOT NULL COMMENT '用户名称',
  private Date birthday; // date DEFAULT NULL COMMENT '生日',
  private String sex; // char(1) DEFAULT NULL COMMENT '性别',
  private String address; // varchar(256) DEFAULT NULL COMMENT '地址',
/**
 * @return the id
 */
public Integer getId() {
     return id;
}
/**
 * @param id the id to set
 */
public void setId(Integer id) {
     this.id = id;
}
/**
 * @return the username
 */
public String getUsername() {
     return username;
}
/**
 * @param username the username to set
 */
public void setUsername(String username) {
     this.username = username;
}
/**
 * @return the birthday
 */
public Date getBirthday() {
     return birthday;
}
/**
 * @param birthday the birthday to set
 */
public void setBirthday(Date birthday) {
     this.birthday = birthday;
}
/**
 * @return the sex
 */
public String getSex() {
     return sex;
}
/**
 * @param sex the sex to set
 */
public void setSex(String sex) {
    this.sex = sex;
}
/**
 * @return the address
 */
public String getAddress() {
     return address;
}
/**
 * @param address the address to set
 */
public void setAddress(String address) {
     this.address = address;
}
/* (non-Javadoc)
 * @see java.lang.Object#toString()
 */
@Override
public String toString() {
     return "User [id=" + id + ", username=" + username + ", birthday="
             + birthday + ", sex=" + sex + ", address=" + address + "]";
}
 
 
 
}
 
3.2.4. 准备sql语句
select * from `user` where id=24
 
3.2.5. 准备mapper映射文件
说明:用于配置java对象,与sql语句的对应关系。
<?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属性:名称空间,相当于java中的package,用于放置sql语句冲突 -->
<mapper namespace="test">
<!--说明:mybatis框架针对每一种sql语句:新增/修改/删除/查询,提供了对应的标签:
insert/update/delete/select来放置  -->
 
<!-- 根据用户Id查询用户,说明:
 select标签:用于放置查询sql语句
 id属性:唯一标识一条sql语句
 parameterType属性:输入参数类型
 resultType属性:返回值类型
 #{id}:占位符,相当于jdbc中的问号:?-->
<select id="queryUserById" parameterType="int" resultType="cn.itheima.mybatis.po.User">
     select * from `user` where id=#{id}
</select>
 
</mapper>
 
 
3.2.6. sqlMapcConfig.xml文件中,加载User.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>
 
<!-- 运行环境配置 -->
<!-- default属性:指定使用哪一个运行环境 -->
<environments default="development">
     <!-- id属性:唯一标识一个运行环境 -->
     <environment id="development">
         <!-- 事务管理器配置,JDBC:mybatis默认使用jdbc事务 -->
         <transactionManager type="JDBC" />
        
         <!-- 数据源配置,POOLED:mybatis提供的连接池 -->
         <dataSource type="POOLED">
             <property name="driver" value="com.mysql.jdbc.Driver" />
             <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />
             <property name="username" value="root" />
             <property name="password" value="admin" />
         </dataSource>
     </environment>
</environments>
<!-- 加载mapper映射文件 -->
<mappers>
     <!--加载User.xml文件,说明:
       resource属性:指定配置文件的位置-->
     <mapper resource="sqlmap/User.xml"/>
</mappers>
</configuration>
 
3.2.7. 编写测试代码
public class MybatisTest {
// 1.测试根据用户Id查询用户
@Test
public void queryUserByIdTest() throws IOException{
    
     // 1.加载核心配置文件:sqlMapConfig.xml
     // resource属性:指定核心配置文件位置
     InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    
     // 2.读取配置文件内容
     SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
     // SqlSessionFactory对象:mybatis框架的核心对象,一个项目中只需要一个(单例设计模式)
     SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
    
     // 3.使用SqlSessionFactory对象,创建sqlSession对象
     // sqlSession对象:
     // 3.1相当于jdbc中的connection对象
     // 3.2 sqlSession对象是线程不安全,每一个执行操作的方法,都需要创建一个sqlSession对象
     SqlSession sqlSession = sqlSessionFactory.openSession();
    
     // 4.使用sqlSession对象,调用方法执行
     // selectOne方法:查询单条记录
     // statement参数:执行的sql语句(名称空间+sql语句Id)
     // parameter参数:传入的参数值
     Object user = sqlSession.selectOne("test.queryUserById", 24);
     System.out.println(user);
    
     // 5.释放资源
     sqlSession.close();
    
}
 
}
 
 
3.3. 其他需求实现
3.3.1. 根据用户名称模糊查询用户
3.3.1.1. 准备sql语句
select * from `user` where username like '%小明%'
 
 
3.3.1.2. 配置映射文件
<!-- 根据用户名称模糊查询用户,说明 -->
<select id="queryUserByName" parameterType="string" resultType="cn.itheima.mybatis.po.User">
     select * from `user` where username like #{username}
</select>
 
3.3.1.3. 编写测试代码
// 2.测试根据用户名称模糊查询用户
@Test
public void queryUserByNameTest() throws IOException{
     // 1.加载核心配置文件
     InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    
     // 2.读取配置文件内容
     SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
     SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
    
     // 3.使用sqlSessionFactory对象,创建sqlSession对象
     SqlSession sqlSession = sqlSessionFactory.openSession();
    
     // 4.使用sqlSession对象,调用方法执行
     // selectList方法:查询多条记录
     // statement参数:执行的sql语句(名称空间+sql语句Id)
     // parameter参数:传入的参数值
     List<Object> list = sqlSession.selectList("test.queryUserByName", "%小明%");
     for(Object o :list){
         System.out.println(o);
     }
    
    // 5.释放资源
     sqlSession.close();
}
 

 
3.3.1.4. 使用字符串拼接符${},拼接参数
<!-- 根据用户名称模糊查询用户,说明 -->
<select id="queryUserByName" parameterType="string" resultType="cn.itheima.mybatis.po.User">
     <!-- select * from `user` where username like #{username} -->
    
     <!--  where username like '%小明%',说明:
     使用字符串拼接符${},拼接参数 -->
     select * from `user` where username like '%${value}%'
</select>
 

 
3.3.1.5. 占位符#{}与字符串拼接符${}区别
1.            占位符#{},相当于jdbc中的问号?,当参数传递的是java简单类型的时候,花括号中的内容可以是任意字符串。
2.            字符串拼接符 ${},当参数传递的是java简单类型的时候,花括号中的内容只能是:value
3.            sql语句中使用字符串拼接符${},可能引起sql注入的问题。但是mybatis中字符串拼接符可以使用,原因是是后端dao层的开发,项目中参数传递经过表现层(action),业务层(service)已经处理好。
 
3.3.2. 新增用户
3.3.2.1. 准备sql语句
insert into `user`(id,username,birthday,sex,address) values(2,'小李飞刀','2017-11-06','1','来自明朝')
 
3.3.2.2. 配置映射文件
<!-- 新增用户,说明
insert标签:用于放置新增sql语句
#{id}:占位符,当参数传递的是pojo的时候,换括号中的内容是pojo的属性-->
 <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
    insert into `user`(id,username,birthday,sex,address)
    values(#{id},#{username},#{birthday},#{sex},#{address})
 </insert>
 
3.3.2.3. 编写测试代码
// 3.测试新增用户
@Test
public void insertUserTest(){
     // 1.创建sqlSession对象
     SqlSession sqlSession = sqlSessionFactory.openSession();
    
     // 2.使用sqlSession对象,调用方法执行
     // insert方法:新增记录
     // statement参数:执行的sql语句(名称空间+sql语句Id)
     // parameter参数:传入的参数值
     // 创建用户对象
     User user  = new User();
     user.setId(3);
     user.setUsername("林诗音");
     user.setBirthday(new Date());
     user.setSex("2");
     user.setAddress("来自大明朝");
    
     sqlSession.insert("test.insertUser", user);
    
     // 3.释放资源
     sqlSession.close();
    
}
 

 
问题:java程序执行成功,但是数据库中并没有林诗音的数据,原因是没有提交事务。
 
 
3.3.2.4. 提交事务
3.3.2.4.1. 方式一
// 3.测试新增用户
@Test
public void insertUserTest(){
     // 1.创建sqlSession对象
     SqlSession sqlSession = sqlSessionFactory.openSession();
    
     // 2.使用sqlSession对象,调用方法执行
     // insert方法:新增记录
     // statement参数:执行的sql语句(名称空间+sql语句Id)
     // parameter参数:传入的参数值
     // 创建用户对象
     User user  = new User();
     user.setId(3);
     user.setUsername("林诗音");
     user.setBirthday(new Date());
     user.setSex("2");
     user.setAddress("来自大明朝");
    
     sqlSession.insert("test.insertUser", user);
    
     // 数据库提交事务:commit
     sqlSession.commit();
    
     // 3.释放资源
     sqlSession.close();
    
}
 
3.3.2.4.2. 方式二
// 3.测试新增用户
@Test
public void insertUserTest(){
     // 1.创建sqlSession对象
     //SqlSession sqlSession = sqlSessionFactory.openSession();
    
     // 创建sqlSession对象,指定自动提交事务。true:表示提交;false:表示不提交。默认是false
     SqlSession sqlSession =  this.sqlSessionFactory.openSession(true);
    
     // 2.使用sqlSession对象,调用方法执行
     // insert方法:新增记录
     // statement参数:执行的sql语句(名称空间+sql语句Id)
     // parameter参数:传入的参数值
     // 创建用户对象
     User user  = new User();
     user.setId(4);
     user.setUsername("林诗音");
     user.setBirthday(new Date());
     user.setSex("2");
     user.setAddress("来自大明朝");
    
     sqlSession.insert("test.insertUser", user);
    
     // 数据库提交事务:commit
     //sqlSession.commit();
    
     // 3.释放资源
     sqlSession.close();
    
}
 
 
问题:用户表中id是自增长,不需要传递,但是mybatis中如何获取到新增以后的用户Id???
 
mysql数据库查询新增Id
select LAST_INSERT_ID()
 
3.3.2.5. 获取新增的用户Id
3.3.2.5.1. 方式一
<!-- 新增用户,说明
insert标签:用于放置新增sql语句
#{id}:占位符,当参数传递的是pojo的时候,换括号中的内容是pojo的属性-->
 <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
    <!-- insert into `user`(id,username,birthday,sex,address)
    values(#{id},#{username},#{birthday},#{sex},#{address}) -->
   
    <!-- selectKey标签:查询主键id,说明
     keyColumn属性:主键字段(表)
     keyProperty属性:主键属性(pojo
     resultType属性:指定主键字段类型
     order属性:指定在insert语句之前,还是之后获取主键值.
     BEFORE:在insert语句前;AFTER:在insert语句之后-->
    <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
        select LAST_INSERT_ID()
    </selectKey>
    insert into `user`(username,birthday,sex,address)
    values(#{username},#{birthday},#{sex},#{address})
 </insert>
 

 
3.3.2.5.2. 方式二
<!-- 新增用户,说明
insert标签:用于放置新增sql语句
#{id}:占位符,当参数传递的是pojo的时候,换括号中的内容是pojo的属性-->
 <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User"
 useGeneratedKeys="true" keyColumn="id" keyProperty="id">
    <!-- insert into `user`(id,username,birthday,sex,address)
    values(#{id},#{username},#{birthday},#{sex},#{address}) -->
   
    <!-- selectKey标签:查询主键id,说明
     keyColumn属性:主键字段(表)
     keyProperty属性:主键属性(pojo
     resultType属性:指定主键字段类型
     order属性:指定在insert语句之前,还是之后获取主键值.
     BEFORE:在insert语句前;AFTER:在insert语句之后-->
    <!-- <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
        select LAST_INSERT_ID()
    </selectKey> -->
    insert into `user`(username,birthday,sex,address)
    values(#{username},#{birthday},#{sex},#{address})
 </insert>
 

 
3.3.3. 根据用户Id修改用户
3.3.3.1. 准备sql语句
update `user` set username='小李飞刀和林诗音',sex='2' where id=2
 
 
3.3.3.2. 配置映射文件
<!-- 根据用户id修改用户,说明:
  update标签:用于放置修改sql语句-->
  <update id="updateUserById" parameterType="cn.itheima.mybatis.po.User">
    update `user`
    set username=#{username},sex=#{sex} where id=#{id}
  </update>
 
 
3.3.3.3. 编写测试代码
// 4.测试根据用户Id修改用户
@Test
public void updateUserByIdTest(){
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession(true);
    
     // 2.使用sqlSession对象,调用方法执行
     // update方法:修改记录
     // statement参数:执行的sql语句(名称空间+sql语句Id)
     // parameter参数:传入的参数值
     // 创建用户对象
     User user = new User();
     user.setId(3);
     user.setUsername("林诗音和小李飞刀");
     user.setSex("1");
    
     sqlSession.update("test.updateUserById", user);
    
     // 3.释放资源
     sqlSession.close();
}
 

 
3.3.4. 根据用户Id删除用户
3.3.4.1. 准备sql语句
delete from `user` where id=4
 
 
3.3.4.2. 配置映射文件
 <!-- 根据用户id删除用户,说明:
   delete标签:用于放置删除的sql语句-->
   <delete id="deleteUserById" parameterType="int">
        delete from `user` where id=#{id}
   </delete>
 
 
3.3.4.3. 编写测试代码
// 5.测试根据用户Id删除用户
@Test
public void deleteUserByIdTest(){
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession(true);
    
     // 2.使用sqlSession对象,调用方法执行
     // delete方法:删除记录
     // statement参数:执行的sql语句(名称空间+sql语句Id)
     // parameter参数:传入的参数值
     sqlSession.delete("test.deleteUserById", 35);
    
     // 3.释放资源
     sqlSession.close();
}
 

 
4.   mybatis框架原理

1.      Configuration配置对象:sqlMapConfig.xlUser.xml......
2.      MappedStatement对象:负责输入输出映射,ParameterType参数输入,ResultType返回值输出
3.      Executor执行器对象:负责执行数据库的CRUD操作
 
5.   mybatis两种开发方法
1.      原始的dao开发方法
2.      mapper代理开发方法
 
 
5.1. 原始的dao开发方法
5.1.1. 需求
1.      根据用户Id查询用户
2.      新增用户
 
5.1.2. 需求实现
5.1.2.1. 准备用户dao接口
public interface UserDao {
//   1.根据用户Id查询用户
User queryUserById(Integer id);
//   2.新增用户
void insertUser(User user);
 
}
 
 
5.1.2.2. 实现用户dao接口
public class UserDaoImpl implements UserDao {
// 定义sqlSessionFactory对象
private SqlSessionFactory sqlSessionFactory;
 
/**
 *
 */
public UserDaoImpl() {
     super();
}
 
/**
 * @param sqlSessionFactory
 */
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
     super();
     this.sqlSessionFactory = sqlSessionFactory;
}
 
/* (non-Javadoc)
 * @see cn.itheima.mybatis.dao.UserDao#queryUserById(java.lang.Integer)
 */
public User queryUserById(Integer id) {
     // TODO Auto-generated method stub
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession();
    
     // 2.使用sqlSession对象,调用方法执行
     Object user = sqlSession.selectOne("test.queryUserById", id);
    
     // 3.释放资源
     sqlSession.close();
    
     return (User) user;
}
 
/* (non-Javadoc)
 * @see cn.itheima.mybatis.dao.UserDao#insertUser(cn.itheima.mybatis.po.User)
 */
public void insertUser(User user) {
     // TODO Auto-generated method stub
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession(true);
    
     // 2.使用sqlSession对象,调用方法执行
     sqlSession.insert("test.insertUser", user);
    
     // 3.释放资源
     sqlSession.close();
 
}
 
}
 
5.1.2.3. 编写测试代码
public class UserDaoTest {
private SqlSessionFactory sqlSessionFactory = null;
@Before
public void init() throws IOException{
    // 1.加载核心配置文件:sqlMapConfig.xml
     // resource属性:指定核心配置文件位置
     InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    
     // 2.读取配置文件内容
     SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
     // SqlSessionFactory对象:mybatis框架的核心对象,一个项目中只需要一个(单例设计模式)
     sqlSessionFactory = builder.build(inputStream);
}
// 测试根据用户Id查询用户
@Test
public void queryUserByIdTest(){
    
     // 1.创建用户dao对象
     UserDao userDao = new UserDaoImpl(sqlSessionFactory);
    
     // 2.使用userDao对象,调用方法执行
     User user = userDao.queryUserById(2);
     System.out.println(user);
    
}
 
}
 

 
测试新增用户:
// 测试新增用户
@Test
public void insertUserTest(){
     // 1.创建用户dao对象
     UserDao userDao = new UserDaoImpl(sqlSessionFactory);
    
     // 2.使用userDao对象,调用方法执行
     // 创建用户对象
     User user = new User();
     user.setUsername("阿飞");
     user.setSex("1");
     user.setBirthday(new Date());
     user.setAddress("来自大明朝");
    
     System.out.println("执行前:"+user);
     userDao.insertUser(user);
     System.out.println("执行后:"+user);
}
 

 
5.2. mapper代理开发方法
 
5.2.1. 注意事项
1.      要求mapper映射文件中namespace属性值,必须是mapper接口的全路径(包名称+接口名称)
2.      要求mapper映射文件中sql语句的声明,与mapper接口方法的声明一致
2.1.mapper接口返回值类型,与sql语句标签的resultType属性指定的类型一致
2.2.mapper接口的方法名称,与sql语句id属性值一致
2.3.mapper接口的方法的形参,与sql语句的parameterType属性指定的类型一致
 
5.2.2. 需求
1.      根据用户Id查询用户
2.      新增用户
 
5.2.3. 需求实现
5.2.3.1. 准备用户mapper接口
public interface UserMapper {
//   1.根据用户Id查询用户
User queryUserById(Integer id);
//   2.新增用户
void insertUser(User user);
 
}
 
5.2.3.2. 准备用户mapper映射文件
<?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属性:名称空间,相当于java中的package,用于放置sql语句冲突 -->
<!--mapper代理开发方法中,namespace属性值,必须是mapper接口的全路径  -->
<mapper namespace="cn.itheima.mybatis.mapper.UserMapper">
 
<!-- 根据用户Id查询用户,说明:
 select标签:用于放置查询sql语句
 id属性:唯一标识一条sql语句
 parameterType属性:输入参数类型
 resultType属性:返回值类型
 #{id}:占位符,相当于jdbc中的问号:?-->
<select id="queryUserById" parameterType="int" resultType="cn.itheima.mybatis.po.User">
     select * from `user` where id=#{id}
</select>
<!-- 新增用户,说明
insert标签:用于放置新增sql语句
#{id}:占位符,当参数传递的是pojo的时候,换括号中的内容是pojo的属性-->
 <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User"
 useGeneratedKeys="true" keyColumn="id" keyProperty="id">
    insert into `user`(username,birthday,sex,address)
    values(#{username},#{birthday},#{sex},#{address})
 </insert>
 
</mapper>
 
 
5.2.3.3. sqlMapConfig.xml,加载UserMapper.xml文件
<!-- 加载mapper映射文件 -->
<mappers>
     <!--加载User.xml文件,说明:
       resource属性:指定配置文件的位置-->
     <mapper resource="sqlmap/User.xml"/>
     <!-- 加载UserMapper.xml文件 -->
     <mapper resource="sqlmap/UserMapper.xml"/>
</mappers>
 
 
5.2.3.4. 编写测试代码
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory = null;
@Before
public void init() throws IOException{
     // 1.加载核心配置文件:sqlMapConfig.xml
     // resource属性:指定核心配置文件位置
     InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    
     // 2.读取配置文件内容
     SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
     // SqlSessionFactory对象:mybatis框架的核心对象,一个项目中只需要一个(单例设计模式)
     sqlSessionFactory = builder.build(inputStream);
}
// 测试根据用户Id查询用户
@Test
public void queryUserByIdTest(){
    
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession();
    
     // 2.使用sqlSession对象,获取mapper代理对象
     // getMapper方法:获取mapper代理对象
     // type参数:mapper接口的class
     UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
     // 3.使用mapper代理对象,调用方法执行
     User user = mapper.queryUserById(2);
     System.out.println(user);
    
     // 4.释放资源
     sqlSession.close();
}
 
}
 

 
测试新增用户:
// 测试新增用户
@Test
public void insertUserTest(){
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession(true);
    
     // 2.使用sqlSession对象,获取mapper代理对象
     UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
     // 3.使用mapper对象,调用方法执行
     // 创建用户对象
     User user = new User();
     user.setUsername("天机老人");
     user.setSex("1");
     user.setBirthday(new Date());
     user.setAddress("来自大明朝");
    
     mapper.insertUser(user);
    
     // 4.释放资源
     sqlSession.close();
}
 
5.3. 两种开发方法总结
1.      原始的dao开发方法:需要开发接口和实现类
2.      mapper代理开发方法:只需要开发接口
3.      企业项目中,推荐使用mapper代理开发
 
6.   mybatis核心配置文件
sqlMapConfig.xml:配置运行环境(数据源),mapper映射文件。
顺序
配置标签名称
说明
1
properties
属性
2
settings
配置全局参数
3
typeAliases
类型别名
4
typeHandlers
类型处理器
5
objectFactory
对象工厂
6
plugins
插件
7
environments
环境集合属性对象
8
databaseIdProvider
多数据库支持
9
mappers
映射器
说明:
1.        红色字体内容要求掌握
2.        sqlMapConfig.xml必须是从上往下的配置顺序
 
6.1. properties(属性)
作用:加载属性文件(比如db.properties)和定义属性
 
6.1.1. 准备db.properties文件

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://127.0.0.1:3306/mybatis
db.username=root
db.password=admin
 
6.1.2. 加载db.properties属性文件
<!--加载属性文件,说明:
 1.resource属性:指定本地配置文件的位置
 2.url属性:指定网络上的配置文件位置-->
<properties resource="db.properties" >
   </properties>
 
 
6.1.3. 使用db.propertis属性文件中的属性
<!-- 运行环境配置 -->
<!-- default属性:指定使用哪一个运行环境 -->
<environments default="development">
     <!-- id属性:唯一标识一个运行环境 -->
     <environment id="development">
         <!-- 事务管理器配置,JDBC:mybatis默认使用jdbc事务 -->
         <transactionManager type="JDBC" />
        
         <!-- 数据源配置,POOLED:mybatis提供的连接池 -->
         <dataSource type="POOLED">
             <!-- <property name="driver" value="com.mysql.jdbc.Driver" />
             <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />
             <property name="username" value="root" />
             <property name="password" value="admin" /> -->
            
             <!-- 使用db.properties属性文件的属性 -->
             <property name="driver" value="${db.driver}" />
             <property name="url" value="${db.url}" />
             <property name="username" value="${db.username}" />
             <property name="password" value="${db.password}" />
         </dataSource>
     </environment>
   </environments>
 
6.1.4. 使用内部property标签定义属性
<!--加载属性文件,说明:
 1.resource属性:指定本地配置文件的位置
 2.url属性:指定网络上的配置文件位置
 3.使用内部property标签定义属性
 4.加载顺序:首先加载内部property标签定义的属性,再加载属性文件中的属性,
 如果有相同的属性,属性文件中的属性,覆盖内部property标签的属性-->
<properties resource="db.properties" >
     <property name="db.username" value="root123"/>
     <property name="db.password" value="admin"/>
   </properties>
 
6.2. typeAliases(类型别名)
作用:简称。比如中华人民共和国,简称中国。
6.2.1. 内置别名
别名
映射类型
_byte
byte
_long
long
_short
short
_int
int
_integer
int
_double
double
_float
float
_boolean
boolean
string
String
byte
Byte
long
Long
short
Short
int
Integer
integer
Integer
double
Double
float
Float
boolean
Boolean
date
Date
decimal
BigDecimal
bigdecimal
BigDecimal
object
Object
map
Map
hashmap
HashMap
list
List
arraylist
ArrayList
collection
Collection
iterator
Iterator
 
说明:
1.      内置别名可以直接使用
2.      别名不区分大小写
 
6.2.2. 自定义别名
6.2.2.1. 自定义别名方式一
<!-- 自定义别名配置 -->
<typeAliases>
     <!-- 自定义用户别名配置,说明:
     1.type属性:别名的类型
     2.默认使用类名称,作为别名
     3.alias属性:指定别名的名称 -->
     <typeAlias type="cn.itheima.mybatis.po.User" alias="user"/>
</typeAliases>
 
6.2.2.2. 自定义别名方式二
<!-- 自定义别名配置 -->
<typeAliases>
     <!-- 自定义用户别名配置,说明:
     1.type属性:别名的类型
     2.默认使用类名称,作为别名
     3.alias属性:指定别名的名称 -->
     <!-- <typeAlias type="cn.itheima.mybatis.po.User" alias="user"/> -->
    
     <!--包扫描方式配置别名,说明:
      1.name属性:指定扫描的包
      2.默认使用类名称,作为别名
      3.如果有多个包,配置多个package
      4.企业项目中,推荐使用包扫描方式 -->
     <package name="cn.itheima.mybatis.po"/>
</typeAliases>
 
6.3. mappers(映射器)
作用:加载mapper映射文件。
 
6.3.1. 加载mapper映射文件方式一
<!-- 加载mapper映射文件 -->
<mappers>
     <!--加载User.xml文件,说明:
       resource属性:指定配置文件的位置-->
     <mapper resource="sqlmap/User.xml"/>
     <!-- 加载UserMapper.xml文件 -->
     <mapper resource="sqlmap/UserMapper.xml"/>
   </mappers>
 
 
6.3.2. 加载mapper映射文件方式二
<!-- 加载mapper映射文件 -->
<mappers>
     <!--加载User.xml文件,说明:
       resource属性:指定配置文件的位置-->
     <mapper resource="sqlmap/User.xml"/>
     <!-- 加载UserMapper.xml文件 -->
     <!-- <mapper resource="sqlmap/UserMapper.xml"/> -->
    
     <!-- 包扫描方式加载mapper映射文件,说明:
     1.前提必须是mapper代理开发方法
     2.要求mapper映射文件,与mapper接口在同一个目录
     3.要求mapper映射文件的名称,与mapper接口的名称一致 -->
     <package name="cn.itheima.mybatis.mapper"/>
   </mappers>
 
 
7.   mybatishibernate比较
7.1. 相同点
都是对jdbc的封装,都是持久层的框架,都用于dao层的开发。
 
7.2. 不同点
1.      hibernate是对sql语句做了封装,提供HQL语言操作数据库,数据库无关性支持好,在项目需要支持多种数据库的情况下,代码开发量较少,sql语句优化困难;mybatis是直接使用sql语句操作数据库,不支持数据库无关性,在项目需要支持多种数据库的情况下,代码开发量较多,sql语句优化容易。
2.      hibernate是配置java对象与数据库表的对应关系,多表关联关系配置复杂。mybatis是配置java对象,与sql语句对应关系,多表关联关系配置容易。
3.      hibernate是重量级的框架,学习使用门槛高,适合于需求相对稳定,中小型的项目,比如:办公自动化系统(OA);mybatis是轻量级的框架,学习使用门槛低,适合于需求变化频繁,大型的项目,比如:互联网电子商务网站项目。目前在企业项目中,mybatis框架使用更多一些。
 
8.   扩展
8.1. 注解开发
//   3.根据用户Id查询用户,使用注解开发实现
@Select("select * from `user` where id=#{id}")
User queryUserById_1(Integer id);
 
// 测试根据用户Id查询用户,测试注解开发
@Test
public void queryUserById_1Test(){
    
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession();
    
     // 2.使用sqlSession对象,获取mapper代理对象
     // getMapper方法:获取mapper代理对象
     // type参数:mapper接口的class
     UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
     // 3.使用mapper代理对象,调用方法执行
     User user = mapper.queryUserById_1(2);
     System.out.println(user);
    
     // 4.释放资源
     sqlSession.close();
   }
 
说明:注解开发,只做了解,企业项目中不推荐使用。
 
8.2. 缓存
8.2.1. 一级缓存(sqlSession级别)
// 测试根据用户Id查询用户,测试一级缓存
@Test
public void oneCacheTest(){
    
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession();
    
     // 2.使用sqlSession对象,获取mapper代理对象
     // getMapper方法:获取mapper代理对象
     // type参数:mapper接口的class
     UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
     // 3.使用mapper代理对象,调用方法执行
     User user = mapper.queryUserById(2);
     System.out.println(user);
    
     System.out.println("-------------------------------------");
    
     User user1 = mapper.queryUserById(2);
     System.out.println(user1);
    
    
     // 4.释放资源
     sqlSession.close();
   }
 

 
说明:一级缓存mybatis框架就已经默认使用,不需要关心。
 
8.2.2. 二级缓存(mapper级别缓存,在多个SqlSession之间共享)
8.2.2.1. sqlMapConfig.xml中,配置开启二级缓存
<!-- 全局参数配置 -->
<settings>
     <!-- 配置开启二级缓存 -->
     <setting name="cacheEnabled" value="true"/>
</settings>
 
 
8.2.2.2. 修改用户pojo,实现序列化接口
public class User implements java.io.Serializable{
  private Integer id; // int(11) NOT NULL AUTO_INCREMENT,
  private String username; // varchar(32) NOT NULL COMMENT '用户名称',
  private Date birthday; // date DEFAULT NULL COMMENT '生日',
  private String sex; // char(1) DEFAULT NULL COMMENT '性别',
  private String address; // varchar(256) DEFAULT NULL COMMENT '地址',
 
8.2.2.3. UserMapper.xml中,开启使用二级缓存

 
8.2.2.4. 测试二级缓存
// 测试根据用户Id查询用户,测试二级缓存
@Test
public void twoCacheTest(){
    
     // 1.创建sqlSession对象
     SqlSession sqlSession = this.sqlSessionFactory.openSession();
    
     // 2.使用sqlSession对象,获取mapper代理对象
     // getMapper方法:获取mapper代理对象
     // type参数:mapper接口的class
     UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
     // 3.使用mapper代理对象,调用方法执行
     User user = mapper.queryUserById(2);
     System.out.println(user);
 
     // 4.释放资源
     sqlSession.close();
    
     System.out.println("-----------------------------------------");
    
     //  5.创建sqlSession对象
     SqlSession sqlSession1 = this.sqlSessionFactory.openSession();
    
     // 6.使用sqlSession对象,获取mapper代理对象
     // getMapper方法:获取mapper代理对象
     // type参数:mapper接口的class
     UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
    
     // 7.使用mapper代理对象,调用方法执行
     User user1 = mapper1.queryUserById(2);
     System.out.println(user1);
 
     // 8.释放资源
     sqlSession1.close();
}

说明:mybatis框架的二级缓存,只做了解,企业项目中不推荐使用。原因是mybatis框架的二级缓存不能实现细粒度的控制。
 
 







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值