Mybatis学习第二弹。

Mybatis-2-简单CRUD

  • 步骤

    1. 创建Maven工程
    2. 关联坐标
    3. 编写实体类和持久层接口
    4. 编写SqlMapConfig.xml
    5. 编写映射配置文件
    6. 编写测试类
    7. 添加其他查询功能
  • 使用要求

    1. 持久层接口和持久层接口的映射配置必须在相同包下
    2. 持久层映射中mapper标签的namespace属性取值必须是持久层接口的全限定类名。
    3. SQL语句的配置标签:select、insert、delete、update的id属性必须和持久层接口的方法名相同。

1. 创建Maven工程

2. 导入坐标

  • pom.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <dependencies>
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
    </dependency>

    <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.5</version>
    </dependency>

    <dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6</version>
    </dependency>
    <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
    </dependency>

    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
    <scope>test</scope>
    </dependency>
    </dependencies>

3. 编写实体类和持久层接口

  • 在main->java下讲解domain和dao包

  • domain->User实体类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package top.tobing.domain;
    import java.util.Date;
    public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    // getter and setter.....

    @Override
    public String toString() {
    return .....
    }
    }
  • dao->UserDao持久层接口

    1
    2
    3
    4
    5
    6
    7
    8
    package top.tobing.dao;
    import top.tobing.domain.User;
    import java.util.List;

    public interface UserDao {
    public List<User> findAll();
    }

4. 编写SqlMapConfig.xml

  • SqlMapConfig.xml用于配置数据库相关信息。以及关联UserDao的配置文件。

  • 在resources目下新建SQLMapConfig.xml文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?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="mysql">
    <environment id="mysql">
    <transactionManager type="JDBC"></transactionManager>
    <dataSource type="POOLED">
    <!--连接数据库信息-->
    <property name="driver" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/ee50"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
    </dataSource>
    </environment>
    </environments>
    <mappers>
    <mapper resource="top/tobing/dao/UserDao.xml"></mapper>
    </mappers>
    </configuration>

5. 编写映射配置文件

  • 每一个Dao接口对应一个映射配置文件

  • 在resources下创建UserDao三级目录top->tobing->dao(记住要一级一级创建,不能和包一样创建)

  • 在dao目录下创建UserDao.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?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="top.tobing.dao.UserDao">
    <select id="findAll" resultType="top.tobing.domain.User">
    SELECT * from user ;
    </select>
    </mapper>
    • namespace:要绑定Dao接口
    • id:指定Dao接口中的方法
    • resultType:设置返回值类型(全限定类名)

6. 编写测试类

  • test->java下创建top.tobing.test包,并创建UserDaoTest测试类用于测试是否可用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    package top.tobing.test;
    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 top.tobing.dao.UserDao;
    import top.tobing.domain.User;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;

    public class UserDaoTest {
    @Test
    public void findAllTest() throws IOException {
    //1.读取配置文件
    InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
    //2.创建工厂类
    SqlSessionFactory factory =new SqlSessionFactoryBuilder().build(in);
    //3.生产SqlSession对象
    SqlSession session = factory.openSession();
    //4.获取代理对象
    UserDao userDao = session.getMapper(UserDao.class);
    //5.执行查询语句
    List<User> users = userDao.findAll();
    //6.遍历输出
    for(User user:users){
    System.out.println(user);
    }
    //7.关闭资源
    session.close();
    in.close();
    }
    }

7. 其他CRUD操作

  1. 到Dao接口中添加新方法
  2. 同时在UserDao.xml中管理方法,编写Sql 语句
  3. 在UserDaoTest中添加新的对应的测试方法
1. Dao接口中添加新方法
1
public User findById(int id);
2. UserDao.xml中绑定该方法,编写Sql语句
1
2
3
4
5
6
<mapper namespace="top.tobing.dao.UserDao">
......
<select id="findById" resultType="top.tobing.domain" parameterType="java.lang.Integer">
select * from user where id = #{id};
</select>
</mapper>
3. 在UserDaoTest中添加对应的测试方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void findById() throws IOException {
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建工厂类
SqlSessionFactory factory =new SqlSessionFactoryBuilder().build(in);
//3.生产SqlSession对象
SqlSession session = factory.openSession();
//4.获取代理对象
UserDao userDao = session.getMapper(UserDao.class);
//5.执行查询语句
User user = userDao.findById(49);
//6.输出
System.out.println(user);
//7.关闭资源
session.close();
in.close();
}

8. 优化

  • 由UserDaoTest中的代码可以看出,在每次创建测试类的时候都要读取配置文件,创建工厂类,获取SqlSession对象等,重复代码较多,因此考虑抽取共性部分将其封装为两个方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    private InputStream in;
    private SqlSession session;
    private UserDao userDao;

    /**
    * 初始化方法
    */
    @Before // 在方法执行前执行
    public void init(){
    try{
    //1.读取配置文件
    in = Resources.getResourceAsStream("SqlMapConfig.xml");
    //2.创建工厂类
    SqlSessionFactory factory =new SqlSessionFactoryBuilder().build(in);
    //3.生产SqlSession对象
    session = factory.openSession();
    //4.获取代理对象
    userDao = session.getMapper(UserDao.class);
    }catch (Exception e){
    e.printStackTrace();
    }
    }

    /**
    * 释放资源
    */
    @After // 在方法执行之后执行
    public void destroy() throws IOException {
    session.commit(); // 此处记得提交事务
    session.close();
    in.close();
    }

9. 批量CRUD

  • 步骤
    1. UserDao
    2. UserDao.xml
    3. UsetDaoTest
1. UserDao添加方法
  • java.top.tobing.dao.UserDao
1
2
3
4
5
6
7
8
9
10
11
// 保存用户
public void save(User user);
// 更新用户
void updateUser(User user);
//根据Id删除用户
void deleteUser(Integer serId);
// 根据用户名模糊查找
List<User> findByName(String name);
// 查找用户记录条数
int findTotal();

2. UserDao.xml修改配置
  • resources->top/tobing/dao/UserDao.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!---------------------------------------save------------------------------------->
<!--
注意!在传入参数的时候,在sql语句中获取User的属性的时候,要以getAbc的方法为准,也就是说。要获取User中的getAbc()对应获取的属性,就填写#{abc},即是getAbc方法去掉get并将首字母小写。
-->
<insert id="save" parameterType="top.tobing.domain.User">
<!--此处配置使用与保持添加之后自增长id-->
<selectKey keyColumn="id" keyProperty="id" resultType="int">
select last_insert_id();
</selectKey>
INSERT into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
<!---------------------------------------updateUser------------------------------------->

<update id="updateUser" parameterType="top.tobing.domain.User">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id = #{id};
</update>
<!---------------------------------------deleteUser------------------------------------->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{id};
</delete>
<!---------------------------------------findByName------------------------------------->

<select id="findByName" resultType="top.tobing.domain.User" parameterType="java.lang.String">
SELECT * from user where username like #{username};
</select>
<!---------------------------------------findTotal------------------------------------->
<select id="findTotal" resultType="java.lang.Integer">
select count(*) from user;
</select>

3. 编写对应测试方法测试
  • test->java->top.tobing.test->UserDaoTest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Test
public void updateUserTest(){
User user = new User();
user.setUsername("张翠山");
user.setAddress("广东省广州市");
user.setSex("男");
user.setId(50);
user.setBirthday(new Date());
UserDao userDao = session.getMapper(UserDao.class);
userDao.updateUser(user);
}
@Test
public void deleteUserTest(){
userDao.deleteUser(51);
}

@Test
public void findByIdTest(){
User user = userDao.findById(49);
System.out.println(user);
}
@Test
public void findByNameTest(){
List<User> users = userDao.findByName("%王%");
for (User user : users) {
System.out.println(user);
}
}
@Test
public void findTotlaTest(){
int total = userDao.findTotal();
System.out.println("数据条数为:"+total);
}

细节

  • 在sql语句中使用#{}字符:

    • 它代表占位符,相当于原来 jdbc 部分所学prepareStatment的?,都是用于执行语句时替换实际的数据。 具体的数据是由#{}里面的内容决定的。

    • 使用的是ognl表达式

    • ognl表达式

      1. 是Apache提供的一种表达式语言,全称是:Object Graphic Navigation Language 对象图导航语言。

      2. 一定的语法格式来获取数据:#{对象.对象}

  • parameterType配置参数

    • 基 本类 型和 String 我 们可 以直接 写类型 名称 ,也 可以 使用包 名 . 类名的 方式 ,例如 : java.lang.String。
    • 实体类类型(自定义),目前我们只能使用全限定类名
    • 是 mybaits 在加载时已经把常用的数据类型注册了别名,从而我们在使用时可以不写包名, 而我们的是实体类并没有注册别名,所以必须写全限定类名。
  • resultType配置

    • resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!-- 建立 User 实体和数据库表的对应关系
    type 属性:指定实体类的全限定类名
    id 属性:给定一个唯一标识,是给查询 select 标签引用用的。
    -->
    <resultMap type="top.tobing.domain.User" id="userMap">
    <id column="id" property="userId"/>
    <result column="username" property="userName"/>
    <result column="sex" property="userSex"/>
    <result column="address" property="userAddress"/>
    <result column="birthday" property="userBirthday"/>
    </resultMap>
    id 标签:用于指定主键字段
    result 标签:用于指定非主键字段
    column 属性:用于指定数据库列名
    property 属性:用于指定实体类属性名称



  • SqlMapConfig.xml配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    -properties(属性)  
    --property
    -settings(全局配置参数)
    --setting
    -typeAliases(类型别名)
    --typeAliase
    --package
    -typeHandlers(类型处理器)
    -objectFactory(对象工厂)
    -plugins(插件)
    -environments(环境集合属性对象)
    --environment(环境子属性对象)
    ---transactionManager(事务管理)
    ---dataSource(数据源)
    -mappers(映射器)
    --mapper
    --package

    • properties(属性)配置的两种方式

      • 直接定义
      1
      2
      3
      4
      5
      6
      7
      <properties> 
      <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy"/>
      <property name="jdbc.username" value="root"/>
      <property name="jdbc.password" value="1234"/>
      </properties>

      • 引用定义
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      <!-- 配置连接数据库的信息    
      resource 属性:用于指定 properties配置文件的位置,要求配置文件必须在类路径下 resource="jdbcConfig.properties"
      url 属性:
      URL: Uniform Resource Locator 统一资源定位符 http://localhost:8080/mystroe/CategoryServlet URL
      协议 主机 端口 URI
      URI:Uniform Resource Identifier 统一资源标识符
      /mystroe/CategoryServlet
      它是可以在 web 应用中唯一定位一个资源的路径 -->
      <properties url="file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.prop erties">
      </properties>
      <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>

    • typeAliases(类型别名)

      • Mybatis 支持的默认别名,我们也可以采用自定义别名方式来开发
      1
      2
      3
      4
      5
      6
      7
      8
      <typeAliases>  
      <!-- 单个别名定义 -->
      <typeAlias alias="user" type="top.tobing.domain.User"/>
      <!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
      <package name="top.tobing.domain"/>
      <package name=" 其它包 "/>
      </typeAliases>

    • mappers(映射器)尚未弄懂

      • resource:使用相对于类路径的资源

        1
        2
        <mapper resource="top/tobing/dao/IUserDao.xml" /> 

      • class:使用mapper接口类路径

        1
        2
        <mapper class="top.tobing.dao.UserDao"/> 

      • name:注册指定包下的使用Mapper接口

        1
        2
        <package name="top.tobing.mybatis.mapper"/> 

评论