美文网首页程序员Java编程
mybatis入门之增删改查

mybatis入门之增删改查

作者: Eugene1024 | 来源:发表于2018-12-04 17:46 被阅读8次

    一、原生态JDBC程序中问题的总结

    1.1 JDBC程序

    需求:使用jdbc查询mysql数据库中用户的记录
    Statement:向数据库发送回个sql语句
    预编译Statement: 好处:提高数据库性能
    预编译Statement向数据库发送一个sql语句,数据库执行后将执行结果存放在缓存中,下次再执行相同的语句会直接从缓存中读取
    1、 加载数据库驱动
    2、 创建并获取数据库链接
    3、 创建jdbc statement对象
    4、 设置sql语句
    5、 设置sql语句中的参数(使用preparedStatement)
    6、 通过statement执行sql并获取结果
    7、 对sql执行结果进行解析处理
    8、 释放资源(resultSet、preparedstatement、connection)

    public class JDBCTest {
        public static void main(String[] args) {
            Connection connection = null;
            // 预编译的Statement,使用预编译的Statement提高数据库性能
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
            try {
                // 加载数据库驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 通过驱动管理类获取数据库链接
                connection = DriverManager.getConnection(
                                "jdbc:mysql://localhost:3306/test?characterEncoding=utf-8",
                                "root", "root");
                // 定义sql语句 ?表示占位符
                String sql = "select * from t_user where username = ?";
                //获取预处理statement
                preparedStatement = connection.prepareStatement(sql);
                // 设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
                preparedStatement.setString(1, "王五");
                // 向数据库发出sql执行查询,查询出结果集
                resultSet = preparedStatement.executeQuery();
                // 遍历查询结果集
                while (resultSet.next()) {
                    System.out.println(resultSet.getString("id") + "  "+ resultSet.getString("username"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //释放资源
                if (resultSet != null) {
                    try {
                        resultSet.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (preparedStatement != null) {
                    try {
                        preparedStatement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    1.2问题总结:

    上面代码的问题总结

    1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响 数据库性能。
    设想:使用数据库连接池管理数据库连接。

    2、将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。
    设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。

    3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。
    设想:将sql语句及占位符号和参数全部配置在xml中。

    4、从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。
    设想:将查询的结果集,自动映射成java对象。

    二、mybatis原理

    2.1 mybatis是什么?

    mybatis是一个持久层的框架,是apache下的顶级项目。
    mybatis托管到goolecode下,再后来托管到github下(https://github.com/mybatis/mybatis-3/releases)。

    mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。

    mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)

    2.2 mybatis框架

    aaa.png

    1、 mybatis配置
    SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
    mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

    2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
    3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
    4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
    5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
    6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
    7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

    三、入门程序之mybatis增删改查

    3.1 需求

    根据用户id(主键)查询用户信息
    根据用户名称模糊查询用户信息
    添加用户
    删除 用户
    更新用户

    3.2 PC环境

    java环境:1.7.0_40
    eclipse
    mysql: 5.7

    3.3 创建mysql数据库

    新建数据库mybatis,新建表user


    user详细信息

    3.4所需Jar包

    MyBatis下载地址:https://github.com/mybatis/mybatis-3/releases

    mybatis-3.4.4.jar :核心包

    mysql-connector-java-5.1.jar:mysql的驱动包

    3.4 工程结构

    在eclipse中新建java工程,创建下面的工程结构,并把jar把添加到lib中


    ccc.png

    3.5 配置log4j.properties

    开发环境 下日志级别设置为DEBUG, log4j.rootLogger=DEBUG, stdout; 生产环境设置为info或error

    # Global logging configuration
    #\u5728\u5f00\u53d1\u73af\u5883\u4e0b\u65e5\u5fd7\u7ea7\u522b\u8981\u8bbe\u7f6e\u6210DEBUG\uff0c\u751f\u4ea7\u73af\u5883\u8bbe\u7f6e\u6210info\u6216error
    log4j.rootLogger=DEBUG, stdout
    # 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
    
    

    3.6 配置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>
    
        <!-- 加载属性文件 -->
        <properties resource="db.properties">
            <!--properties中还可以配置一些属性名和属性值  -->
            <!-- <property name="jdbc.driver" value=""/> -->
        </properties>
        <!-- 全局配置参数,需要时再设置 -->
        <!-- <settings>
        
        </settings> -->
        
        <!-- 别名定义 -->
        <typeAliases>
            
            <!-- 针对单个别名定义
            type:类型的路径
            alias:别名
             -->
            <!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
            <!-- 批量别名定义 
            指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)
            -->
            <package name="cn.itcast.mybatis.po"/>
            
        </typeAliases>
        
        <!-- 和spring整合后 environments配置将废除-->
        <environments default="development">
            <environment id="development">
            <!-- 使用jdbc事务管理,事务控制由mybatis-->
                <transactionManager type="JDBC" />
            <!-- 数据库连接池,由mybatis管理-->
                <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>
            </environment>
        </environments>
        <!-- 加载 映射文件 -->
        <mappers>
            <mapper resource="sqlmap/User.xml"/>    
        </mappers>  
    </configuration>
    
    

    3.7 根据用户id(主键)查询用户信息

    3.7.1 创建po类

    在cn.eugene.po下创建user类

    package cn.eugene.po;
    
    public class User {
        private int id;
        private String userName;
        private String userAge;
        private String userAddress;
        public User() {
            super();
            // TODO Auto-generated constructor stub
        }
        /**
         * @return the id
         */
        public int getId() {
            return id;
        }
        /**
         * @param id the id to set
         */
        public void setId(int id) {
            this.id = id;
        }
        /**
         * @return the userName
         */
        public String getUserName() {
            return userName;
        }
        /**
         * @param userName the userName to set
         */
        public void setUserName(String userName) {
            this.userName = userName;
        }
        /**
         * @return the userAge
         */
        public String getUserAge() {
            return userAge;
        }
        /**
         * @param userAge the userAge to set
         */
        public void setUserAge(String userAge) {
            this.userAge = userAge;
        }
        /**
         * @return the userAddress
         */
        public String getUserAddress() {
            return userAddress;
        }
        /**
         * @param userAddress the userAddress to set
         */
        public void setUserAddress(String userAddress) {
            this.userAddress = userAddress;
        }
    
        @Override
        public String toString() {
            return "User [id=" + id + ", userName=" + userName + ", userAge=" + userAge + ", userAddress=" + userAddress
                    + "]";
        }   
        
    
    }
    
    

    3.7.2 映射文件

    在项目目录的sqlmap下创建user的映射文件userMapp.xml,并配置根据id查询用的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="test">
        <!-- 根据id查询用户信息 -->
        <select id="findUserById" parameterType="int" resultType="cn.eugene.po.User">
            select * from user where id = #{id}
        </select>   
     
    </mapper>
    

    3.7.3 在SqlMapConfig.xml加载映射文件

    <mappers>
            <mapper resource="sqlmap/User.xml"/>
    </mappers>
    
    

    3.7.4 编写测试程序,根据id查询用户信息

    package cn.eugene.first;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.junit.Test;
    
    import cn.eugene.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;
    
    public class MybatisFirst {
        
        @Test
        public void findUserByIdTest() throws IOException{
            //得到配置文件流
            String resource = "SqlMapConfig.xml";
            InputStream inputstream = Resources.getResourceAsStream(resource);
            //创建会话工厂,传入mybatis的配置文件信息
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
            //通过会话工厂得到SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            User user = sqlSession.selectOne("test.findUserById", "1");
            System.out.println(user);
            sqlSession.close();     
        }
        
        
    
        @Test
        public void deleteUser() throws IOException {
            String resource = "SqlMapConfig.xml";
            InputStream inputstream = Resources.getResourceAsStream(resource);
            //创建会话工厂,传入mybatis的配置文件信息
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
            //通过会话工厂得到SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();    
            sqlSession.delete("test.deleteUser", "2");
            sqlSession.commit();
            sqlSession.close();
        }
        
        @Test
        public void updateUser() throws IOException {
            String resource = "SqlMapConfig.xml";
            InputStream inputstream = Resources.getResourceAsStream(resource);
            //创建会话工厂,传入mybatis的配置文件信息
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
            //通过会话工厂得到SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();    
            User user = new User();
            user.setId(2);
            user.setUserName("出运费");
            user.setUserAge("21");
            user.setUserAddress("重庆");
            sqlSession.update("test.updateUser", user);
            sqlSession.commit();
            sqlSession.close();
        }    
        
    
    }
    
    

    3.8 添加用户

    sql配置

    <insert id="insertUser" parameterType="cn.eugene.po.User">
            insert into user(userName,userAge,userAddress)VALUES(#{userName},#{userAge},#{userAddress})
        </insert>
    

    测试方法

        @Test
        public void insertUser() throws IOException {
            String resource = "SqlMapConfig.xml";
            InputStream inputstream = Resources.getResourceAsStream(resource);
            //创建会话工厂,传入mybatis的配置文件信息
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
            //通过会话工厂得到SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();    
            User user = new User();
            user.setUserName("出运费");
            user.setUserAge("21");
            user.setUserAddress("重庆2");
            sqlSession.update("test.insertUser", user);
            sqlSession.commit();
            sqlSession.close();
        }
    

    3.9 删除用户更新用户

    sql配置

    <!-- 根据id删除用户 -->
        <delete id="deleteUser" parameterType="int">
            delete from user where id = #{id}
        </delete>
        
        <update id="updateUser" parameterType="cn.eugene.po.User">
            update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id= #{id}
        </update>
    
    

    测试方法

        @Test
        public void insertUser() throws IOException {
            String resource = "SqlMapConfig.xml";
            InputStream inputstream = Resources.getResourceAsStream(resource);
            //创建会话工厂,传入mybatis的配置文件信息
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
            //通过会话工厂得到SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();    
            User user = new User();
            user.setUserName("出运费");
            user.setUserAge("21");
            user.setUserAddress("重庆2");
            sqlSession.update("test.insertUser", user);
            sqlSession.commit();
            sqlSession.close();
        }
    

    3.10添加用户主键返回

        <insert id="insertUser2" parameterType="com.ganlion.po.User">
            <selectKey keyProperty="id" order="AFTER" resultType="int">
                SELECT LAST_INSERT_ID()
            </selectKey>
            insert into user(userName,userAge,userAddress)VALUES(#{userName},#{userAge},#{userAddress})
        </insert>
    

    测试方法

    @Test
        public void insertUser2(){
            InputStream inputstream = Resources.getResourceAsStream(resource);
            //创建会话工厂,传入mybatis的配置文件信息
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
            //通过会话工厂得到SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();    
            User user = new User();
            user.setUserName("飛天");
            user.setUserAge("24");
            user.setUserAddress("上海浦江");
            session.insert("test.insertUser2", user);
            session.commit();
            System.out.println("返回的插入的主鍵id:"+user.getId());
            session.close();
        }
    

    四、总结

    sql配置文件中

    parameterType指定输入参数类型
    resultType指定输出参数类型
    #{}表示一个占位符,#{}接收输入参数。#{}可以有效防止sql注入。类型可以是简单类型,pojo、hashmap。如果接收简单类型,#{}中可以写成value或其它名称。

    #{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

    ${}表示一个拼接符号,拼接sql串,会引起sql 注入存在安全隐患,所以不建议使用${}。${}接收输入参数,类型可以是简单类型,pojo、hashmap。如果接收简单类型,${}中只能写成value。

    ${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

    五、编写入门程序可能遇到的问题

    问题一、Could not find resource SqlMapConfig.xml

    ddd.png

    原因:一开始是因为默认的情况下,只有src是build path的source folder目录,自定义的文件夹在Use as Source Folder前只是一个普通的文件夹,默认的情况下不会被加载,需要手动将自定义的文件夹加载为source folder。也就是之前所说的步骤。

    解决办法:右键点击SqlMapConfig.xml所在的文件夹(我的是config)------>Build Path------>Use as Source Folder

    参考mybatis中遇到Could not find resource SqlMapConfig.xml

    问题二、当查询数据库数据的时候,控制台System.out.println(user)输出了NULL

    注意sql配置文件查询的字段和数据库对应

    相关文章

      网友评论

        本文标题:mybatis入门之增删改查

        本文链接:https://www.haomeiwen.com/subject/ehsnoftx.html