本次全部学习内容: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定义输出结果的类型。

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

MyBatis(2)增删改查的更多相关文章

  1. 学习MyBatis必知必会(5)~了解myBatis的作用域和生命周期并抽取工具类MyBatisUtil、mybatis执行增删改查操作

    一.了解myBatis的作用域和生命周期[错误的使用会导致非常严重的并发问题] (1)SqlSessionFactoryBuilder [ 作用:仅仅是用来创建SqlSessionFactory,作用 ...

  2. MyBatis的增删改查。

    数据库的经典操作:增删改查. 在这一章我们主要说明一下简单的查询和增删改,并且对程序接口做了一些调整,以及对一些问题进行了解答. 1.调整后的结构图: 2.连接数据库文件配置分离: 一般的程序都会把连 ...

  3. MyBatis批量增删改查操作

      前文我们介绍了MyBatis基本的增删该查操作,本文介绍批量的增删改查操作.前文地址:http://blog.csdn.net/mahoking/article/details/43673741 ...

  4. 上手spring boot项目(三)之spring boot整合mybatis进行增删改查的三种方式。

    1.引入依赖. <!--springboot的web起步依赖--><dependency> <groupId>org.springframework.boot< ...

  5. 上手spring boot项目(三)之spring boot整合mybatis进行增删改查

    使用mybatis框架进行增删改查大致有两种基础方式,一种扩展方式.两种基础方式分别是使用xml映射文件和使用方法注解.扩展方式是使用mybatis-plus的方式,其用法类似于spring-data ...

  6. 从0开始完成SpringBoot+Mybatis实现增删改查

    1.准备知识: 1)需要掌握的知识: Java基础,JavaWeb开发基础,Spring基础(没有Spring的基础也可以,接触过Spring最好),ajax,Jquery,Mybatis. 2)项目 ...

  7. Spring Boot入门系列(六)如何整合Mybatis实现增删改查

    前面介绍了Spring Boot 中的整合Thymeleaf前端html框架,同时也介绍了Thymeleaf 的用法.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/z ...

  8. Mybatis实例增删改查(二)

    创建实体类: package com.test.mybatis.bean; public class Employee { private Integer id; private String las ...

  9. mybatis的增删改查返回值小析(六)

    本文验证了通过mybatis访问数据库时的,增删改查的返回值情况. 直接看代码. 1.service层 /** *@Author: Administrator on 2020/3/12 15:15 * ...

  10. ssm 框架实现增删改查CRUD操作(Spring + SpringMVC + Mybatis 实现增删改查)

    ssm 框架实现增删改查 SpringBoot 项目整合 一.项目准备 1.1 ssm 框架环境搭建 1.2 项目结构图如下 1.3 数据表结构图如下 1.4 运行结果 二.项目实现 1. Emplo ...

随机推荐

  1. ODBC, OLEDB, ADO, ADO.NET

    在SSIS中,选择Connction Manager时,有很多的类型.其中会发现如下4个连接类型ODBC, OLEDB, ADO, ADO.NET.这4个东东到底是什么,他们有什么关联,什么区别,如何 ...

  2. Query performance optimization of Vertica

    Don't fetch any data that you don't need,or don't fetch any columns that you don't need. Because ret ...

  3. CSS基础知识---浮动,定位和盒模型

    转载请注明出处! 需要掌握的三个最重要的CSS概念是浮动,定位和盒模型. 盒模型概述: 页面上的每个元素都被看做一个矩形框(元素框or盒模型),这个框由元素内容,内边距,边框和外边距组成. 内边距出现 ...

  4. CXF - 拦截器获取调用方法

    没想到要弄这么一个东西. 起初只是想用interceptor记录一下webservice调用日志,后来却被要求在页面展示. 展示容易,但只是展示webservice的地址无法让用户从中明白什么. 那么 ...

  5. WPF画箭头

    简介 参考Using WPF to Visualize a Graph with Circular Dependencies的基础上写了一个WPF画箭头的库. 效果图如下: 使用的XAML代码如下: ...

  6. Flash流媒体服务器软件

    所谓流媒体技术,是指将连续的影像和声音信息经过压缩处理后放在网站服务器上,让用户能够一边下载一边观看.收听(即所谓的“在线欣赏”),而不需要等整个压缩文件下载到自己的机器上才可以欣赏的网络传输技术.目 ...

  7. linux cut: invalid byte, character or field list Try 'cut --help' for more information.

    1. 概述 centos执行简单shell 脚本 报错 cut: invalid byte, character or field listTry 'cut --help' for more info ...

  8. js对象之间的继承

    js的对象之间的继承抛弃了原型与构造器的概念,而转为字面量对象之间进行属性拷贝的方式进行继承. 首先我们来写一个封装好的继承函数: function extend(parent){ var child ...

  9. Python-MRO和C3算法

    一. python多继承 在前面的学习过程中,我们已经知道了python中类与类之间可以有继承关系,当出现x是一种y的时候就可以使用继承关系.即'is-a'关系,在继承关系中子类自动拥有父类中除了私有 ...

  10. 【Udacity】异常值检测/删除

    Outlier Detection