您的位置:首页 > 其它

Mybatis原生dao开发方法实现增删改查

2017-11-19 10:16 579 查看

思路

程序员需要写 dao 接口和 dao 实现类

需要向 dao 实现类中注入 SqlSessionFactory,在方法体内通过 SqlSessionFactory

 

项目准备

1、项目结构

① 新建 Java 项目

② 在 src 下新建 com.liuyanzhao.mybatis.po 包(用来放持久化类,和数据库对应)

和 com.liuyanzhao.mybatis.dao 包 (用来放 CURD 实现代码)

③ 在 src 下新建(或者拷贝)Configuration.xml (mybatis全局配置文件)和 userDao.xml (映射文件)

 

2、导入 两个必备的 jar 包

mysql-jdbc 驱动包: mysql-connector-java-5.1.41-bin.jar
mybatis 包:mybatis-3.4.4.jar
在项目中新建一个 lib 目录,将两个包拷贝到 lib 中,然后将两个包加入环境(build path)中

 

3、新建数据库和数据表

我这里在本地测试,主机 localhost,数据库用户名root,密码为空

① 新建数据库:mybatis

② 新建数据表:user表

表结构如下,五个字段(id,username,gender,birthday,address)



 

代码实现

1、Configuration.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>

  <!-- 和Spring整合后,environments配置将废除-->
  <environments default="development">
    <environment id="development">
      <!--使用JDBC事务管理,事务控制由mybatis-->
      <transactionManager type="JDBC">
        <property name="" value=""/>
      </transactionManager>
      <!--数据库连接池-->
      <dataSource type="UNPOOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
      </dataSource>
    </environment>
  </environments>

  <!--加载映射文件-->
  <mappers>
    <mapper resource="userDao.xml" />
  </mappers>

</configuration>

 

2、userDao.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">

<!--namespace命名空间,作用是对sql进行分类话管理,理解sql,理解sql隔离
    注意:使用mapper代理方法开发,namespace有着特殊的作用
-->

<mapper namespace="test">
    <!--在映射文件中配置很多sql语句-->
    <!--
    id:表示映射文件中的sql
    将sql语句封装到mappedStatement对象中,所以称id为Statement的id
    parameterType:指定输入参数的类型
    resultType:指定就是单条记录所映射的java对象类型
    #{}表示占位符,相当于?
    #{id} 其中id表示接受输入的参数,参数名就是id,如果输入的参数是简单类型,#{}中的参数可以任意,可以value或者其他名称
    ${}:表示拼接sql串,将接受到的参数的内容不加任何修饰直接拼接在sql中
    ${}安全隐患:使用${}拼接sql,引起sql注入
    ${value}:接受输入参数的内容,如果传入类型是简单类型,${}中只有使用value

    -->
    <select id="findUserById" parameterType="int" resultType="com.liuyanzhao.mybatis.po.User">
        SELECT * FROM user WHERE id=#{value}
    </select>

    <!--根据用户名称模糊查询,可能返回多条-->
    <select id="findUserByName" parameterType="java.lang.String" resultType="com.liuyanzhao.mybatis.po.User">
        SELECT * FROM user WHERE username LIKE '%${value}%'
    </select>

    <!--#{}指定pojo的属性名,接收到pojo对象的属性值,Mybatis通过OGNL获取对象的属性值-->
    <!--添加用户-->
    <insert id="insertUser" parameterType="com.liuyanzhao.mybatis.po.User">

     <!--
        将插入数据的主键返回,返回到user对象中
        SELECT LAST_INSERT_ID(); 得到insert进去的主键值,只适用自增主键
    -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT INTO user(username,birthday,gender,address) VALUE(#{username},#{birthday},#{gender},#{address})
    </insert>

    <!--删除用户,根据id-->
    <delete id="deleteUserById" parameterType="java.lang.Integer">
        DELETE FROM user WHERE id=#{id}
    </delete>

    <!--更新用户,根据id
    需要传入用户信息
    parameterType指定user对象,包括id和更新信息。注意:id必须存在
    #{id}:从输入的user对象中获取id的属性值

    -->
    <update id="updateUserById" parameterType="com.liuyanzhao.mybatis.po.User">
        UPDATE user SET username=#{username},birthday=#{birthday},gender=#{gender},address=#{address} WHERE id=#{id}
    </update>

</mapper>

 

3、UserDao.java   dao接口

package com.liuyanzhao.mybatis.dao;

import com.liuyanzhao.mybatis.po.User;

import java.util.List;

/**
 * Created by 言曌 on 2017/8/10.
 */
public interface UserDao {
    //根据id查询用户信息
    public User findUserById(int id) throws Exception;

    //根据username查询用户信息
    public List<User> findUserByName(String username) throws Exception;

    //添加用户信息
    public void insertUser(User user) throws Exception;

    //删除用户信息
    public void deleteUser(int id) throws Exception;

    //更新用户信息
    public void updateUser(User user) throws Exception;

}

 

4、UserDaoImpl.java  dao接口的实现类

package com.liuyanzhao.mybatis.dao;

import com.liuyanzhao.mybatis.po.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

/**
 * Created by 言曌 on 2017/8/10.
 */
public class UserDaoImpl implements UserDao{
    //向dao实现类注入SqlSessionFactory
    //这里通过构造方法注入
    private SqlSessionFactory sqlSessionFactory;
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User findUserById(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
         //执行查询操作,赋值给user对象
        User user = sqlSession.selectOne("test.findUserById",id);
        //释放资源
        sqlSession.close();
        return user;
    }

    @Override
    public List<User> findUserByName(String username) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行查询操作,存储到list中
        List<User> list = sqlSession.selectList("test.findUserByName",username);
        //释放资源
        sqlSession.close();
        return list;
    }

    @Override
    public void insertUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行插入操作
        sqlSession.insert("test.insertUser",user);
        //提交事务
        sqlSession.commit();
        //释放资源
        sqlSession.close();
    }

    @Override
    public void deleteUser(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行删除操作
        sqlSession.delete("test.deleteUserById",id);
        //提交事务
        sqlSession.commit();
        //释放资源
        sqlSession.close();
    }

    @Override
    public void updateUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行更新操作
        sqlSession.update("test.updateUserById",user);
        //提交事务
        sqlSession.commit();
        //释放资源
        sqlSession.close();
    }
}

 

5、测试类 UserDaoImplTest.java

package com.liuyanzhao.mybatis.test;

import com.liuyanzhao.mybatis.dao.UserDao;
import com.liuyanzhao.mybatis.dao.UserDaoImpl;
import com.liuyanzhao.mybatis.po.User;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * Created by Liu_Yanzhao on 2017/8/10.
 */
public class UserDaoImplTest {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        String resource = "Configuration.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder()
            .build(inputStream);
    }

    //测试,根据id查询用户
    @Test
    public void testFindUserById() throws Exception {
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        User user = userDao.findUserById(10);
        System.out.println(user);
    }

    //测试,根据username查询用户
    @Test
    public void testFindUserByName() throws Exception {
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        List<User> list = userDao.findUserByName("小明");
        System.out.println(list);
    }

    //测试,添加信息
    @Test
    public void testInsertUser() throws Exception {
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        //创建User对象,存储用户信息
        User user = new User();
        user.setUsername("龙小云");
        user.setGender("女");
        user.setBirthday(new Date());
        user.setAddress("江西南昌");
        //执行添加操作
        userDao.insertUser(user);
    }

    //测试,删除信息
    @Test
    public void testDeleteUserByUser() throws Exception {
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        //执行删除操作
        userDao.deleteUser(10);
    }

    //测试,更新用户信息
    @Test
    public void testUpdateUser() throws Exception {
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        //创建User对象,存储用户信息
        User user = new User();
        user.setId(8);
        user.setUsername("令小冲");
        user.setGender("男");
        user.setBirthday(new Date());
        user.setAddress("华山");
        //执行更新操作
        userDao.updateUser(user);
    }

}

 

总结原生 dao 开发问题

1、dao 接口实现类方法中存在大量模板方法,设想是否能将这些代码提取出来,从而减少程序员的工作量。

 

2、调用 sqlSession 方法时将 statement 的 id 硬编码(硬编码是指将可变变量用一个固定值来代替的方法)了。

如:

User user = sqlSession.selectOne("test.findUserById",id);

在根据id查询用户的方法里,这句里的 "test.findUserById" 是一个固定的值。

 

3、调用 sqlSession 方法时传入的变量,由于 sqlSession 方法使用泛型,即使变量类型传入错误,在编译阶段也不会报错,不利于 程序员开发

如:

User user = sqlSession.selectOne("test.findUserById",id);

还是 2  中的那一行代码,id 处接受一个对象值,但是我们要求是 一个整数,所以当我输入其他的,如字符串类型时,编译时不会报错,运行时才会有。

 

本文链接:https://liuyanzhao.com/5782.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: