• MyBatis之基于XML的增删改查


    这里先吐槽下,写的半天的东西,IE浏览器弹出调试窗口导致写的东西全部没保存,搞得我还要重新用谷歌写,思路全没了,fuck.

    前面学习了下spring的DAO层,说起DAO层,那ORM肯定是少不了的,ORM的框架也比较多,做C#的时候用EF,现在Java的话流行SSM,所以就想着学习下Mybatis,参考这EF的几篇博客,打算MyBatis这块也系统的学习下,主要涉及单表增删改查、属性与列名映射、表之间关系映射、事务与锁、存储过程、缓存、Spring与MyBatis结合这几块,可能随着深入的学习还会有慢慢补充。今天主要学习单表的增删改查。

    一、准备

    1.引入库

    这里新建了一个maven的project,既然是MyBatis,肯定少不了pom.xml中引入它,同时与数据库交换,这里用的是mysql,所以也少不了mysql连接库。

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>Cuiyw</groupId>
      <artifactId>MyBatisDemo</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>
    
      <name>MyBatisDemo</name>
      <url>http://maven.apache.org</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
    
      <dependencies>
      <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.1</version>
        </dependency>
      <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    </project>
    View Code

    2.创建Model

    既然是ORM,那肯定也得有对象,所以创建model.这里创建了一个简单的User类。

    package Cuiyw.MyBatis.Model;
    
    public class User {
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return  "User [id=" + Id + ", name=" + Name + ", age=" + Age + "]";
    
        }
        public int getId() {
            return Id;
        }
        public void setId(int id) {
            Id = id;
        }
        public String getName() {
            return Name;
        }
        public void setName(String name) {
            Name = name;
        }
        public int getAge() {
            return Age;
        }
        public void setAge(int age) {
            Age = age;
        }
        private int Id;
        private String Name;
        private int Age;
        
        
        
        
    }
    View Code

    3.创建数据库表

    ORM要做持久化,那少不了数据库,这里创建了MyBatis数据库,并增加了user表。

    CREATE DATABASE `mybatis` /*!40100 DEFAULT CHARACTER SET utf8 */;
    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `NAME` varchar(20) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    View Code

    二、MyBatis使用

    前面算是把准备工作做完了,那下面就是开始MyBatis的使用了,这里主要是单表的增删改查。处理增删改查的时候首先要解决的是怎么把User类与数据库中的user表对应起来,对象关系映射那肯定得有个映射才对。于是乎UserMapper出现了,用它来映射数据库处理得一些操作。

    <?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
    例如namespace="Cuiyw.MyBatis.DBMapping.UserMapper"就是Cuiyw.MyBatis.DBMapping(包名)+UserMapper(UserMapper.xml文件去除后缀)
     -->
    <mapper namespace="Cuiyw.MyBatis.DBMapping.UserMapper">
        <!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复
        使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型
        resultType="Cuiyw.MyBatis.Model.User"就表示将查询结果封装成一个User类的对象返回
        User类就是user表所对应的实体类
        -->
        <!-- 
            根据id查询得到一个user对象
         -->
        <select id="getUser" parameterType="int" 
            resultType="Cuiyw.MyBatis.Model.User">
            select * from user where id=#{id}
        </select>
        <select id="getUserList" resultType="Cuiyw.MyBatis.Model.User">
            select * from user
        </select>
        <insert id="addUser" parameterType="Cuiyw.MyBatis.Model.User">
          <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
              SELECT LAST_INSERT_ID()
          </selectKey>
            insert into user(name,age) values (#{name},#{age})
        </insert>
        <delete id="deleteUserById" parameterType="int">
            delete from user where id=#{id}
        </delete>
        <update id="updateUser" parameterType="Cuiyw.MyBatis.Model.User">
            update user set name=#{name},age=#{age} where id=#{id}
        </update>
    </mapper>
    View Code

    上面UserMapper.xml中配置了对user表的增删改查,有了UserMapper.xml,算是项目中与表user扯上关系了,通过传入传出参数也与User类扯上了关系,不过还差一步,就是目前并不知道是映射到哪个数据库,地址多少,所以还需要一个数据库配置文件。这里要提下insert,其他几个都是直接一条sql,而insert与其他不一样,主要是为了演示新增返回主键值。

    <?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="development">
            <environment id="development">
                <transactionManager type="JDBC" />
                <!-- 配置数据库连接信息 -->
                <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="123456" />
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!-- 注册UserMapper.xml文件, 
            UserMapper.xml位于Cuiyw.MyBatis.DBMapping这个包下,所以resource写成meCuiyw/MyBatis/DBMapping/UserMapper.xml-->
            <mapper resource="Cuiyw/MyBatis/DBMapping/UserMapper.xml"/>
        </mappers> 
    </configuration>
    View Code

     1.新增

    先了解下insert的属性。

    parameterType:入参的全限定类名或类型别名
    keyColumn:设置数据表自动生成的主键名。对特定数据库(如PostgreSQL),若自动生成的主键不是第一个字段则必须设置
    keyProperty:默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中
    useGeneratedKeys:取值范围true|false(默认值),设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。MySQL和SQLServer执auto-generated key field,因此当数据库设置好自增长主键后,可通过JDBC的getGeneratedKeys方法获取。但像Oralce等不支持auto-generated key field的数据库就不能用这种方法获取主键了
    statementType:取值范围STATEMENT,PREPARED(默认值),CALLABLE
    flushCache:取值范围true(默认值)|false,设置执行该操作后是否会清空二级缓存和本地缓存
    timeout:默认为unset(依赖jdbc驱动器的设置),设置执行该操作的最大时限,超时将抛异常
    databaseId:取值范围oracle|mysql等,表示数据库厂家,元素内部可通过`<if test="_databaseId = 'oracle'">`来为特定数据库指定不同的sql语句

    这里有两个知识点,第一个是commit()提交的问题。我刚开始是按照下面写的.

            //mybatis的配置文件
            String resource = "DBConfig.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
            Reader reader = Resources.getResourceAsReader(resource); 
            //构建sqlSession的工厂
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建能执行映射文件中sql的sqlSession
            SqlSession session = sessionFactory.openSession();
            
            String statement="Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
            User user=new User();
            user.setName("Cuiyw");
            user.setAge(27);
            int result=session.insert(statement, user);
            session.close();
            System.out.println(user.getId());
    View Code

    在main中运行上面的代码,也能打印出返回的主键值,但当我打开数据库表查询时并没有找到数据,当时觉得时没刷新,刷新了好几变还是没有,又去百度了下,参考其他博客发现时自己少了session.commit(),增加上之后发现数据库也有值了。

            //mybatis的配置文件
            String resource = "DBConfig.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
            Reader reader = Resources.getResourceAsReader(resource); 
            //构建sqlSession的工厂
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建能执行映射文件中sql的sqlSession
            SqlSession session = sessionFactory.openSession();
            
            String statement="Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
            User user=new User();
            user.setName("Cuiyw");
            user.setAge(27);
            int result=session.insert(statement, user);
            session.commit();
            session.close();
            System.out.println(user.getId());
    View Code

    但有搜了几篇文章,发现有的insert时也没调用commit(),刚开始怀疑是不是代码遗漏了,还看了下面的评论,怎么也没人说,这不科学啊,于是有继续百度查找原因,终于还是找到了,原来SqlSessionFactory的openSession中有个是带布尔值参数的方法autoCommit,默认是false,代表不是自定提交,所以当我创建session时传入true后,也不用再写commit()方法了。

            //mybatis的配置文件
            String resource = "DBConfig.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
            Reader reader = Resources.getResourceAsReader(resource); 
            //构建sqlSession的工厂
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建能执行映射文件中sql的sqlSession
            SqlSession session = sessionFactory.openSession(true);
            
            String statement="Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
            User user=new User();
            user.setName("Cuiyw");
            user.setAge(27);
            int result=session.insert(statement, user);
            //session.commit();
            session.close();
            System.out.println(user.getId());
    View Code

     第二个是获取主键的问题。这个也是之前做C#的时候遇到过,所以想着看下MyBatis是怎么实现,除了除了上面使用selectKey的方式还可以在insert中直接配置keyProperty和useGeneratedKeys。

    selectKey常用属性如下:

    作用:在insert元素和update元素中插入查询语句。

    keyProperty:默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中

    resultType:keyPropety所指向的属性类全限定类名或类型别名

    order属性:取值范围BEFORE|AFTER,指定是在insert语句前还是后执行selectKey操作

    statementType:取值范围STATEMENT,PREPARED(默认值),CALLABLE

    2.删改查

    其实这几个是比较类似的,都是SqlSession中调用对应的方法。下面是先增加一个user,然后修改,遍历和删除

        public static void main( String[] args ) throws IOException
        {
            //mybatis的配置文件
            String resource = "DBConfig.xml";
            //使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
            Reader reader = Resources.getResourceAsReader(resource); 
            //构建sqlSession的工厂
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //创建能执行映射文件中sql的sqlSession
            SqlSession session = sessionFactory.openSession(true);
            System.out.println("新增");
            String statement="Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
            User user=new User();
            user.setName("Cuiyw");
            user.setAge(27);
            int result=session.insert(statement, user);
            //session.commit();
            //session.close();
            System.out.println(user.getId());
            System.out.println("查询单个");
             statement="Cuiyw.MyBatis.DBMapping.UserMapper.getUser";
             user=session.selectOne(statement, user.getId());
             //session.close();
             System.out.println(user.toString());
             System.out.println("修改");
             statement="Cuiyw.MyBatis.DBMapping.UserMapper.updateUser";
             user.setName("Cuiye Update");
             result=session.update(statement, user);
    
             System.out.println("遍历所有");
             statement="Cuiyw.MyBatis.DBMapping.UserMapper.getUserList";
             List<User> users=session.selectList(statement);
            // session.close();
             for(int i=0;i<users.size();i++)
             {
                 System.out.println(users.get(i));
             }
             session.commit();
             System.out.println("删除");
            statement="Cuiyw.MyBatis.DBMapping.UserMapper.deleteUserById";
          
            session.delete(statement,user.getId());
            System.out.println("删除之后遍历所有");
            statement="Cuiyw.MyBatis.DBMapping.UserMapper.getUserList";
            users=session.selectList(statement);
            session.close();
            for(int i=0;i<users.size();i++)
            {
                System.out.println(users.get(i));
            }
    
        }
    View Code

  • 相关阅读:
    Redis数据库概述
    分布式爬虫(一)------------------分布式爬虫概述
    Spark环境搭建(五)-----------Spark生态圈概述与Hadoop对比
    错误解决记录------------rhel安装Mysql软件包依赖 mariadb组件
    rhel 7安装Mysql
    Linux虚拟机搭建本地yum源
    rhel配置网络yum源
    Spark环境搭建(四)-----------数据仓库Hive环境搭建
    冲销会计凭证:FBRP与FB08的区别
    xk01创建供应商保存的时候,提示错误“科目800001已经存在”
  • 原文地址:https://www.cnblogs.com/5ishare/p/8320691.html
Copyright © 2020-2023  润新知