zoukankan      html  css  js  c++  java
  • MyBatis(2)增删改查

    本次全部学习内容MyBatisLearning

     
    查:
    根据id查询用户信息,得到一个用户信息
     
    在User.xml文件中添加代码:
     <mapper namespace="test">
        <!-- 配置很多的sql语句 -->
         
         <!-- 查询标签 -->
         <!-- id用于唯一标识这个sql查询 -->
         <!-- #{} 标识占位符 -->
         <!-- parameterType:指定输入参数的类型: -->
         <!-- #{id}:接受输入的参数,id表示输入的参数,参数名就是id,如果输入参数是简单的类型,#{}中的参数可以是任意字符 -->
         <!-- resultType:输出结果的类型 所映射的java 类型对象,单挑记录所映射成的java对象-->
         
         <select id="findUserByID" parameterType="int" resultType="com.MrChengs.po.User">
               select * from user where id=#{id}
         </select>
    </mapper>
     
    在测试代码中test.java:
    //根据id查询用户信息,得到一个用户信息
         @Test
         public void findUserById() throws IOException{
               
               //配置文件的
               String resource = "SqlMapConfig.xml";
               //得到配置文件流
               InputStream inputStream = Resources.getResourceAsStream(resource);
               
               //创建会话工程
               SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
         
               //通过工程得到Session
               SqlSession session = sessionFactory.openSession();
               
               //通过SqlSession操作数据库
               //session.selectOne(arg0, arg1)
               //第一个参数:映射文件statement的id,等于 namespace.statement
               //第二个参数:指映射文件的中的parameType的类型参数
               
               User user = session.selectOne("test.findUserByID", 10);
               System.out.println(user);
               //关闭资源
               session.close();
         }
    这里的代码使用try{}finally{} 和jdbc类似,暂时没有使用!
     
    控制台的结果:
    DEBUG [main] - Opening JDBC Connection
    DEBUG [main] - Created connection 733957003.
    DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2bbf4b8b]
    DEBUG [main] - ==>  Preparing: select * from user where id=?
    DEBUG [main] - ==> Parameters: 10(Integer)
    DEBUG [main] - <==      Total: 1
    User [id=10, username=张三, birthday=Thu Jul 10 00:00:00 CST 2014, sex=1, address=北京市]
    DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2bbf4b8b]
    DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@2bbf4b8b]
    DEBUG [main] - Returned connection 733957003 to pool.
    根据用户名称来模糊查询用户信息:
    在User,xml文件中添加代码:
         <!-- 模糊查询 -->
         <!-- resultType:指定单挑记录所映射的类型 -->
         <select id="findByName" parameterType="java.lang.String" resultType="com.MrChengs.po.User" >
               select * from user where username Like #{username}
         </select>
     
    其余不变去测试代码中
    在测试代码中test.java:
    //根据用户名称来模糊查询用户
         @Test
    public void findUserByName() throws IOException{
               
               //配置文件的
               String resource = "SqlMapConfig.xml";
               //得到配置文件流
               InputStream inputStream = Resources.getResourceAsStream(resource);
               
               //创建会话工程
               SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
         
               //通过工程得到Session
               SqlSession session = sessionFactory.openSession();
               
               //通过SqlSession操作数据库
               //selectList(String arg0, Object arg1)
               //list中的user和映射文件中的resultType所指类型一直
               //百分号不能忘记添加
               List<User> users = session.selectList("test.findByName", "%小明%");
               for(User user : users){
                    System.out.println(user);
               }
               //关闭资源
               session.close();
         }
         

    注意红色标记的部分。

     
     
    思考:我们可不可以不在测试类中添加百分号?
     
    我们这本此程序代码的基础上进行改进:
    在User,xml文件中:
    <!-- 模糊查询 -->
         <!-- resultType:指定单挑记录所映射的类型 -->
         
         <!-- ${} :表示拼接sql串,将接收的参数的内容不加任何修饰的拼接在sql中 -->
         <!-- 使用 ${ } 拼接sql,容易sql注入 -->
         <!-- ${}  接受参数的内容,如果传入类型是简单类型  ${} 只能使用value -->
         <select id="findByName" parameterType="java.lang.String" resultType="com.MrChengs.po.User" >
               select * from user where username Like '%${value}%'
         </select>
    在这里测试时,'%${value}%',其余字符得不到结果,只能使用value
     
    测试代码test.java中:
    //根据用户名称来模糊查询用户
         @Test
    public void findUserByName() throws IOException{
               
               //配置文件的
               String resource = "SqlMapConfig.xml";
               //得到配置文件流
               InputStream inputStream = Resources.getResourceAsStream(resource);
               
               //创建会话工程
               SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
         
               //通过工程得到Session
               SqlSession session = sessionFactory.openSession();
               
               //通过SqlSession操作数据库
               //selectList(String arg0, Object arg1)
               //list中的user和映射文件中的resultType所指类型一直
               List<User> users = session.selectList("test.findByName", "小明");
               for(User user : users){
                    System.out.println(user);
               }

    此时此刻,没有使用 %

    结果:
    DEBUG [main] - Opening JDBC Connection
    DEBUG [main] - Created connection 213193302.
    DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@cb51256]
    DEBUG [main] - ==>  Preparing: select * from user where username Like '%小明%'
    DEBUG [main] - ==> Parameters:
    DEBUG [main] - <==      Total: 3
    User [id=16, username=张小明, birthday=null, sex=1, address=河南郑州]
    User [id=22, username=陈小明, birthday=null, sex=1, address=河南郑州]
    User [id=25, username=陈小明, birthday=null, sex=1, address=河南郑州]
    DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@cb51256]
    DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@cb51256]
    DEBUG [main] - Returned connection 213193302 to pool.
     
    此时是直接拼串,没有占位符,这种方法的使用,容易被注入!
     
    查询小结:
    1.
    parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
    resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。
    2.
    selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:
    selectList可以查询一条或多条记录。
    3.
    #{}  & ${} 
    #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
     
    ${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value
     
     
    添加用户:
    在在User,xml文件中:
    主键id是自增的,此时也可以省略主键
        <!-- 添加用户 -->
         <!-- parameterType:指定输入的参数类型是pojo(包括用户信息) -->
         <!-- #{} 中指定pojo的属性名,接收到的pojo对象的属性值,mybatis通过OGNL获取对象的属性值 -->
         <insert id="addUser" parameterType="com.MrChengs.po.User">
               insert into user(id,username,birthday,sex,address)
                value(#{id},#{username},#{birthday},#{sex},#{address})
         </insert>
     
    在测试类test.java:
    //添加用户
         @Test
    public void addUser() throws IOException{
               String resource = "SqlMapConfig.xml";
               InputStream inputStream = Resources.getResourceAsStream(resource);
               SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
               SqlSession session = sessionFactory.openSession();
               
               //添加的用户信息
               User user = new User();
               user.setUsername("MrCheng");
               user.setSex(1);
               user.setBirthday(new Date());
               user.setAddress("北京");
               
               session.insert("test.addUser", user);
               
               //需要提交事物
               session.commit();
               //关闭会话
               session.close();
         }

    查看结果:

    DEBUG [main] - Opening JDBC Connection
    DEBUG [main] - Created connection 1384722895.
    DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@528931cf]
    DEBUG [main] - ==>  Preparing: insert into user(id,username,birthday,sex,address) value(?,?,?,?,?)
    DEBUG [main] - ==> Parameters: 0(Integer), MrCheng(String), 2018-10-05 13:09:06.928(Timestamp), 1(Integer), 北京(String)
    DEBUG [main] - <==    Updates: 1
    DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@528931cf]
    DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@528931cf]
    DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@528931cf]
    DEBUG [main] - Returned connection 1384722895 to pool.

    假设我们此时在添加用户的同时得到主键值:

    自增主键返回:
    mysql自增主键,执行insert提交之前自动生成一个主键 
    通过mysql函数获取自增主键
    对之前的代码进行修改
    User.xml文件中:

    LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值

         <!-- 添加用户 -->
         <!-- parameterType:指定输入的参数类型是pojo(包括用户信息) -->
         <!-- #{} 中指定pojo的属性名,接收到的pojo对象的属性值,mybatis通过OGNL获取对象的属性值 -->
         <insert id="addUser" parameterType="com.MrChengs.po.User">
         
               <!-- 将插入的数据主键返回,返回到user对象中 -->
               <!-- SELECT LAST_INSERT_ID():得到insert插入后得到的主键值 -->
               <!-- keyProperty:将查询到的主键设置到parameterType指定对象的属性中 -->
               <!-- order:执行顺序,相对比插入insert来说 -->
               <!-- resultType:指定结果的类型 -->
               <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
                    SELECT LAST_INSERT_ID()
               </selectKey>
         
               insert into user(id,username,birthday,sex,address)
                value(#{id},#{username},#{birthday},#{sex},#{address})
         </insert>
     
    测试类test.java中:
    @Test
    public void addUser() throws IOException{
               String resource = "SqlMapConfig.xml";
               InputStream inputStream = Resources.getResourceAsStream(resource);
               SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
               SqlSession session = sessionFactory.openSession();
               User user = new User();
               user.setUsername("MrCheng");
               user.setSex(1);
               user.setBirthday(new Date());
               user.setAddress("北京");
               
               session.insert("test.addUser", user);
               
               System.out.println(user.getId());
               //需要提交事物
               session.commit();
               
                         
               //关闭会话
               session.close();
         }

    结果:

    DEBUG [main] - Opening JDBC Connection
    DEBUG [main] - Created connection 22429093.
    DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - ==>  Preparing: insert into user(id,username,birthday,sex,address) value(?,?,?,?,?)
    DEBUG [main] - ==> Parameters: 0(Integer), MrCheng(String), 2018-10-05 14:11:48.735(Timestamp), 1(Integer), 北京(String)
    DEBUG [main] - <==    Updates: 1
    DEBUG [main] - ==>  Preparing: SELECT LAST_INSERT_ID()
    DEBUG [main] - ==> Parameters:
    DEBUG [main] - <==      Total: 1
    28
    DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - Returned connection 22429093 to pool.
     
    非自增主键的返回:
    使用mysql的uuid()函数生成逐渐,需要修改表中的id为String,长度设置为35位
    需要增加通过select uuid()得到uuid值
    <insert  id="insertUser" parameterType="cn.itcast.mybatis.po.User">
    <selectKey resultType="java.lang.String" order="BEFORE"
    keyProperty="id">
    select uuid()
    </selectKey>
    insert into user(id,username,birthday,sex,address)
     values(#{id},#{username},#{birthday},#{sex},#{address})
    </insert>
    注意这里使用的order是“BEFORE”
    

      

    删除用户:

    映射文件中:
     
    User.xml文件:
    <!-- 删除用户 -->
         <!-- 根据id删除 -->
         <delete id="deleteUser" parameterType="java.lang.Integer">
               delete from user where id=#{id}
         </delete>

    测试类:

        //删除用户
        @Test
         public void deleteUser() throws IOException{
    
                    String resource = "SqlMapConfig.xml";
                    InputStream inputStream = Resources.getResourceAsStream(resource);
                    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
                    SqlSession session = sessionFactory.openSession();
                    
                    session.delete("test.deleteUser", 28);
                    //需要提交事物
                    session.commit();
                    //关闭会话
                    session.close();
               }

    控制台:

    DEBUG [main] - Opening JDBC Connection
    DEBUG [main] - Created connection 22429093.
    DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - ==>  Preparing: delete from user where id=?
    DEBUG [main] - ==> Parameters: 28(Integer)
    DEBUG [main] - <==    Updates: 1
    DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - Returned connection 22429093 to pool.
    更新数据:

    User.xml

        <!-- 更新用户 -->
         <!-- 根据id更新用户 -->
         <!-- parameterType:指定user对象,包括id更新信息,注意id必须存在 -->
         <update id="updateUser" parameterType="com.MrChengs.po.User">
               update user set username=#{username},sex=#{sex} where id = #{id}
         
         </update>

    测试类:

              //更新
               @Test
               public void updateUser() throws IOException{
                    String resource = "SqlMapConfig.xml";
                    InputStream inputStream = Resources.getResourceAsStream(resource);
                    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                    SqlSession session = sessionFactory.openSession();
                    User user = new User();
                    user.setUsername("MrChegns");
                    user.setSex(2);
                    user.setId(27);
                    session.update("test.updateUser", user);
                    //需要提交事物
                    session.commit();
                               
                    //关闭会话
                    session.close();
               }
    注意:id必须要上进行设置。
    控制台:
    DEBUG [main] - Opening JDBC Connection
    DEBUG [main] - Created connection 22429093.
    DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]
    DEBUG [main] - ==>  Preparing: update user set username=?,sex=? where id = ?
    DEBUG [main] - ==> Parameters: MrChegns(String), 2(Integer), 27(Integer)
    DEBUG [main] - <==    Updates: 1

     Mybatis解决jdbc编程的问题

    1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

    解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。

    2、 Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

    解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

    3、 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

    解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。

    4、 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

    解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

    当你看到这里,基本入门程序已经讲解完了!!!

  • 相关阅读:
    net中System.Security.Cryptography 命名空间 下的加密算法
    关于如何生成代码的帮助文档的链接
    Application.EnableVisualStyles();
    VS2010里属性窗口中的生成操作
    把普通的git库变成bare库
    MultiTouch camera controls source code
    android onTouch()与onTouchEvent()的区别
    iOS开发中常见的语句@synthesize obj = _obj 的意义详解
    java nio 快速read大文件
    使用ndk standalone工具链来编译某个平台下的库
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/9744945.html
Copyright © 2011-2022 走看看