1.mybatis简介。
JDBC有些东西太过繁琐。mabatis免除了很多代码。
2.mybatis快速入门
题目:查询user表种所有的数据。
为了解决硬编码。写一个mybatis-config.xml里
数据库查询写在mapper.xml。
2.1创建数据库
create table tb_user(
id int PRIMARY key,
username VARCHAR(20),
password varchar(20),
gender VARCHAR(1),
addr VARCHAR(30)
);
INSERT INTO tb_user VALUES(1,'zhangsan','123','男','北京');
INSERT INTO tb_user VALUES(2,'李四','123','男','天机阁');
INSERT INTO tb_user VALUES(3,'王五','123','男','北平');
2.2 pom里导入坐标
1.先导入mybatis
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
</dependencies>
2.为了连数据库。导入mysql的驱动jar。
为了写日志,得导入logback。
先写artifactid,然后alt+/ 补全。
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.24</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!--logback日志依赖-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.31</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.0-alpha12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.3.0-alpha12</version>
</dependency>
logback不仅需要坐标,还需要一个logback.xml配置文件。
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%level] %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<logger name="com.itheima" level="DEBUG" additivity="false">
<appender-ref ref="Console"/>
</logger>
<!--
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
, 默认debug
<root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
-->
<root level="DEBUG">
<appender-ref ref="Console"/>
</root>
</configuration>
mybatis-cofig.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>
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
<!--
environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment
-->
<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:///mabatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="a839846976"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mabatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="a839846976"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<mapper resource="UserMapper.xml"/>
<!--Mapper代理方式,文件路径sql-->
<!--<package name="UserMapper.xml"/>-->
</mappers>
</configuration>
写完UserMapper,需要在mybatis.xml,加在<mappers>里面。
2.3.编码。
pojo类写属性。
User类
package com.itheima.pojo;
/**
* @author Just Ching
* @create 2022-01-15 14:01
*/
public class User {
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", gender='" + gender + '\'' +
", addr='" + addr + '\'' +
'}';
}
private Integer id ;
private String username;
private String password;
private String gender ;
private String addr ;
}
MybatisTest测试我们已经写的查询小例子。
import java.util.List;
/**
* @author Just Ching
* @create 2022-01-15 14:08
*/
public class MybatisTest {
public static void main(String[] args) throws Exception {
//1.加载mybatis的核心配置文件,获取sqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession=sqlSessionFactory.openSession();
//3.执行sql
List<User> users = sqlSession.selectList("test.selectAll");//这里只需要xml里,传入sql语句的唯一标识和名称空间
System.out.println(users);
sqlSession.close();
}
}
目录结构写成这样,可以跑了。
2.4 数据库表报红解决。
发现映射文件写sql,数据库表报红。
这样做。
点击 蓝线上面的,小笔。甚至可以在里面写sql语句。
3.Mapper代理开发
入门里还是有一些硬编码。
改进之后,不依赖字面字符串的值。
获取结构类代理对象后,可以直接.来调用找个方法。
1.必须要整一个和xml文件同名的接口,接口里的方法就是xml文件里的id,保持接口与xml中参数类型和返回值一样。
2.最终要的是,xml和接口必须在同一个文件下。
3.但不建议在2这样放在痛一文件下,xml文件和java代码要分开放。
在resource里,new一个分层的,和mapper接口所在文件一样的directory(其实是包)。
com\itheima\mapper,不要用点。用\
然后给UserMapper拖进去,一定是拖,不能是复制。
然后编译完毕,xml文件,在target里和mapper接口在一起了。
3.1 编码。
Mapper.xml里修改。namespace里填的接口的路径,对应接口。
Mapper.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">
<!--
namespqce:名称空间
select id="selectBlog是SQL语句的唯一标识。
resultType是指数据要包装的类型,即查到的数据类型。
-->
<mapper namespace="com.itheima.mapper.UserMapper">
<select id="selectAll" resultType="com.itheima.pojo.User">
select * from tb_user;
</select>
</mapper>
然后在mybatis-config.xml里,改一下resource的路径。
注意,设的xml文件的路径。可以右键它。getPath
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>
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
<!--
environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment
-->
<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:///mabatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="a839846976"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mabatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="a839846976"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载sql映射文件-->
<mapper resource="com\itheima\mapper\UserMapper.xml"/>
<!--Mapper代理方式,文件路径sql-->
<!--<package name="UserMapper.xml"/>-->
</mappers>
</configuration>
MybatisTest2.java里执行。
注释原来的有字符串的,用代理对象来做。
MybatisTest2.java
package com.itheima.pojo;
import com.itheima.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.util.List;
/**mabatis代理开发。
* @author Just Ching
* @create 2022-01-15 14:08
*/
public class MybatisTest2 {
public static void main(String[] args) throws Exception {
//1.加载mybatis的核心配置文件,获取sqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession=sqlSessionFactory.openSession();
//3.执行sql
/*List<User> users = sqlSession.selectList("test.selectAll");
//这里只需要xml里,传入sql语句的唯一标识和名称空间*/
//3.1 获取UserMapper的代理对象。
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//反射。
List<User> users=userMapper.selectAll();
System.out.println(users);
sqlSession.close();
}
}
3.2改进
用这句话,可以直接去那个包里扫描xml,文件,所有的Mapper.xml都能加载。
4.MyBatis核心配置文件
配标签的时候一定要遵守前后顺序。
4.1envirment
1.配置多个数据源,比如现在想用test,测试数据源。通过default属性来切换。
2.datasource,配数据库连接。
3.之前写类型的时候,写了个路径,很麻烦。mybatis里可以自定义别名。
这样写就相当于,给pojo下面的类,起了个别名。这个别名不区分大小写。
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
这里直接小写user也行。
5.配置文件完成增删改查
这个叫statement。与mapper接口里一一对应。
在接口里写方法,自动去xml里给你加statement。
里面可以写SQL
5.1 查询时碰到的小问题
字段与数据库里字段不一致,导致有些数据不能被封装。控制台里输出为null。
解决办法1:写一个sql片段,用别名。
建议用解决方法2:用一个resultMap来接收数据库的值,然后映射给实体类,完成封装。
然后换掉resultType的值,为
resultMap id="brandResultMap"
5.1.1 总结与具体
5.2查询————查看详情
这里用的#{id},来接收id。实际上还有个字段 parameter 来规定传进来值得类型。
参数占位符:
1.#{},会将其替换成?,防止SQL注入。
2.${},拼sql,会出现SQL注入。
3.使用时机:参数传递进去用#{},如果表名或列名不固定,用$来传表或者列。
如果用<号判断会出错,因为与<>冲突。
解决办法1:转义字符
解决办法2:CDATA区。把小于号写在里面。
5.2.1 多条件查询
用户想搜两个字就出来好多行可以选择。所以用模糊查询。
三种接收参数的方式。1.@param(“占位符里的属性”)加定义。
2.传对象。
3.传map
这里2.3两种方法都是解析成了Map,存键值。传的对象最后也称了Map。
三种传值方式。SQL语句不用变。
第二种用对象传的时候
第三种用map,键的值要用“”包起来,键的名称就是SQL里#接收的名称。
这里遇到一个小问题,值都传对了,但搜不到正确的值。
在mybatis-config里修改url,加上&useUnicode=true&characterEncoding=utf-8。
5.2.2 多条件——动态条件查询
1.用if标签(笨方法 where 后面加 1=1),test里面写传进来的属性名的逻辑表达式。
但有一个问题,如果status为null,没传值。SQL语句就成了
where and company_name like #{}。就会出错。
解决:每个if标签里的语句前都加and,然后在where后面加 1=1 ,就可以连接and。满足语法要求。
2.where标签包裹解决(mybatis的聪明方法)
可以帮你自动去and。
5.2.3单条件----动态sql查询。
choose标签类似 switch
,这里记得改成这样。不然没封装进去。
那如果用户一个都没选,直接空的来搜索,怎么处理?
这个时候<otherwise>标签就很重要了。
但直接上where标签,也可以,如果where标签里的都是错误的。
where 会自动
5.3 添加
添加完了得手动提交事务,不然数据库那里不更新信息。
这里给事务回滚了。
也可以这里设置为true,不用在commit
5.3.1 获取插入数据的主键(id)的值
keyProperty=“id”,Brand类里的对象在数据库里的id,就可以被拿出来。可以用
brand.getId(),方法得到数据库里新生成的id。
5.4 修改字段
5.4.1 修改全部字段
5.4.2 修改动态字段
就比如用户重置密码,提交过来的只有password
如果我们注释几行代码,只给这个新对象理赋部分的值。
sql语句中国,用来传值的对象,的部分属性值为null。
最后一个逗号的问题用 <set>标签来解决。<set>标签用来写动态修改。
5.5删除
5.5.1删除一个
5.5.2 批量删除
选中的几个的,id的值提交到后台。id被封装成数组,一次性接收。
如果数组里有3个id,这里会生成这样。中间一行是三次遍历的结果。应该用逗号隔开,用separtor。
open和close ,拼括号。open是foreach标签,前的啥字符。比如这里前面是(。
5.6 参数传递
学习MyBatis如何封装这些参数。
进ParamNameResolver里看源码。
name里装的是arg0,arg1.。。。具体看传了几个参数。
我debug了一个数组。不加注解。参数名是这俩。
然后加了@param(“ids”)注解。参数名编程了这俩。
第一次在map里循环,先生成了ids,再生成的param1。
5.6.1不加注解的时候
这里1.2 两种方法都是解析成了Map存键值。
5.6.2 加了注解后
这里加了注解username,arg0就被换成了username。
5.6.3 默认键名。
就是arg0,arg1.。。。参数提交的时候用map存,系统默认的键名。
键名----》参数。这样存。
5.6.4思考
这里在sql里直接user.username,即可。用了反射。
5.6.5注解开发
简单的查询,写在注解里,比较复杂的比如动态SQL,还是得需要mapper.xml。