Mybatis-增删改查
Posted 飞人01_01
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis-增删改查相关的知识,希望对你有一定的参考价值。
文章目录
一、简介
Mybatis是属于持久层(DAO层)的框架,它封装了很多JDBC的很多操作细节,让开发者大大简化了DAO层的代码。在2010年从iBatis改名为Mybatis。
中文官网:https://mybatis.org/mybatis-3/zh/getting-started.html
二、准备工作
1、依赖
在idea中新建一个Maven项目,在该项目的pom.xml文件中写入依赖。然后点击下载、刷新。
<dependencies>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
</dependencies>
使用Mybatis框架时,还是需要导入MySQL的依赖包。
2、核心配置文件
在resource文件夹下,新建 mybatis-config.xml文件,这个文件称为 Mybatis的核心配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- mybatis-config.xmd 称为mybatis的核心配置文件-->
<!-- 工作环境-->
<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/test"/>
<property name="username" value="root"/>
<property name="password" value="0000"/>
</dataSource>
</environment>
</environments>
</configuration>
这里可以配置多个 <environment>标签,用于表示多个运行环境,比如开发时、上线时等。在<environments>中的default处可以切换环境。
3、创建Session
在JDBC中 是通过Connection对象进行操作数据库的,在Mybatis中却是通过SqlSession对象来操作数据库。
在test下面创建一个DBUtil类,后续在这里测试代码。
public class DBUtil
private static SqlSessionFactory factory; // 构建SQL session的工厂
static
// 1、读取 Mybatis的核心配置文件
try (Reader reader = Resources.getResourceAsReader("mybatis-config.xml"))
// 2、需要一个工厂构建器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 3、 创建一个工厂
factory = builder.build(reader);
catch (IOException e)
e.printStackTrace();
public static SqlSession openSession() // 返回一个session 会话值,上层调用自己进行session资源的回收
return factory.openSession();
// 同时也可以通过session获得Connection对象,就可以回到JBDC的代码
// session.getConnection();
三、增删改查
1、实体映射
1、创建实体映射配置文件
假设我现在要查询数据库中的Student的信息,那么首先我需要先创建一个 实体映射的配置文件,后续关于这个Student的所有SQL语句相关的操作,都放在这个 实体映射配置文件中。
在 resource -> mappers 中,新建一个 student.xml 文件,这个就是 实体映射的配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace 命令空间,后续可以根据这个命名空间来访问他所包含的 SQL代码-->
<mapper namespace="student">
<!-- resultType是返回的结果表示 是以 Student类的形式进行存储-->
<select id="list" resultType="students.Student">
select * from student
</select>
</mapper>
2、装载实体映射配置文件
写好实体映射的配置文件后,要将该文件装载到 Mybatis的核心配置文件中。
2、查询
a、不带参数查询
在 实体映射配置文件 student.xml 中,写入相应的SQL语句,如下图
- 第6行的 namespace:用于后续session进行调用的一个参数
- 第8行的 id:表示当前select操作的唯一标识符,类似与 HTML标签中的ID。
- 第8行的 resultType:表示 查询的结果是以什么形式进行存储,图中写的是 以Student类的形式进行存储
在select标签里面,就可以写入相应的SQL语句。
提前在pom.xml中引入单元测试的依赖包(Junit),然后在test文件下,新建一个类,用于测试。
@Test
public void select()
// 不带任何参数的查询
try (SqlSession session = DBUtil.openSession()) // 自己获取session和关闭session
// 直接通过session进行操作
List<Student> objects = session.selectList("student.list");
for (Student object : objects)
System.out.println(object);
b、带参数查询
1、只带一个参数时
在实体映射配置文件中,写入 #name,表示一个参数,后续调用时,传入即可。当只有一个参数时,参数名称可以随便取。
@Test
public void select2()
// 查询一个参数
try (SqlSession session = DBUtil.openSession())
Student student = session.selectOne("student.get", "彭于晏");
System.out.println(student);
2、带多个参数时
@Test
public void select3()
// 第一种:传入多个参数的查询方法
try (SqlSession session = DBUtil.openSession())
Map<String, String> map = new HashMap<>();
map.put("id","2");
map.put("name","彭于晏");
List<Student> student = session.selectList("student.get2", map);
for (Student student1 : student)
System.out.println(student1);
@Test
public void select4()
// 第二种:传入多个参数的查询方法
try (SqlSession session = DBUtil.openSession())
Student student = new Student();
// 切记:这里的Student类中的属性名称:id、name
// 与 student.xml中写的#id、#name是相对应的
student.setId(2);
student.setName("彭于晏");
List<Student> students = session.selectList("student.get2", student);
for (Student student1 : students)
System.out.println(student1);
c、字段映射
在实际开发中,有可能出现 Java类的属性名 跟 数据库的表中的字段名不一样,此时在查询到结果后,需要进行映射一下。
举个例子:Student类的属性名:name,而数据库的表中的字段名:myname。二者都是指的学生的姓名,但字段名和属性名不一样,所有在查询结果后,导致这个数据并没有存储在Student对象中,所以需要自己映射一下。
特别的:MySQL中的主键,需要使用**<id> </id>** 来进行映射。
当然,还有一种复杂的映射情况,也就是下文的多表查询的例子:
第一种写法:
第二种写法:
d、$与#的区别
- $:就是普通的文本替换,不能防止SQL注入。在模糊查询的SQL中,使用 ‘%$key%’ 可以正常使用。
- #:就类似于JDBC中的那个prepareStatement(),这个就会进行预编译,防止SQL注入。在模糊查询中,使用 ‘%#key%’ 就不能正常使用,需要在key的上层传递时,就将%加入进去。
e、多表联合查询
相应的多表查询就比较简单了,特别需要注意的是 如何将返回的结果存储在一个Student类中,好好理解上述的 字段映射,自然也就会了。
3、增加、删除、修改
事务:在进行增加、删除、修改时,这样的操作一般都是需要进行事务管理的,在Mybatis中,可以进行自动提交事务 和 手动提交事务。手动提交事务分为两种:
1、commit,提交当前的所有操作,对数据库的影响是永久的。2、rollback,回滚事务,即当前所有的操作都不会生效,回滚到事务开始之前。
在openSession方法中,传入相应的参数,就能切换 自动/手动提交事务。true:自动提交事务;false:手动提交事务。
- 增加
学会了查询的相关操作,相应的增加、删除、修改基本都会了,这里就举几个例子。
<insert id="insert" parameterType="students.Student">
<!-- 如果Student里面有个参数是引用类型,这里在使用的时候,还是需要像正常调用参数一样:manger.managerID-->
<!-- 参数:parameterType 指的是 传入进来的参数的类型-->
INSERT INTO student VALUES (#id, #name, #manager.managerID);
</insert>
- 删除
<delete id="delete" parameterType="int">
DELETE FROM student WHERE id = #id
</delete>
- 修改
<update id="update" parameterType="students.Student">
UPDATE student SET name = #name WHERE id = #id
</update>
4、批量操作
- 批量增加
例如插入数据的SQL语句如下:
# 插入三个Student的学号、姓名、班主任ID
INSERT INTO student VALUES (id, name, managerID), (id, name, managerID), (id, name, managerID);
所以有如下Mybatis的代码:
<!-- 批量插入-->
<insert id="insertList" parameterType="java.util.List">
INSERT INTO student VALUES
<foreach collection="list" item="stu" separator=",">
(#stu.id, #stu.name, #stu.manager.managerID)
</foreach>
</insert>
其中,collection
指的是集合类型,传参用的是 List<Student> ,所以这里写 collection = “list”。当然,如果传参用的是 数组,就写collection = “array”。 item
指的是 每次循环的实参,就类似于 Java中的 for (int num : array)
中的num。separator
指的是每组参数之间的分隔符。
- 批量删除
DELETE FROM student WHERE id in (?, ?, ?, ?);
跟上述的批量增加很类似,代码代码如下:
<delete id="deleteList" parameterType="List">
DELETE FROM student WHERE id in
<foreach collection="list" item="id" separator=","
open="(" close=")">
#id
</foreach>
</delete>
5、动态SQL
在实际的开发环境中,可能某一些查询操作很复杂,比如:
select * from student where id < 7 or name like '%刘%';
像这种,需要满足好几个 where条件的,但是在实际环境中,有时是2个条件,有时是3个条件,这种情况就需要动态的调整SQL语句。
<select id="dynamicSQL1" parameterType="Map" resultType="students.Student">
SELECT id,name, managerID `manager.managerID` FROM student
<!-- where 标签 代替了 SQL语句中的 where子句-->
<where>
<if test="id != null">
<!-- 这里的 < 是字符实体,表示 '<'号。如果直接写'<'号 会编译不过去-->
id < #id
</if>
<if test="name != null">
OR name like #name
</if>
</where>
</select>
如上代码,当if标签中的test条件成立时,才会将其中的SQL代码拼接上。
6、其他标签
1、 SQL标签:应用在实体映射文件中,用于直接替换大量重复的SQL语句
<sql id = "sqlListAll">
SELECT * FROM student
</sql>
<!-- 应用如下 -->
<select id="get" resultType="students.Student">
<!-- 直接将上述第2行的SQL代码 替换进来 -->
<include refid = "sqlListAll"/>
</select>
2、typeAliases 标签:起别名。 应用场景:比如上面一直在写 resultType = “students.Student
”,写的很啰嗦,就可以用别名简化。切记,这个标签是写在 Mybatis的核心配置文件,也就是 mybatis-config.xml
中。
<typeAliases>
<!-- 起别名:这里是不区分大小写的,-->
<typeAlias type="students.Student" alias="student"/>
</typeAliases>
如上,每个标签的顺序是有规定的,如果这个核心配置文件报红,有可能就是 某些标签的位置没放对。
3、properties 标签:一些配置文件的参数,可以重新引用到另外一个文件。
如图,像username、password这些参数,有可能需要随时换,在这里改又比较麻烦,就可以创建一个新的文件,用于参数替换。
更多标签,请参考:https://mybatis.org/mybatis-3/zh/configuration.html
以上全部就是mybatis的基本使用,感谢阅读。
mybatis增删改查
目录
数据库的经典操作:增删改查。
在这一章我们主要说明一下简单的查询和增删改,并且对程序接口做了一些调整,以及对一些问题进行了解答。
1、调整后的结构图:
2、连接数据库文件配置分离:
一般的程序都会把连接数据库的配置单独放在.properties 文件中,然后在XML文件中引用,示例如下:
config.properties:
driver=oracle.jdbc.OracleDriver url=jdbc:oracle:thin:@127.0.0.1:1521:orcl username=phonesurvey password=world
mybatis-config.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="config.properties" /> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="nankang/dao/agentDao.xml" /> </mappers> </configuration>
3、SqlSession分离:
SqlSeesion单独做成工具类,以便调用,示例如下:
SqlSessionHelper:
package nankang.util; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class SqlSessionHelper { public static SqlSessionFactory getSessionFactory(){ SqlSessionFactory sessionFactory = null; String resource= "mybatis-config.xml"; try{ InputStream inputStream = Resources.getResourceAsStream(resource); //Reader reader = Resources.getResourceAsReader(resource); sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); }catch(Exception ex){ ex.printStackTrace(); } return sessionFactory; } }
SqlSessionFactory创建时,根据Reader和InputStream都可以。
4、XML文件添加内容:
agentDao.xml:
<?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="nankang.dao.AgentDao"> <!-- 根据Id查询 --> <select id="selectAgentById" parameterType="string" resultType="nankang.po.Agent"> select * from Agent where AgentId=#{id} </select> <!-- 添加 --> <insert id="insertAgent" parameterType="nankang.po.Agent"> insert into Agent(agentId, companyCode, LoginName, AgentPwd, AgentCode, Name, status,sysFlag) values(#{agentId},\'SHNK\',#{loginName},\'D41D8CD98F00B204E9800998ECF8427E\',#{agentCode},#{name},1,1) </insert> <!-- 删除 --> <delete id="deleteAgent" parameterType="string"> delete from Agent where agentid=#{id} </delete> <!-- 修改 --> <update id="updateAgent" parameterType="nankang.po.Agent"> update agent set name=#{name} where agentid=#{agentId} </update> <!-- 查询所有 --> <select id="selectAllAgent" resultType="nankang.po.Agent"> select * from Agent </select> <!-- 查询所有无返回对象 --> <select id="selectAllAgent2" resultType="hashmap"> select * from Agent </select> </mapper>
AgentDao.java:
package nankang.dao; import java.util.List; import java.util.Map; import nankang.po.Agent; import org.apache.ibatis.annotations.Select; public interface AgentDao { //根据Id查询 public Agent selectAgentById(String Id); //根据名称查询 @Select("select * from Agent where name=#{name}") public Agent selectAgentByName(String name); //添加 public int insertAgent(Agent agent); //删除 public int deleteAgent(String id); //修改 public int updateAgent(Agent agent); //查询所有的 public List<Agent> selectAllAgent(); public List<Map<String, Object>> selectAllAgent2(); }
1、XML文件中的语句,可以直接写在接口文件中,如:根据名称查询;
2、其他参考示例。
几个问题说明:
1)如何查询数据集合?
使用ResultType设置,返回用List<T>即可
2)查询一条数据,如果为空,怎么判断?
如果没有查询到数据,返回为NULL,进行空对象判断即可
3)查询所有的集合,不放在构建对象的List中:
4)如何实现事务:
SqlSession:commit,rollback,close
5、测试
package nankang.test; import java.util.List; import java.util.Map; import nankang.dao.AgentDao; import nankang.util.SqlSessionHelper; import org.apache.ibatis.session.SqlSession; public class test { /** * @param args */ public static void main(String[] args) { SqlSession sqlSession = SqlSessionHelper.getSessionFactory().openSession(); try{ AgentDao agentMapper = sqlSession.getMapper(AgentDao.class); //根据Id查询 // Agent agent = agentMapper.selectAgentById("SHNKAG00000000051"); // if(null != agent){ // System.out.println(agent.getName()); // }else{ // System.out.println("不存在该用户"); // } // agent = agentMapper.selectAgentByName("1001"); // System.out.println(agent.getAgentId()); //查询所有 List<Map<String, Object>> agentList = agentMapper.selectAllAgent2(); System.out.println(agentList.size()); //添加 // Format format = new SimpleDateFormat("00yyyyMMddhhmmss"); // Calendar calendar = Calendar.getInstance(); // String dateStr = format.format(calendar.getTime()); // Agent agent = new Agent(); // agent.setAgentId(dateStr); // agent.setLoginName("1111"); // agent.setAgentCode("aaaa"); // agent.setName("aaaa"); // int num = agentMapper.insertAgent(agent); // System.out.println(num); //删除 // int num = agentMapper.deleteAgent("0020150226093127"); // System.out.println(num); //更新 // Agent agent = new Agent(); // agent.setAgentId("0020150226010005"); // agent.setName("Test"); // int num = agentMapper.updateAgent(agent); // System.out.println(num); //增删改,提交 sqlSession.commit(); System.out.println("完成"); }catch(Exception ex){ sqlSession.rollback(); System.out.println(ex.getMessage()); }finally{ sqlSession.close(); } } }
这边需要注意的是:SqlSession一定要close
以上是关于Mybatis-增删改查的主要内容,如果未能解决你的问题,请参考以下文章