本次全部学习内容: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. .net core 第二篇控制台程序项目初步学习

    1. 使用vscode 创建一个控制台程序 创建项目默认创建的项目名称为父级文件夹名称 后面学习下创建的命令各个参数说明 运行项目dotnet run 其他命令SDK 命令:add 将包或引用添加到 ...

  2. idea快捷键、常用设置

      代码提示: code completion :ALT + / 选用Eclipse的keymap. 设置代码助手快捷键(keymap-basic) 代码上下行复制(Ctrl + Alt + Down ...

  3. java对象中含有Integer类型字段转json字符串问题

    问题:对于含有Integer类型字段的java对象,在通过下面这种方式转为json字符串时,Integer类型的字段如果为空的情况下,会默认转化为0,但是我想让它为空的时候直接转化为null,不要默认 ...

  4. 基于easyUI实现权限管理系统(一)一—组织结构树图形

    此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 相关文件介绍 1. organize.jsp:组织结构树的主界面 <!DOCTYPE html PUBLIC &quo ...

  5. javascrapy 正则表达式验证 IP和MAC

    var psrc = $('input[name="psrc"]').val() var hwsrc = $('input[name="hwsrc"]').va ...

  6. Springboot事务使用与回滚

    Springboot中事务的使用: 1.启动类加上@EnableTransactionManagement注解,开启事务支持(其实默认是开启的). 2.在使用事务的public(只有public支持事 ...

  7. 监听css3的animation动画和transition事件

    webkit-animation动画有三个事件: 开始事件: webkitAnimationStart 结束事件: webkitAnimationEnd 重复运动事件: webkitAnimation ...

  8. 20个实用的javascript技巧及实践(一)

    在本篇文章中,我们将会向大家分享JavaScript开发中的小技巧.最佳实践和实用内容,不管你是前端开发者还是服务端开发者,都应该来看看这些编程的技巧总结,绝对会让你受益匪浅的. 文中所提供的代码片段 ...

  9. js修改日期

    需求说明: (1)首先是input显示年月日时分格式时间,其中年月日实在本地时间基础上,加上后面联动值.小时默认08:00不变 (2)后面input内显示天数,右侧加减按钮,控制天数,天数确定后,前面 ...

  10. jQuery和css3控制箭头丝滑旋转

    问题: 我们经常会遇见点击一个小三角使之丝滑的旋转180度上下旋转,怎么实现呢,需要css3搭配jq 来处理 如图:1.点击前 2.点击后(效果丝滑旋转)                 1.html ...