Mybatis初级应用——实现增删查改

转载注明出处


前两天学习了mybatis连接数据库,实现增删查改,和前面的文章JDBC实现增删查改有异曲同工之妙,在此记录,遗忘的时候翻一翻。

首先,还是建项目,什么项目?maven项目,不讲了,去翻前面的文章。

直接贴项目结构



然后是导入jar包

mybatis包是一定要的;mqsql-connector-java也是必须的;junit包就更不用说了;还有1.8的包就不提了,建完项目就有。


这里我使用了mybatis的两种方法,一种就是和JDBC差不多的,利用dao层和它的实现类来完成增删查改。不过多讲解,直接贴代码。

记得先在数据库建表!


一、DAO层实现


User.java

package mybatis.po;

import java.sql.Date;

/**
 * Created by Administrator on 2017/07/07.
 */
public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

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

    public User(Integer id,String username, Date birthday, String sex, String address) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
    }

    public User(String username, Date birthday, String sex, String address) {
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

然后是

UserDao.java

package mybatis.po;

import java.util.List;

/**
 * Created by Administrator on 2017/07/07.
 */
public interface UserDao {
    //根据id查询用户信息
    public User findUserById(int id) throws Exception;
    //根据用户名模糊查询
    public List<User> findUserByName(String name) throws Exception;
    //添加用户信息
    public void insertUser(User user) throws Exception;
    //删除用户信息
    public void deleteUser(int id) throws Exception;
    //更新用户信息
    public void updateUser(User user) throws Exception;
}

再然后是

UserDaoImpl.java

package mybatis.po;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

/**
 * Created by Administrator on 2017/07/07.
 */
public class UserDaoImpl implements UserDao{
    private SqlSessionFactory sqlSessionFactory;
    //需要向dao实现类中注入SqlSessionFactory,由于没和Spring整合,这里通过构造函数注入
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User findUserById(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.findUserById", id);
        //释放资源
        sqlSession.close();
        return user;
    }

    @Override
    public List<User> findUserByName(String name) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> list = sqlSession.selectList("test.findUserByName", name);
        //释放资源
        sqlSession.close();
        return list;
    }

    @Override
    public void insertUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("test.insertUser", user);
        sqlSession.commit();//执行插入要先commit
        sqlSession.close();
    }

    @Override
    public void deleteUser(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("test.deleteUser", id);
        sqlSession.commit();//执行插入要先commit
        sqlSession.close();
    }

    @Override
    public void updateUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.update("test.updateUser", user);
        sqlSession.commit();//执行插入要先commit
        sqlSession.close();
    }

}

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

<mapper namespace="test">

    <!-- 需求:通过id查询用户 -->
    <select id="findUserById" parameterType="int" resultType="mybatis.po.User">
        select * from user where id = #{id}
    </select>

    <!-- 根据用户名称模糊查询用户信息,可能返回多条 -->
    <select id="findUserByName" parameterType="java.lang.String" resultType="mybatis.po.User">
        select * from user where username like '%${value}%'
        <!--
        ${}:表示拼接sql串,将接收到的参数的内容不加任何的修饰拼接在sql中,${}中只能使用value,
        但是使用${}来拼接sql,可能会引起sql注入,所以不建议使用这种方法。
        -->
    </select>

    <!-- 添加用户 -->
    <insert id="insertUser" parameterType="mybatis.po.User">
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})

        <!-- 将插入数据的主键返回,返回到user对象中 -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select last_insert_id()
        </selectKey>

        <!--
        <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
            select uuid()
        </selectKey>
         -->

        <!--
        1 <insert>标签:用于执行数据库查询的,所有关于查询的都使用该标签。
        2 parameterType:要传入一个具体的pojo(包括用户信息)
        3 #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值。
        4 <selectKey>标签:用来返回插入数据的主键的,实际中如果有获得主键的需要就可以使用它。
        5 select last_insert_id():是sql函数,表示得到刚刚insert进去记录的主键值,只适用于自增主键。
        6 keyProperty:表示将查询到主键值设置到上面parameterType指定的对象的哪个属性。
        7 order:表示select last_insert_id()的执行顺序,是相对于insert语句来说的。
        8 resultType:表示select last_insert_id()的结果类型。
        -->
    </insert>

    <!-- 删除用户 -->
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id=#{id}
    </delete>

    <!-- 更新用户 -->
    <update id="updateUser" parameterType="mybatis.po.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
</mapper>

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

    </typeAliases>
    <!-- 和Spring整合后environment配置都会被干掉 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理,目前由mybatis来管理 -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池,目前由mybatis来管理 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
                <property name="username" value="root" />
                <property name="password" value="yubotao9527" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="User.xml" />
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

log4j.properties日志生成文件

# Global logging configuration
# developer-->DEBUG  productor-->INFO or ERROR
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# 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

最后的测试

UserDaoImplTest.java

import mapper.UserMapper;
import mybatis.po.User;
import mybatis.po.UserDao;
import mybatis.po.UserDaoImpl;
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.Before;
import org.junit.Test;

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

/**
 * Created by Administrator on 2017/07/07.
 */
public class UserDaoImplTest {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void setUp() throws Exception {
        //创建sqlSessionFactory
        String resource = "SqlMapConfig.xml"; //mybatis配置文件

        //得到配置文件的流
        InputStream inputStream = Resources.getResourceAsStream(resource);

        //创建会话工厂SqlSessionFactory,要传入mybaits的配置文件的流
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void testFindUserById() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findUserById(1);
        System.out.println(user);
    }

    @Test
    public void testFindUserByName() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> list = userMapper.findUserByName("倪升武");
        sqlSession.close();
        System.out.println(list);
    }
}


到此,使用DAO层完成mybatis实现增删查改就完成了


接下来讲第二种方法

二、Mapper

User.java

同上



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

<mapper namespace="mapper.UserMapper">

    <!-- 需求:通过id查询用户 -->
    <select id="findUserById" parameterType="int" resultType="mybatis.po.User">
        select * from user where id = #{id}
    </select>

    <!-- 根据用户名称模糊查询用户信息,可能返回多条 -->
    <select id="findUserByName" parameterType="java.lang.String" resultType="mybatis.po.User">
        select * from user where username like '%${value}%'
        <!--
        ${}:表示拼接sql串,将接收到的参数的内容不加任何的修饰拼接在sql中,${}中只能使用value,
        但是使用${}来拼接sql,可能会引起sql注入,所以不建议使用这种方法。
        -->
    </select>

    <!-- 添加用户 -->
    <insert id="insertUser" parameterType="mybatis.po.User">
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})

        <!-- 将插入数据的主键返回,返回到user对象中 -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select last_insert_id()
        </selectKey>

        <!--
        <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
            select uuid()
        </selectKey>
         -->

        <!--
        1 <insert>标签:用于执行数据库查询的,所有关于查询的都使用该标签。
        2 parameterType:要传入一个具体的pojo(包括用户信息)
        3 #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值。
        4 <selectKey>标签:用来返回插入数据的主键的,实际中如果有获得主键的需要就可以使用它。
        5 select last_insert_id():是sql函数,表示得到刚刚insert进去记录的主键值,只适用于自增主键。
        6 keyProperty:表示将查询到主键值设置到上面parameterType指定的对象的哪个属性。
        7 order:表示select last_insert_id()的执行顺序,是相对于insert语句来说的。
        8 resultType:表示select last_insert_id()的结果类型。
        -->
    </insert>

    <!-- 删除用户 -->
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id=#{id}
    </delete>

    <!-- 更新用户 -->
    <update id="updateUser" parameterType="mybatis.po.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
</mapper>

主配置文件Configure.xml

这里和上面的一样

主配置文件中就不需要UserMapper.xml的关联了。



最后是测试

MybatisFirst.java

import mybatis.po.User;
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 java.io.IOException;
import java.io.InputStream;
import java.sql.Date;
import java.util.List;

/**
 * Created by Administrator on 2017/07/07.
 */
public class MybatisFirst {
    //因为接下来的测试代码中,获取sqlSession这部分都相同,所以抽取成一个方法
    public SqlSession getSession() throws IOException {

        String resource = "SqlMapConfig.xml"; //mybatis配置文件

        //得到配置文件的流
        InputStream inputStream = Resources.getResourceAsStream(resource);

        //创建会话工厂SqlSessionFactory,要传入mybaits的配置文件的流
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //通过工厂得到SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        return sqlSession;
    }

    //根据id查询用户的信息,得到一条记录的结果
    @Test
    public void findUserById() throws IOException {

        SqlSession sqlSession = getSession(); //调用上面的方法获取sqlSession

        //通过SqlSession操作数据库
        //第一个参数:映射文件中statement的id,= namespace + statement的id
        //第二个参数:指定和映射文件中所匹配的parameterType类型的参数  
        //selectOne表示查询出一条记录进行映射
        User user = sqlSession.selectOne("test.findUserById", 1);

        System.out.println(user);

        //释放资源,最好放在finally中,这里只是测试程序,就不弄了
        sqlSession.close();
    }

    //根据用户名称模糊查询用户列表
    @Test
    public void findUserByName() throws IOException {

        SqlSession sqlSession = getSession();

        //selectList表示查询出一个列表(多条记录)进行映射
        List<User> list = sqlSession.selectList("test.findUserByName", "张三");

        System.out.println(list);

        //释放资源,最好放在finally中,这里只是测试程序,就不弄了
        sqlSession.close();
    }

    //添加用户信息
    @Test
    public void insertUser() throws IOException {

        SqlSession sqlSession = getSession();

        User user = new User("倪升武", new Date(1995,07,02), "男", "同济大学");

        sqlSession.insert("test.insertUser", user); //添加一项

        //提交事务
        sqlSession.commit();

        System.out.println(user.getId()); //获取刚刚添加的id

        //释放资源,最好放在finally中,这里只是测试程序,就不弄了
        sqlSession.close();
    }

    //删除用户信息
    @Test
    public void deleteUser() throws IOException {

        SqlSession sqlSession = getSession();

        //传入id,删除用户
        sqlSession.delete("test.deleteUser", 3);

        //提交事务
        sqlSession.commit();

        //释放资源,最好放在finally中,这里只是测试程序,就不弄了
        sqlSession.close();
    }

    //更新用户信息
    @Test
    public void updateUser() throws IOException {

        SqlSession sqlSession = getSession();

        User user = new User("倪升武", new Date(0,0,0), "男", "同济大学");
        user.setId(2);

        //更新用户
        sqlSession.update("test.updateUser", user);

        //提交事务
        sqlSession.commit();

        //释放资源,最好放在finally中,这里只是测试程序,就不弄了
        sqlSession.close();
    }
}

最后,完成这些结果后,我们回顾一下

这里面出现了许多没见过的东西,比如:

SqlSession和SqlSessionFactory

这个SQLSession对应一次数据库的对话,也就是说你的增删查改语句都是通过它来传递给数据库的;是不是感觉和前面的PreparedStatement有点像?反正我感觉像!

SqlSessionFactory就是SqlSession的工厂,通过SqlSessionFactory.openSession()方法来创建SqlSession对象。


其他的地方都有相应注解,就不一一解释了。


三、Annotation注解

这里的代码是另一个项目的,但是和前面的东西差不多,改一下即可
和Mapper类似,需要一个主配置文件Configure.xml
需要创建一个注解接口来代替.xml的SQL语句配置文件
如下
package dao;

import domain.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

/**
 * Created by Administrator on 2017/07/19.
 */
public interface Annotation {
    @Select("select * from businesstable where ID = #{ID}")
    public Student selectById(Integer ID);

    @Delete(" delete from businesstable where ID = #{ID}")
    public void deleteById(Integer ID);

    @Insert(" insert into businesstable(SName,QQ,Style,Time,School,SNumber,Link,Dream,FBro,YBro,WhereKnow,create_at)\n" +
            "        values(#{SName},#{QQ},#{Style},#{Time},#{School},#{SNumber},#{Link},#{Dream},#{FBro},#{YBro},#{WhereKnow},#{create_at})")
    public void insertStu(Student stu);

    @Update("update businesstable set SName=#{SName},QQ=#{QQ},Style=#{Style},Time=#{Time},School=#{School},SNumber=#{SNumber},\n" +
            "        Link=#{Link},Dream=#{Dream},FBro=#{FBro},YBro=#{YBro},WhereKnow=#{WhereKnow},update_at=#{update_at} where ID=#{ID}")
    public void updateStu(Student stu);
}
其他就不变,注解的方法就是这个样子
然后给出该接口的测试类
import dao.Annotation;
import domain.Student;
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 java.io.IOException;
import java.io.InputStream;

/**
 * Created by Administrator on 2017/07/19.
 */
public class AnnotationTest {
    public SqlSession getSession() throws IOException {
        String resource = "Configure.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }
    @Test
    public void selectStudent() throws IOException {
        SqlSession sqlSession = getSession();
        Annotation ant = sqlSession.getMapper(Annotation.class);
        Student stu = ant.selectById(2);
        System.out.println(stu);
        sqlSession.close();

    }

    @Test
    public void insertStudent() throws IOException{
        SqlSession sqlSession = getSession();
        Student stu = new Student("s",22,"dsfa","20170705",null,null,
                null,null,null,null,null,null,20170707,null);
        Annotation ant = sqlSession.getMapper(Annotation.class);
        ant.insertStu(stu);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void deleteStudent() throws  IOException{
        SqlSession sqlSession = getSession();
        Annotation ant = sqlSession.getMapper(Annotation.class);
        ant.deleteById(18);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void updateStudent() throws IOException{
        SqlSession sqlSession = getSession();
        Student stu = new Student("s",22,"dsfa","20170705",null,null,
                null,null,null,null,null,null,null,20170707);
        stu.setID(3);
        Annotation ant = sqlSession.getMapper(Annotation.class);
        ant.updateStu(stu);
        sqlSession.commit();
        sqlSession.close();
    }
}

我们可以看到,注解和mapper方式是很接近的,或者说是一样的(不过就是配置文件和接口类做了替换而已)


最后总结:mybatis就是讲sql的增删查改语句配置到.xml文件(或注解接口)中,这就是和JDBC比较的优势了,不必在代码实现的时候考虑如何实现这些sql语句,还要考虑连接等等。总的来说,就是简单了,改sql语句直接去配置文件(或注解接口)中改就好了!


log4j.properties文件就是个打日志的,原理我也不是很清楚,百度下把,可能以后会更和它相关的文章。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值