mybatis+spring的TODO小项目记录(六)使用mybatis进行数据库操作

4 篇文章 0 订阅
2 篇文章 0 订阅

在前面的准备工作完成之后,我们终于可以使用mybatis进行数据库操作啦。在第一篇中介绍了三张简单的表结构:userprojectstep。鉴于数据表很简单并且很相似,在这里只以用户表user为例进行说明。

第一步,我们首先创建与user表对应的pojo类(Plain Ordinary Java Object),命名为User,并且让数据表中的每一列都与类中的实例变量相对应。根据user表中的列id、name、password、email、last_login,我们相应创建了User类,如下:

package com.loveqh.pojo;

/**
 * Created by WL on 2017-04-23.
 */
public class User {

    private int id;
    private String name;
    private String password;
    private String email;
    private String lastLogin;
}

注意到,由于java一般采用驼峰式命名法,数据表中带下划线的列名last_login对应的是lastLogin属性。

设计完User类的属性之后,我们还需要为每个属性设置settergetter方法,可以使用intellij快捷键Alt+Insert自动添加。添加的代码如下:

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getLastLogin() {
        return lastLogin;
    }

    public void setLastLogin(String lastLogin) {
        this.lastLogin = lastLogin;
    }

为了方便调试中打印对象信息,我们再添加对象的toString方法,如下:

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                ", lastLogin='" + lastLogin + '\'' +
                '}';
    }

第二步,使用mybatis进行数据库操作,可以采用xxxMapper.xmlXxxDao接口的方式,即在XxxDao接口中定义需要的数据操作方法,然后在xxxMapper.xml中使用相应的sql语句实现。

对应地,我们在com.loveqh.dao包中创建UserDao接口,并在mybatis-mapper文件夹下创建userMapper.xml文件。

首先,我们想实现查询总用户数的操作,那么就可以在UserDao接口中添加相应方法:

package com.loveqh.dao;

import com.loveqh.pojo.User;

/**
 * Created by WL on 2017-04-23.
 */
public interface UserDao {

    int getAllUsersCount();

}

对应地,在userMapper.xml中添加相应的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">
<mapper namespace="com.loveqh.dao.UserDao">

    <select id="getAllUsersCount" resultType="int">
        select count(*) from user
    </select>

<mapper>

在该文件中,我们注意两点:
1. mapper节点的namespace属性要对应UserDao接口。
2. select节点的id对应接口中的方法名,然后设置方法相应的参数类型及返回类型。

当然,这个mapper的xml文件需要在mybatis的配置文件中声明才能够使用。打开Configuration.xml文件,在environments节点后面添加以下节点:

    <mappers>
        <mapper resource="mybatis-mapper/userMapper.xml"/>
    </mappers>

为了测试该方法能否成功执行,我们可以在user数据表中先插入一条测试数据,然后使用junit进行单元测试。我们在com.loveqh.test包中新建UserTest测试类,以测试getAllUsersCount方法。代码如下:

package com.loveqh.test;

import com.loveqh.dao.UserDao;
import com.loveqh.pojo.User;
import com.loveqh.util.MyBatisSessionFactory;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Created by WL on 2017-04-23.
 */
public class UserTest {

    private SqlSession session;
    private UserDao userDao;

    @Before
    public void setUp() {
        SqlSessionFactory sessionFactory = MyBatisSessionFactory.getSessionFactory();
        session = sessionFactory.openSession();
        userDao = session.getMapper(UserDao.class);
    }

    @Test
    public void getAllUsersCount() {
        int count = userDao.getAllUsersCount();
        Assert.assertEquals(count, 1);
    }

    @After
    public void tearDown() {
        session.close();
    }
}

增加以下几点说明:
1. 使用mybatis访问数据库,我们需要根据数据库配置文件构造出SqlSessionFactory对象,然后得到SqlSession对象。MyBatisSessionFactory类是为了方便获取SqlSessionFactory对象而创建的工具类,代码稍后贴出。
2. 在使用时需要首先创建SqlSession对象,操作完毕之后就要进行关闭,因此这两步我们分别在@Before@After中进行。
3. 对象userDao不是(也不能)直接由接口创建,而是通过sessiongetMapper方法构造出了的UserDao接口的实例。
4. 在@Test声明的测试方法中,我们调用UserDao接口中的getAllUsersCount方法,由于我们插入了一条测试数据,因此可以使用断言判断总用户数是否为1,如果是,则测试通过。

MyBatisSessionFactory类的代码如下:

package com.loveqh.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

/**
 * Created by WL on 2017-04-23.
 */
public class MyBatisSessionFactory {

    public static SqlSessionFactory getSessionFactory() {
        SqlSessionFactory sessionFactory = null;
        String resource = "Configuration.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }
}

在用户管理中,我们可能会需要根据用户的id来得到用户的详细信息,因此在UserDao类中需要一个findUserById方法,如下:

    User findUserById(int id);

对应地,userMapper.xml中添加相应的sql语句实现:

<select id="findUserById" resultType="com.loveqh.pojo.User" parameterType="int">
        select * from user where id=#{value}
</select>

这里存在两个问题:

  1. 如果很多方法都是返回User对象,那么每个resultType都需要填写完整的包名路径,十分繁琐,也容易出错。不过,当然也有解决办法,就是使用mybatis提供的别名,我们可以再次打开Configuration.xml文件,在environments节点之前添加以下节点:

    <typeAliases>
            <typeAlias type="com.loveqh.pojo.User" alias="User"></typeAlias>
    </typeAliases>

    这样我们便可以把包路径替换成别名User

  2. 前面提到过,由于java的驼峰式命名法,使得对象属性与数据表列名可能不一致,例如这里的lastLoginlast_login。这时,我们可以采用resultMap方式,将数据表的列名与类的属性名进行映射。打开userMapper.xml文件,添加以下节点:

        <resultMap id="userResultMap" type="User">
            <id property="id" column="id"></id>
            <result property="name" column="name"></result>
            <result property="password" column="password"></result>
            <result property="email" column="email"></result>
            <result property="lastLogin" column="last_login"></result>
        </resultMap>

    然后在select节点中使用resultMap替换掉resultType,修改如下:

        <select id="findUserById" resultMap="userResultMap" parameterType="int">
            select * from user where id=#{value}
        </select>

在项目中,我还增加了根据字符串进行模糊查询的操作,由于sql语句需要使用%通配符,所以在字符串拼接时不能使用#{},这里改用${},如下:

    List<User> findUsersLikeName(String name);
    <select id="findUsersLikeName" resultMap="userResultMap" parameterType="String">
        select * from user where name like '%${value}%'
    </select>

注意到这里返回类型仍然是User,当查询结果多于一条时,mybatis会自动帮我们保存到List中,是不是很方便?关于mybatis中#$的区别,可以参考mybatis中的#和$的区别

数据库的基本原子操作是CURD,即创建(Create)、更新(Update)、读取(Retrieve)和删除(Delete)操作。上面只介绍了读取操作,而其他三个操作也类似,只不过它们都会对数据库进行修改,因此在执行完操作后会返回影响的记录数,并且需要执行commit操作。示例如下:

    @Test
    public void deleteUserById() {
        int id = 2;
        int count = userDao.deleteUserById(id);  //返回影响的记录数
        session.commit();  //提交
        Assert.assertEquals(count, 1);
        findAllUsers();
    }

具体的代码实现可以参考提交到github上的本项目,用户管理对应的文件分别是:
- User.java
- UserDao.java
- userMapper.xml
- UserTest.java

类似地,我们可以根据需求实现project和step的数据库逻辑。接下来,我们就可以安心进行界面实现了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要创建一个快递员登录的页面,包括用户名和密码的输入框,以及登录按钮。在SpringMVC中,可以使用Controller来处理用户的请求。 1. 创建一个CourierController类,使用@Controller注解标识该类为Controller。 ``` @Controller @RequestMapping("/courier") public class CourierController { //TODO } ``` 2. 在CourierController类中,创建一个login方法,使用@RequestMapping注解标识该方法为处理/login请求的方法。该方法接收一个Courier对象作为参数,包含用户名和密码信息。 ``` @RequestMapping("/login") public String login(Courier courier, Model model) { //TODO return "courier"; } ``` 3. 在login方法中,使用Mybatis查询数据库,判断该用户是否存在。 ``` Courier existCourier = courierService.findByUsernameAndPassword(courier); if (existCourier == null) { model.addAttribute("error", "用户名或密码错误"); return "login"; } ``` 4. 如果用户存在,则跳转到代取单页面,同时将当前用户的代取单数据查询出来,显示在页面上。 ``` List<Order> orderList = orderService.findByCourierId(existCourier.getId()); model.addAttribute("orderList", orderList); return "courier"; ``` 5. 在代取单页面上,可以使用Thymeleaf模板引擎展示数据。 ``` <table> <tr> <th>订单号</th> <th>收货人</th> <th>电话</th> <th>地址</th> </tr> <tr th:each="order : ${orderList}"> <td th:text="${order.orderNumber}"></td> <td th:text="${order.consigneeName}"></td> <td th:text="${order.consigneePhone}"></td> <td th:text="${order.consigneeAddress}"></td> </tr> </table> ``` 完整的CourierController类代码如下: ``` @Controller @RequestMapping("/courier") public class CourierController { @Autowired private CourierService courierService; @Autowired private OrderService orderService; @RequestMapping("/login") public String login(Courier courier, Model model) { Courier existCourier = courierService.findByUsernameAndPassword(courier); if (existCourier == null) { model.addAttribute("error", "用户名或密码错误"); return "login"; } List<Order> orderList = orderService.findByCourierId(existCourier.getId()); model.addAttribute("orderList", orderList); return "courier"; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值