目录
1
永和大王门店管理系统-SSM版 1
1 第一天:持久层框架MyBatis 3
1.1 前言 3
1.1.1 JDBC回顾 3
1.1.2 Mybatis概述 3
1.1.3 MyBatis原理图 4
1.2 开发环境 5
1.2.1 引入DTD文件提示支持 5
1.2.2 创建mybatisdb数据库,创建user表 7
1.3 Mybatis入门案例 8
1.3.1 Maven工程结构 8
1.3.2 pom.xml 8
1.3.3 sqlMapConfig.xml 9
1.3.4 User 10
1.3.5 UserMapper.xml 12
1.3.6 sqlMapConfig.xml中引入 UserMapper.xml 13
1.3.7 测试类 14
1.3.8 引入log4j打印SQL语句 15
1.4 总结 16
1.4.1 MyBatis中的重要对象 16
1.4.2 配置文件 16
1.5 常见操作 17
1.5.1 【根据id查询记录】 17
1.5.2 【查询总记录数】 17
1.5.3 【新增一条记录】 18
1.5.4 【修改指定记录】 18
1.5.5 【删除记录】 18
1.6 拓展: 19
1.6.1 #获取参数和$的区别 19
1.6.2 配置别名 19
1.6.3 SQL中有特殊字符 19
1.6.4 ResultMap映射不规范字段 20
1.6.5 自动匹配规范驼峰规则 20
1.6.6 自增主键 21

第一天:持久层框架MyBatis

MyBatis - 图1

前言

JDBC回顾

Java database connectivity,Java数据库连接。专门用来通过一段Java代码连接数据库操作数据库的一门技术。
开发步骤:
1,注册驱动 2,获取数据库连接
3,获取传输器(Statement、PreparedStatement)
4,执行SQL 5,遍历结果集 6,释放资源
其实,Mybatis也是用来操作数据库的技术,jdbc就可以了为啥又今天又要学框架?

Mybatis概述

MyBatis的前身就是iBatis,iBatis本是apache的一个开源项目,2010年5月这个项目由apahce sofeware foundation 迁移到了google code,并且改名为MyBatis。
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。

  1. 简化JDBC的开发

  2. 能够更好的完成ORM(对象关系映射)

MyBatis原理图

MyBatis - 图2

  1. SqlMapConfig.xml:此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

  2. UserMapper.xml:sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

  3. SqlSessionFactory:通过mybatis环境等配置信息构造会话工厂对象

  4. SqlSession:由会话工厂创建会话,操作数据库需要通过SqlSession进行。

  5. User:Executor把执行sql后的内容输出映射到java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

开发环境

引入DTD文件提示支持

MyBatis - 图3
MyBatis - 图4
MyBatis - 图5
MyBatis - 图6

创建mybatisdb数据库,创建user表

创建数据库
MyBatis - 图7

创建mybatisdb数据库,设置utf8字符集。
创建user表:
create database mybatisdb default character set utf8;
use mybatisdb;
create table user(
id int primary key auto_increment,
name varchar(100),
addr varchar(100),
age int);
insert into user values(null,’hanmeimei,’北京’,28);
insert into user values(null,’xiongda’,’上海’,20);
insert into user values(null,’xiaonger’,’上海’,19);

Mybatis入门案例

Maven工程结构

MyBatis - 图8
MyBatis - 图9

pom.xml

xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0

  1. <groupId>cn.tedu</groupId><br /> <artifactId>mybatis</artifactId><br /> <version>0.0.1-SNAPSHOT</version><br /> <packaging>jar</packaging>
  2. <name>mybatis</name><br /> <url>http://maven.apache.org</url>
  3. <properties><br /> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><br /> </properties>
  4. <dependencies><br /> <dependency><br /> <groupId>mysql</groupId><br /> <artifactId>mysql-connector-java</artifactId><br /> <version>5.1.40</version><br /> </dependency><br /> <dependency><br /> <groupId>org.mybatis</groupId><br /> <artifactId>mybatis</artifactId><br /> <version>3.2.8</version><br /> </dependency><br /> <dependency><br /> <groupId>cglib</groupId><br /> <artifactId>cglib</artifactId><br /> <version>2.2.2</version><br /> </dependency><br /> <dependency><br /> <groupId>log4j</groupId><br /> <artifactId>log4j</artifactId><br /> <version>1.2.17</version><br /> </dependency><br /> </dependencies><br /></project>

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">













value=”com.mysql.jdbc.Driver”/>

value=”jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf-8”/>








User

package cn.tedu.pojo;
//将表和字段映射给实体类和属性
public class User {

//id,name,addr,age<br />    //映射id字段<br />    private Integer id;<br />    <br />    //映射name字段<br />    private String name;<br />    <br />    //映射addr字段<br />    private String addr;<br />    <br />    //映射age字段<br />    private Integer age;

//getters and setters<br />    <br />    public Integer getId() {<br />        return id;<br />    }

public void setId(Integer id) {<br />        this.id = id;<br />    }

public String getName() {<br />        return name;<br />    }

public void setName(String name) {<br />        this.name = name;<br />    }

public String getAddr() {<br />        return addr;<br />    }

public void setAddr(String addr) {<br />        this.addr = addr;<br />    }

public Integer getAge() {<br />        return age;<br />    }

public void setAge(Integer age) {<br />        this.age = age;<br />    }

//toString()<br />    @Override<br />    public String toString() {<br />        return "User [id=" + id + ", name=" + name + ", addr=" + addr + ", age=" + age + "]";<br />    }<br />    <br />    <br />}

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">




resultType=”cn.tedu.pojo.User”>
select * from user



sqlMapConfig.xml中引入 UserMapper.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">















value=”com.mysql.jdbc.Driver”/>

value=”jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf-8”/>














测试类

获取SqlSessionFactory对象,加载配置文件

获取SqlSession对象,执行SQL

解析结果

释放资源

package cn.tedu.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.tedu.pojo.User;

//这个类用来测试MyBatis的入门案例
public class HelloTest {

//单元测试<br />    @Test<br />    **public** **void** hello() **throws** IOException{<br />//        1.3.7.1    获取SqlSessionFactory对象,<br />        //加载核心配置文件<br />        InputStream in = <br />                Resources._getResourceAsStream_<br />                ("sqlMapConfig.xml");<br />        <br />        SqlSessionFactory ssf = <br />                **new** SqlSessionFactoryBuilder()<br />                .build(in);<br />        <br />        <br />//        1.3.7.2    获取SqlSession对象,执行SQL<br />        SqlSession session = <br />                ssf.openSession();<br />        <br />//        1.3.7.3    解析结果<br />        //定位SQL的=namespace值+SQL的id值<br />        List<User> list = <br />                session.selectList(<br />                    "HelloMapper.SelectAll");<br />        //TODO遍历list<br />        **for** (User user : list) {<br />            System._**out**_.println(user);<br />        }<br />        <br />//        1.3.7.4    释放资源<br />        session.close();<br />        <br />    }<br />    <br />}

引入log4j打印SQL语句

在classpath中建立一个名叫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
再次运行:
DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@17671]
DEBUG [main] - ==> Preparing: select * from user
DEBUG [main] - ==> Parameters:
可以很清楚的看到执行的sql和执行sql使用的参数。

总结

MyBatis中的重要对象

MyBatis中有两个重要的对象,分别是SqlSessionFactory和SqlSession。

SqlSessionFactory

可以理解为会话工厂,在整个项目中共享,是线程安全的。通过openSession方法创建SqlSession对象,该方法存在很多重载方式可以有参数可以无参数。

SqlSession

可以通过会话工厂产生,线程不安全。用来执行SQL,提供了丰富的方法来完成数据库的操作。
Mybatis不会自动提交事务,需要手动提交。
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@56b981c0]
提交方式有两种:openSession(true)或者session.commit()

配置文件

核心配置文件sqlMapConfig.xml

  • 文件名可以随意命名,习惯名称sqlMapConfig.xml

  • 主要配置3个内容:事务管理器,数据源信息,映射文件

  • 后续和spring框架整合后,该文件内容就都没了

映射文件UserMapper.xml

  • 文件名可以随意命名,习惯的方式是: POJO对象名+Mapper.xml

  • 用来描述对应对象的信息,写大量表操作的SQL语句

  • 通过#{value}来获取值,value写的是属性的名字。

  • 命名空间namespace作为该映射文件的唯一标志

  • 映射文件里的配置要和代码中匹配,比如返回值类型,参数类型等等

常见操作

【根据id查询记录】

UserMapper.xml

添加SQL

<!-- 根据id查询记录<br />        id:是这条SQL的唯一标志<br />        resultType:查询的结果封装给哪个对象,全路径。。<br />    --><br />    <select id=_"SelectOne"_<br />            resultType=_"cn.tedu.pojo.User"_><br />        select * from user where id=22<br />    </select><br />    

创建测试类CRUDTest

调用sqlsession的CRUD方法<br />package cn.tedu.test;

import java.io.IOException;
import java.io.InputStream;

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.tedu.pojo.User;

public class CRUDTest {

//根据id查询记录<br />    @Test<br />    public void SelectOne() throws IOException{<br />        //加载核心配置文件<br />        InputStream in = <br />                Resources.getResourceAsStream(<br />                    "sqlMapConfig.xml");<br />        <br />        //创建会话工厂<br />        SqlSessionFactory ssf = <br />                new SqlSessionFactoryBuilder()<br />                .build(in);<br />        <br />        //创建会话<br />        SqlSession session = ssf.openSession();<br />        <br />        //定位SQL并执行<br />        //namespace值.SQL的id值<br />        //SQL对应的结果集类型就是测试代码对应的类型<br />        User user = <br />                session.selectOne("HelloMapper.SelectOne");<br />        <br />        //处理结果集<br />        System.out.println(user);<br />        //释放资源<br />        session.close();<br />        <br />    }<br />    <br />    <br />}

【查询总记录数】

UserMapper.xml




测试类

// 查询总记录数
@Test
public void Count() throws IOException{
//加载 核心配置文件
InputStream in =
Resources.getResourceAsStream(
“sqlMapConfig.xml”);

//创建ssf会话工厂
SqlSessionFactory ssf =
new SqlSessionFactoryBuilder()
.build(in);

//创建会话
SqlSession session = ssf.openSession();

//执行SQL
//定位SQL:namespace值.id值
int rows =
session.selectOne(“HelloMapper.Count”);

//处理结果集
System.out.println(rows);
//释放资源
session.close();

}

【新增一条记录】

UserMapper.xml

<!-- 新增一条记录 --><br />    <insert id=_"Add"_><br />        insert into user values<br />            (null,'rose','taiguo',18)<br />    </insert><br />或者<br /><!-- 新增一条记录 <br />        #{id}获取值  id是实体对象的属性名<br />    --><br />    <insert id=_"Add"_><br />        insert into user values<br />        (#{id},#{name},#{addr},#{age})<br />    </insert>

改造测试类

<br />//    新增一条记录<br />    @Test<br />    **public** **void** add() **throws** IOException{<br />        //加载核心配置文件<br />        InputStream in = Resources._getResourceAsStream_(<br />                "sqlMapConfig.xml");<br />        <br />        //创建ssf会话工厂<br />        SqlSessionFactory ssf = <br />                **new** SqlSessionFactoryBuilder()<br />                .build(in);<br />        <br />        //创建会话<br />        SqlSession session = ssf.openSession();<br />        <br />        //定位SQL并执行<br />        //namcspace.id<br />        session.insert("HelloMapper.Add");<br />        <br />        //手动提交事务<br />        //openSession(boolean autocommit)<br />        session.commit();<br />        <br />        //释放资源<br />        session.close();<br />        <br />    }

或者

// 新增一条记录
@Test
public void add2() throws IOException{
//加载核心配置文件
InputStream in = Resources.getResourceAsStream(
“sqlMapConfig.xml”);

//创建ssf会话工厂
SqlSessionFactory ssf =
new SqlSessionFactoryBuilder()
.build(in);

//创建会话
SqlSession session = ssf.openSession();

//定位SQL并执行
//namcspace.id
//设置参数,SQL中动态获取参数值
User user=new User();
user.setName(“jack”);
user.setAddr(“shanghai”);
user.setAge(20);

    session.insert("HelloMapper.Add",user);<br />        <br />        //手动提交事务<br />        //openSession(boolean autocommit)<br />        session.commit();<br />        <br />        //释放资源<br />        session.close();<br />        <br />    }<br />    <br />    

【修改指定记录】

UserMapper.xml



update user set
age=#{age} where
id=#{id}

测试类

@Test
public void update() throws IOException{
//加载核心配置文件
InputStream in =
Resources.getResourceAsStream(
“sqlMapConfig.xml”);

//创建ssf
SqlSessionFactory ssf =
new SqlSessionFactoryBuilder()
.build(in);

//创建会话
SqlSession session =
ssf.openSession(true);

//定位SQL并执行
//第一个参数用来定位SQL
//第二个参数用来给SQL传递参数
User user = new User();
user.setAge(52);
user.setId(22);

session.update(
“HelloMapper.update”,user);

session.close();

}

【根据id删除一条记录】

UserMapper.xml



delete from user where id=#{id}

测试类

// 根据id删除一条记录
@Test
public void delete() throws IOException{
//加载核心配置文件
InputStream in =
Resources.getResourceAsStream(
“sqlMapConfig.xml”);

//创建ssf
SqlSessionFactory ssf =
new SqlSessionFactoryBuilder()
.build(in);

//创建会话
SqlSession session = ssf.openSession(true);

//定位SQL并执行
//第一个参数用来定位SQL
//第二个参数用来给SQL传递参数
User user = new User();
user.setId(27);

session.delete(“HelloMapper.delete”,user);

session.close();

}

拓展:

前面讲了CRUD的全部测试,下面是对CRUD示例的优化:

#获取参数和$的区别

(推荐!)#: 使用#{parameterName}引用参数的时候,Mybatis会把这个参数认为是一个字符串,例如传入参数是“Smith”,那么在SQL(Select from emp where name = #{employeeName})使用的时候就会转换为Select from emp where name = ‘Smith’。
MyBatis - 图10

$: 不做字符串拼接,SQL(Select from emp where name = ${employeeName})使用的时候就会转换为Select from emp where name = Smith。此时,如果字段是varchar类型直接抛出SQL异常。
MyBatis - 图11

从安全性上考虑,能使用#尽量使用#来传参,因为这样可以有效防止SQL注入的问题。

配置别名

在sqlMapConfig.xml配置,在映射文件中直接写对象名称即可


SQL中有特殊字符

当SQL中有特殊字符,mybatis不能正常解析时,用CDATA括起来
<![CDATA[ age<=#{age} ]]>

ResultMap映射不规范字段

<?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">











自动匹配规范驼峰规则

数据库中我们习惯使用全大写,多个单词用下划线隔开,而po对象,习惯使用java驼峰规则。那一个一个手工写resultMap字段,浪费开发时间。Mybatis可以配置mapUnderscoreToCamelCase,实现自动映射。这个值默认为true。
1)全局配置:
<?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">





2)resultMap配置autoMapping=”true”



注意:主键需要单独写,其它字段就可以直接利用驼峰规则自动映射。

自增主键

字段类型必须为int/long,数据还需支持mysql,sqlserver,oracle不支持
<?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">



insert into person_c
(name)
values
(#{name})