JavaWeb4——Mybatis框架(与数据库交互)
2022/7/4
Mabatis作为一款优秀的持久层框架,用来简化JDBC开发,封装核心内容(半成品软件,软件基础代码模型)
一、基础配置
一样新建Maven项目,注意java和test以及对应的resources关系确定。
项目的pom.xml下需要通过maven进行一些必需jar包的导入。包括以下部分:
<dependencies>
<!--mybatis 依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.8</version>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!--junit 单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
<!--添加slf4j日志api-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<!--添加logback-classic依赖-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!--添加logback-core依赖-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
接着,在项目的resources中,也需要添加对应的xml文件来配置各个导入内容:主要包括:
mybatis-config.xml:(这部分可以用官方入门来初学,注意这里启用了mapper代理方式)
<?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>
<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/mybatis?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="liu124302909"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件 基础方法-->
<!--<mapper resource="com/hanzhe/mapper/UserMapper.xml"/>-->
<!--mapper代理方式-->
<package name="com.hanzhe.mapper"/>
</mappers>
</configuration>
logback.xml(日志输出用)
UserMapper.xml(后续与mapper代理开发密切相关,这里仅作一个User类查询的简单示例):
<?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="com.hanzhe.mapper.UserMapper">
<select id="selectAll" resultType="com.hanzhe.pojo.User">--
select * from tb_user;
</select>
</mapper>
这个部分对应着对应SQL表内User内容的查询,注意这里给出的resultType,需要在对应目录下新建java类,这样mybatis可以自动在导入数据库数据时,填写有关内容。(内部写好数据定义,getset方法,tostring语句来检查)
二、mapper代理开发
上述给出的配置已经有所说明,用mapper代理开发可以采用映射的方式来让选用方法更简单;让mapper可以自动扫描,前提是在同一个目录下。总之规避一些重复内容来简化开发。
目录结构上,注意resources下不能直接采用package的形式对应建立目录结构。为了保证配置加载和类的加载在同一个目录下,进而能够扫描到mapper,需要按照例如com/hanzhe/mapper在idea内建立目录。再把配置好的mapper的xml文件放进去,并且修改namespace路径,就可以完成配置。
三、操作——全部查询
使用时的模板:
@Test
public void testSelctAll() throws IOException {
//1. 获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 获取Mapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 执行方法
List<Brand> brands = brandMapper.selectAll(); //这是整个过程的核心,剩下都是一样的
System.out.println(brands);
//5.释放资源
sqlSession.close();
}
mapper配置学习:(xml)
为了规避SQL和java类属性不一致的问题:
使用as改名:
<select id="selectAll" resultType="brand">
select id, brand_name as brandName, company_name as companyName, ordered, description, status
from tb_brand;
</select>
使用sql来建个库:
<sql id="brand_column">
id, brand_name as brandName, company_name as companyName, ordered, description, status
</sql>
最有效和常用的,resultMap:
<!--
id 是一个唯一标识 主键
type 映射的类型,支持别名
-->
<resultMap id="brandResultMap" type="brand">
<result column="brand_name" property="brandName" />
<result column="company_name" property="companyName" />
</resultMap>
<select id="selectAll" resultMap="brandResultMap">
select
*
from tb_brand;
</select>
四、操作——查看详情(条件查询):
使用参数传递和占位符完成SQL就可以了;
关于参数占位符:
1、#{}:会将其替换为?,为了防止SQL注入
2、${}:拼sql,会存在SQL注入问题
3、使用时机:参数传递用#{},表名或者列名不固定的情况下:${},但存在SQL注入问题
参数类型:parameterType,一般可以省略,因为java接口已经规定好了,相互匹配
特殊字符处理:
1、转义字符
2、CDATA区
select
*
from tb_brand where id
<![CDATA[
<
]]>
#{id};
<!--转义-->
select
*
from tb_brand where id < #{id};
五、操作——添加:
前述相同,注意的问题在于,可以使用主键返回来获取id。
<insert id="add" useGeneratedKeys="true" keyProperty="id">
insert into tb_brand(brand_name, company_name, ordered, description, status)
values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
</insert>
另外事务注意commit确保结果成功加入数据库,当然也可以在sqlSession创建时打开autocommit。
六、操作——修改
注意动态修改,实际上和动态查询大同小异。类似于where可以开set标签来防止出现格式问题。
<update id="updateByCondition">
update tb_brand
<set>
<if test="status != null">
status = #{status},
</if>
<if test="companyName != null and companyName != '' ">
company_name = #{companyName},
</if>
<if test="brandName != null and brandName != '' ">
brand_name = #{brandName},
</if>
<if test="ordered != null">
ordered = #{ordered},
</if>
<if test="description != null and description != '' ">
description = #{description}
</if>
</set>
where id = #{id}
</update>
七、操作——删除
通用批量删除,主键查询删除(当然也可以通过查询类似的方式删除)。注意foreach标签的使用简化。
<delete id="deleteByIds">
delete from tb_brand where id
in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
其中collection标出了java定义的参数(使用@Param进行参数标注,否则需要指定"array"),item表示内容,separator是sql语句内部的分隔符,open,close可以补充不完整的"()",使美观。
八、参数传递:
MyBatis接口方法可以接收各种参数,底层有不同的处理方式。
单个参数:
1、POJO类型:直接使用,实体类属性和参数占位符名称一致;
2、Map集合:直接使用,键名和参数占位符一致;
3、Collection集合,封装为Map集合:
map.put("collection", list集合);
map.put("list", list集合);
map.put("arg0", list集合);
4、Array封装为Map集合:
map.put("array", 数组);
map.put("arg0", 数组);
5、其它类型:直接使用即可
多个参数:(封装为Map集合)
map.put("arg0", 参数值1); //注解替换这个部分的键名
map.put("param1", 参数值1);
map.put("arg1", 参数值2);
map.put("param2", 参数值2);
最好使用@Param注解来修改Map集合中默认的键名,并且使用修改后的值来获取值,这样可读性会提高。
九、注解开发:
会简化简单的用法,但是复杂语句编写还是需要xml配置。
@Select("select * from tb_user where id = #{id}")
public List<Brand> selectAll();