湘潭市建设局网站,网站关于 模板,网站建设工期及预算,新闻类网站怎么做MyBatis
JavaEE三层框架#xff1a;表现层、业务层、持久层。
现在开始学习持久层。持久层就是负责与数据库打交道的代码。
框架#xff1a;就是一个半成品软件。在框架的基础上#xff0c;可以更加高效地写出代码。
1、MyBatis快速入门
1、准备工作#xff08;创建sp…MyBatis
JavaEE三层框架表现层、业务层、持久层。
现在开始学习持久层。持久层就是负责与数据库打交道的代码。
框架就是一个半成品软件。在框架的基础上可以更加高效地写出代码。
1、MyBatis快速入门
1、准备工作创建springboot工程、导入mybatis和mysql的依赖、编写实体类、编写配置类 2、注解开发编写接口使用注解编写sql语句注解开发比较简单先使用注解开发来进行 3、测试。 2、数据库连接池
什么是数据库连接池 数据库连接池是个容器负责分配、管理数据库连接 Connection 它允许应用程序重复使用一个现有的数据库连接/而不是再重新建立一个 释放空闲时间超过最大空闲时间的连接/来避免因为没有释放连接而引起的数据库连接遗漏
如果没有数据库连接池会怎么样每一次连接数据库都要创建一个数据库连接用完后需要立刻销毁连接以免造成资源浪费。
数据库连接池的优势
资源重用提升系统响应速度避免数据库连接泄漏
sun公司在Java中提供了一个数据库连接池的标准接口之后其他公司生产了不同的数据库连接池产品。C3P0和DBCP现在基本上也已经不用了用的是德鲁伊和追光者Hikari。追光者是springboot默认使用的连接池。 切换druid连接池非常方便导入依赖然后配置文件中改一下即可。 3、注解开发
就是直接在接口方法上写个注解注解里直接写sql语句就可以了。但是注解只适合简单的语句开发如果想要复杂的功能的话注解开发是非常麻烦的这时候还是使用xml文件完成sql语句的编写更好。
在接口方法上的注解有以下几类 Select 接口方法的返回值需要是一个实体且实体的字段必须跟表字段一致。这样一来查询到的结果会自动封装到实体之中。如果实体字段和表字段名字不一致封装是不会成功的。然而问题来了Java字段命名方式是小驼峰命名mysql字段命名方式是下划线命名总不能为了兼容强行把Java的字段名改成下划线命名或者强行把MySQL字段名改成小驼峰命名吧 解决方式有多种。 第一种就是在Select的sql语句中用as给MySQL表字段起别名别名跟Java的实体字段名字一致。 第二种是使用mybatis提供的Results注解和Result注解进行手动映射。 **第三种方式是最方便的。**在配置文件中写入配置让mybatis开启下划线和驼峰命名的映射。 另外在进行条件查询时会出现问题。 方法是使用字符串拼接函数concat。 Delete Insert 如果想要获得插入之后的主键可以添加一个注解让插入之后生成的主键赋值给实体的id属性。 Update
接口方法之中可以传入参数注解中对应位置使用#{}进行代替。 Java会通过反射获取到接口方法上的注解中的sql语句然后把sql语句发送给MySQL数据库执行。MySQL数据库接收到sql语句会先去缓存中查找是否存在这条sql语句如果是直接执行如果否先进行sql语法检查然后对sql进行优化然后编译sql然后把编译好的sql存入缓存以便下次执行一样的sql语句时提高性能。这种方式称为预编译sql。预编译SQL语句的过程是将SQL语句的结构和参数分离先将SQL语句编译为一个可执行的执行计划然后在每次执行时只需传入参数无需重新编译从而减少了重复解析和编译的开销。
delete from emp where id #{id}实际上传给MySQL的是delete from emp where id 以及id的值。如果直接传给MySQL的语句是delete from emp where id id那预编译sql就不起作用了。
预编译sql可以提高性能另外也可以防止sql注入攻击。
sql注入攻击是怎么一回事呢假设Java传给mysql的不是预编译sql形式的sql语句而是一个拼接成的完整sql语句select count(*) from user where name and password以查询账号和密码进行登录操作。这时候有人在表单中随便写了个账号但是密码写入or 11传给MySQL的语句是select count(*) from user where namefjewa;ofj and passwordor 11这条sql语句永远会成功用户无论是何种身份都可以登录。
预编译sql可以解决这个问题因为它明确了where的字段只有name和password不会有后面的or ‘1’ ‘1’。
4、日志输出
为了更加方便查看执行什么sql语句以及执行的结果需要查看日志。Mybatis默认是不打开日志的需要在配置文件中进行配置。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
5、xml映射文件开发
注解开发虽然方便但是只能执行简单的sql逻辑。想要执行复杂的sql逻辑需要使用xml文件编写sql语句进行开发。xml映射文件有一些规范。
xml映射文件的名称与Mapper接口名称一致并且将xml映射文件和mapper接口放置在相同包下同包同名。在maven项目中最后编译之后main包下的java和resource两个目录都会消失的。也就是说最后java和resource里面的文件都会在一个目录下。这样一来就可以在resource下创建sql映射文件在java里面创建接口只要sql映射文件和接口文件的目录写成一样的最后编译它们就会是一样的。注意在resource下创建层次接口不能是“com.ghl”的形式而是com/ghl的形式。xml映射文件的namespace属性为Mapper接口全限定名一致。方便映射xml映射文件中sql语句的id与mapper接口中的方法名一致并保持返回类型一致。方便映射
xml文件长什么样呢
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.iss.mapper.EmpMapper!--resultType:实体的全限定名执行结果会封装到实体之中--select idselectEmp resultTypecom.iss.entity.Empselect * from emp where id #{id}/select
/mapper想要调用接口中的方法来执行sql语句接口中的方法肯定是没有这样的功能的只有xml文件中才有sql语句。所以关键在于如何将接口中的方法与xml文件进行映射。只要按照上边的规范正确地在xml文件中写内容当调用接口中的方法时mybatis会自动根据接口找到对应的xml文件然后根据id找到方法对应的sql语句。
有一款插件可以挺方便根据接口跟xml文件的映射关系进行相互定位。MybatisX。 查询
xml映射文件中使用select标签来进行查询。这个标签的最重要的属性有两个一个是id用来和接口方法进行对应的一个是resultmap用来把查询到的数据封装进实体类的
准备工作 首先由于在实体对象里字段名使用驼峰命名但是在数据库的字段名有时候并不是使用驼峰命名所以有时候可能数据库的字段名与实体类的驼峰命名对应不上这样会使得数据无法完成封装。解决方法是在映射文件里的mapper标签里写一个resultmap标签这个resultmap标签里面主要有两种小标签id和result。id主要用来进行主键进行映射result主要用于对普通字段进行映射。两种小标签都有两个属性分别是column(真正的字段名)和property(实体类的驼峰命名)。写完之后把resultmap作为查询标签的属性就可以进行映射了。 接着查询语句里要有参数占位符用来指代接口方法传入的参数有两种参数占位符#{参数名}${参数名}前一种可以用来防止sql恶意注入黑客攻击后一种无法防止sql注入安全性会差一点。 注意在核心配置文件里面datasource标签里url那里一定要设置一个参数指定utf-8字符集不然字符串字段查询到的内容总是null
跟普通的sql查询差不多。就是可能有参数占位符存在。
要注意一点小于号要使用转义字符来写因为在xml文件里边小于号被认为是标签的起始不会被认为是小于号。使用转义字符 lt ; (这里由于markdown自动识别成小于号了所以我直接这里加了两个空格进行处理)。
动态查询/动态sql
有这么多个字段怎么知道用户想要查询哪个字段或者想要查询哪些字段呢当然可以把所有可能全部写一遍但是这样如果字段太多会显得非常愚蠢。所以可以使用一种比较好的方法动态查询。来实现动态查询多个字段的功能。
使用if标签配合where标签使用来实现动态查询
要实现动态查询其实就是在每一个条件上加上一个判断只要判断传入的参数不为空就使用这个参数进行查询就可以了。
所以使用if标签把条件给括起来逻辑符也要就可以了。但是if标签有一个问题就是如果传入的第一个参数为空这个参数恰好在第一个条件那么会变成 where and 字段名 参数2 这样的形式这不符合sql语法要求。**可以直接在where关键字的第一个条件写上11这样就不会出现这样的问题。不过mybatis提供了一个where标签直接使用where标签来代替where关键字就不会出现问题了**这个标签会自动处理。where标签只会在子元素有内容的情况下才会插入子句而且会自动去除子句开头的and和or。
if标签有一个属性test要在test里面写判断在标签体里写查询条件。 添加、修改和删除
添加
使用insert标签进行数据添加。里面直接写insert into语句进行添加就可以了。
一个小细节。如果主键是默认自增而且在执行接口方法的时候传入了一个没有定义主键的实体对象去添加数据库里产生了主键然而如何知道主键是什么呢这个问题的解决方法可以在insert标签里设置两个属性来解决。两个属性配置上实体中的主键字段在数据库添加完毕之后就会自动被赋值。 修改
使用update标签进行修改。
调用接口方法传入一个实体对象会根据实体对象的主键值和实体对象中每一个对象对应的值对对应记录的值进行修改。
动态修改如果按照上边那种方法来写的话那么每一次必定是修改数据库表中的全部字段。如果只想要修改某一些字段的话就可以使用动态修改。即在set关键字下方写上if标签。这里同样会有一些bug出现所以要将set关键字换成set标签。mybatis会自动解决bug冲突。
删除
**删除单条记录**写在delete标签里面。同样地如果想要动态删除使用where标签和if标签。
删除多条记录
这里如果不在xml文件里实现的话其实可以定义一个数组将要删除的记录的主键全部放到数组里边去然后遍历数组将数组里的元素一个一个传入接口方法里边就行。
不过mybatis对于这个东西有一个标签可以完成删除多条记录的功能。即foreach标签。这个标签用在where后边。
foreach有三个属性collection用于接收接口方法传入的数组mybatis会自动把这个数组放到一个map的值里边键是array。所以collection属性里直接写array就可以了。item属性就是要遍历的字段写上主键字段的名称就可以了。separator属性和open和close属性都是用来规范sql语法的。因为in后要有括号括号中的每一个字段之间要有逗号隔开。 两个标签sql和include。这两个标签是配套使用的。
在一个xml文件中如果出现了大量的重复sql片段可以使用这两个标签来解决。
select idselectAll resultMapBrandResultMapselect id,brand_name,enterprise_name,sort,introduction,statusfrom brand;
/select
select idselectById resultMapBrandResultMapselect id,brand_name,enterprise_name,sort,introduction,statusfrom brandwhere id #{id};
/select使用这两个标签过后会变为
!--id就是用来标识这段sql代码的--
sql idcommonSqlselect id,brand_name,enterprise_name,sort,introduction,status
/sql
select idselectAll resultMapBrandResultMap/*把sql的id填入refid*/include refidcommonSql/from brand;
/select
select idselectById resultMapBrandResultMap/*把sql的id填入refid*/include refidcommonSql/from brandwhere id #{id};
/select