目录
(2)使用Druid数据库连接池操作数据库步骤及相关代码实例
2.编写Mybatis的核心配置文件----》数据库连接信息及其它重要配置
(1)配置文件名:mybatis-config.xml(附带类型别名操作)
(2)创建sql映射文件并且更改mybatis-config.xml中的(未更改)
(1) 定义与sql映射文件同名的mapper接口,并将mapper接口与sql映射文件放置在同一目录下。
(2)把sql映射文件的nasmespace属性设置为对应mapper接口的包路径
(5)包扫描,解决过多sql映射文件路径在mybatis核心配置文件中的逐个添加的繁琐过程。
(6)任务:在settings-plugins里面下载MybatisX插件,在官网学会使用
(10)条件查询——多条件查询 (Mybatis如何接收多个参数)
一、JDBC
1.JDBC基本配置
示例代码:
package com.wangrongxiao.jdbc;
import com.mysql.jdbc.Driver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class demojdbc {
public static void main(String[] args) throws Exception {
//1.注册驱动
//Class.forName("com.mysql.cj.jdbc.Driver") ;
//2.获取连接
String url ="jdbc:mysql:///shop";//ip和端口号localhost:3306
String user = "root";
String password = "root";
Connection coon = DriverManager.getConnection(url, user, password);
//3.定义sql语句
String sql = "UPDATE stu1 SET name = \"高黎\" WHERE id = 2";
//4.获取执行sql对象
Statement stmt = coon.createStatement();
//5.执行sql
int count = stmt.executeUpdate(sql);//获取执行次数
//6.处理返回的结果
System.out.println("受影响"+count+"行");
//7.释放资源
coon.close();
stmt.close();
}
}
2.数据库连接池Druid的配置文件
(1)Druid的配置文件
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///shop?useSSL=false&useServerPrepStmts=true #useServerPrepStmts=true 预编译,高效率
username=root
password=****
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
#最大等待时间
maxWait=3000
如何配置 ——示例代码
public static void main(String[] args) throws Exception {
//1.第一步导入jar包
//2.第二步定义配置文件后缀名是properties 在new里选择Resource Bundle
//3.第三步加载配置文件
Properties prop=new Properties();
prop.load(new FileInputStream("jdbc/src/druid.properties"));//导入要配置的文件地址
//4.获取连接
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5.获取数据库连接
Connection coon = dataSource.getConnection();
System.out.println(coon);
//System.out.println(System.getProperty("user.dir"));寻找路径
}
(2)使用Druid数据库连接池操作数据库步骤及相关代码实例
实体类和主方法:
package com.wangrongxiao.pojo;
public class testBrand {
// id 主键
private Integer id ;
// 品牌名称;
private String brand_name ;
// 企业名称
private String company_name ;
// 排序字段
private Integer ordered ;
// 描述信息
private String description ;
// 状态:0:禁用 1:启用
private Integer STATUS ;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBrand_name() {
return brand_name;
}
public void setBrand_name(String brand_name) {
this.brand_name = brand_name;
}
public String getCompany_name() {
return company_name;
}
public void setCompany_name(String company_name) {
this.company_name = company_name;
}
public Integer getOrdered() {
return ordered;
}
public void setOrdered(Integer ordered) {
this.ordered = ordered;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getSTATUS() {
return STATUS;
}
public void setSTATUS(Integer STATUS) {
this.STATUS = STATUS;
}
@Override
public String toString() {
return "testBrand{" +
"id=" + id +
", brand_name='" + brand_name + '\'' +
", company_name='" + company_name + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", STATUS=" + STATUS +
'}';
}
}
package com.wangrongxiao.Example;
import com.wangrongxiao.pojo.testBrand;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.awt.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
/**
*
* Brand项目
*1.SQL语句
* 2.是否需要参数
* 3.结果list<Brand>
*
*/
public class test {
public static void main(String[] args) throws Exception {
//加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("jdbc/src/druid.properties"));
//获取连接
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
Connection coon = dataSource.getConnection();
//写sql语句
String sql = "select * from tb_brand ";
//获取数据库连接,处理sql
PreparedStatement pstate = coon.prepareStatement(sql);
//是否需要参数赋值:这里由于sql语句中没有?占位符的使用故不需要参数 详见jdbc5_denglu2
//处理sql,带回返回值
ResultSet rs = pstate.executeQuery();
//处理结果list<Brand>
testBrand brand = new testBrand();
List<testBrand> list = new ArrayList<>();
while(rs.next()){
//获取数据
int id = rs.getInt("id");
String brand_name = rs.getString("brand_name");
String company_name = rs.getString("company_name");
int ordered = rs.getInt("ordered");
String description = rs.getString("description");
int status = rs.getInt("status");
//把数据封装入对象
brand.setId(id);
brand.setBrand_name(brand_name);
brand.setCompany_name(company_name);
brand.setOrdered(ordered);
brand.setDescription(description);
brand.setSTATUS(status);
System.out.println(brand);
//装入集合
list.add(brand);
}
System.out.println(list);
//释放资源
coon.close();
pstate.close();
rs.close();
}
}
二、Maven
1.Maven是什么?有啥用?
2.在ide中配置maven
3.依赖
三、Mybatis入门
(先创建user表,要用)
1.在maven中创建模块:
(必须)导入Mybatis的依赖;其次为mysql的依赖;
mysql依赖的版本号换成8以上。
(不必须)测试用的test的junit的依赖;以及日志依赖
<dependencies>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</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>
备注:若是用到日志,还需要添加一个logback配置文件
logbak日志的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %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>
添加在resources(配置文件)
2.编写Mybatis的核心配置文件----》数据库连接信息及其它重要配置
(1)配置文件名:mybatis-config.xml(附带类型别名操作)
配置文件内容:
文件中需要更改的是注释部分(1):更改数据库连接信息(已更改)
(2):更改mappers(未更改)
<?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.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载SQL的映射文件 -->
<mapper resource="org/mybatis/example/BlogMapper.xml"/> <!--双引号里的是sql映射文件的路径(带有mapper) -->
</mappers>
</configuration>
注:可以在,<config>上面添加类型别名,以后用到type就不用再填写整个包路径了。
(2)创建sql映射文件并且更改mybatis-config.xml中的<mappers>(未更改)
注:文件名的格式为其中sql语句操作的对应的表明Mapper.xml 例如:userMapper
1. 在此之前,我们需要先创建一个用来处理封装数据的pojo包里的实体类 ,这里我创建的表是tb_user,所以我创建的是user实体类:com.pojo.tbUser。
实体类中的构造器使用不再赘述!
2. 然后我们创建userMapper.xml这个sql映射文件,并作相应的修改,备注中已经说明
第一步把这段代码写入:(涉及到接口的注释,下节mapper代理开发会提及,这里这个名字可以随便写)
<?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">
<!--namespace命名空间的名字要和对应的Mapper接口的限定名一致(包路径)-->
<mapper namespace="com.mapper.userMapper">
<!-- id是这个sql映射的唯一标识,Mapper接口里的方法名与其一样 -->
<!-- resultType是返回值类型这里我们的返回值类型设定为tbUser,应填入它的包路径 -->
<select id="selectAll" resultType="com.pojo.tbUser">
select * from tb_user;
</select>
</mapper>
第二步:在核心配置mybatis-config.xml的<mappers>中添加对应的sql映射文件的路径(带有Mapper.xml的文件)
<mappers>
<!--加载SQL的映射文件 -->
<mapper resource="userMapper.xml"/> <!--双引号里的是sql映射文件的路径(带有mapper) -->
</mappers>
(3)创建一个demo类完成主方法
public static void main(String[] args) throws IOException {
//第一步加载Mybatis核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession对象并执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql
List<tbUser> brands = sqlSession.selectList("test.selectAll");
//处理结果
System.out.println(brands);
sqlSession.close();
}
(非必要)注:如果报错应该是没有自动导包
可加入下面的包:
package com.wangrongxiao.wanngrongxiao;
import com.wangrongxiao.pojo.tbUser;
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.IOException;
import java.io.InputStream;
import java.util.List;
在此一个mybatis的项目初始化完成了
四、idea与自己的数据库建立连接解决sql警告
1.
2. 点击加号
3.选择自己对应的数据库,我用的是mysql
4.
也要输入的有三项mysql的用户user,密码password,数据库名database
按照下面顺操作即可
出现set time 问题也就是时区不一样的可以参照这位大哥的博客:(27条消息) IDEA连接数据库时,时区修改问题_静谧人的博客-CSDN博客_idea 修改时区
以上步骤完成就完成了数据库的连接。
也可以在url后面添加 ?driverTimezone=GTM
五、mapper代理简化数据查询
(1) 定义与sql映射文件同名的mapper接口,并将mapper接口与sql映射文件放置在同一目录下。
1. 我们先定义接口:接口中有一个方法,方法名与对应的sql映射文件的id同名。
我们在com.mapper中定义usermapper.xml的同名接口userMapper。
2.如何把两个不同类型的文件放在一起呢?
(1).在resources中新建目录Directory,与建包不同的是把 “ . ” 换成 " / "就可以了.
(2).做到与接口的路径一致,接口是com.mapper.userMapper
那我们要做到路径一致只需要创建时输入:com/mapper 然后把userMapper.xml拉进来就可以了
别忘了更改核心配置文件中的sql映射文件的路径:右键Copy path就okk了
或者直接采用包扫描的方法:
<mappers>
<!--加载SQL的映射文件 -->
<package name="com.mapper"/>
<!-- <mapper resource="com/mapper/userMapper.xml"/> <!–双引号里的是sql映射文件的路径(带有mapper) –>-->
</mappers>
(2)把sql映射文件的nasmespace属性设置为对应mapper接口的包路径
代码如下:
<?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">
<!--namespace命名空间的名字要和对应的Mapper接口的限定名一致(包路径)-->
<mapper namespace="com.mapper.userMapper">
<!-- id是这个sql映射的唯一标识,Mapper接口里的方法名与其一样 -->
<!-- resultType是返回值类型这里我们的返回值类型设定为tbUser,应填入它的包路径 -->
<select id="selectAll" resultType="com.pojo.tbUser">
select * from tb_user;
</select>
</mapper>
(3)给接口创建方法
先看usermapper.xml里的内容:
我们的方法与这里面的id同名:
package com.mapper;
import com.pojo.tbUser;
import java.util.List;
public interface userMapper {
List<tbUser> selectAll();
}
(4)编码
package com.pojo;
import com.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;
public class demo {
public static void main(String[] args) throws Exception {
//第一步加载Mybatis核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession对象并执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
userMapper userMapper = sqlSession.getMapper(userMapper.class);
List<tbUser> tbUsers = userMapper.selectAll();
//执行sql
//ist<tbUser> brands = sqlSession.selectList("test.selectAll");
//处理结果
System.out.println(tbUsers);
sqlSession.close();
}
}
这就是mapper代理的初始化过程,还是比较麻烦的。
(5)包扫描,解决过多sql映射文件路径在mybatis核心配置文件中的逐个添加的繁琐过程。
<mappers>
<!--加载SQL的映射文件 -->
<package name="com.mapper"/>
<!-- <mapper resource="com/mapper/userMapper.xml"/> <!–双引号里的是sql映射文件的路径(带有mapper) –>-->
</mappers>
附赠我的代码:
1.userMapper接口
package com.mapper;
import com.pojo.tbUser;
import java.util.List;
public interface userMapper {
List<tbUser> selectAll();
}
2.demo
package com.pojo;
import com.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;
public class demo {
public static void main(String[] args) throws Exception {
//第一步加载Mybatis核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession对象并执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
userMapper userMapper = sqlSession.getMapper(userMapper.class);
List<tbUser> tbUsers = userMapper.selectAll();
//执行sql
//ist<tbUser> brands = sqlSession.selectList("test.selectAll");
//处理结果
System.out.println(tbUsers);
sqlSession.close();
}
}
3.tbUser
package com.pojo;
/**
*
* 实体类user
*/
public class tbUser {
private int id ;
private String username ;
private String password ;
private String gender ;
private String addr ;
public int getId() {
return id;
}
public void setId(int 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 + '\'' +
'}';
}
}
4.userMapper.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">
<!--namespace命名空间的名字要和对应的Mapper接口的限定名一致(包路径)-->
<mapper namespace="com.mapper.userMapper">
<!-- id是这个sql映射的唯一标识,Mapper接口里的方法名与其一样 -->
<!-- resultType是返回值类型这里我们的返回值类型设定为tbUser,应填入它的包路径 -->
<select id="selectAll" resultType="com.pojo.tbUser">
select * from tb_user;
</select>
</mapper>
5.logback
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %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>
6.mabatis-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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--数据库连接信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加载SQL的映射文件 -->
<package name="com.mapper"/>
<!-- <mapper resource="com/mapper/userMapper.xml"/> <!–双引号里的是sql映射文件的路径(带有mapper) –>-->
</mappers>
</configuration>
7.pom.xml的依赖
<dependencies>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</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>
(6)任务:在settings-plugins里面下载MybatisX插件,在官网学会使用
1.先创建mapper接口
2.创建对应的sqlMapper.xml并且namespace与接口绑定
3.在接口中写方法,对准方法alt+enter自动在映射文件里创建对应的sql语句的唯一标识id
(7)resultMap的使用
由于我们使用的数据库列名有时候和实体类的属性名有时候会差错性质的写错,就会导致无法封装写错属性名的那里一列的数据。resultMap是一种将错就错的方法。
下面介绍代码实例:
在brandMapper.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">
<!--namespace命名空间的名字要和对应的Mapper接口的限定名一致(包路径)-->
<mapper namespace="com.mapper.brandMapper">
<select id="selectall" resultMap="brandResultMap">
select *
from tb_brand;
</select>
<!--resultMap的使用-->
<!-- id :是resultMap的唯一标识
type :为封装的数据类型
-->
<resultMap id="brandResultMap" type="Brand">
<!-- id:完成主键字段的映射
result:完成非主键字段的映射
column;在数据库里的列名
property;实体类的属性名
-->
<result column="brand_name" property="brandName"></result>
<result column="company_name" property="companyName"></result>
</resultMap>
</mapper>
(8)关于xml中的sql语句的一些特殊情况
1.参数占位符一般使用#{} , ${}有sql注入的风险
2.sql语句中的特殊字符:
像 “ < ” 这种类型的字符在xml中是分辨不清楚意思的。使用CDATA避免特殊字符干扰
代码示例:
<?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">
<!--namespace命名空间的名字要和对应的Mapper接口的限定名一致(包路径)-->
<mapper namespace="com.mapper.brandMapper">
<!---->
<select id="selectall" resultMap="brandResultMap">
select *
from tb_brand ;
</select>
<select id="selectById" resultMap="brandResultMap">
<!--参数占位符
1.#{}:在执行sql时候,会将#{}占位符替换成?,将来自动设置参数值
2.${}: 拼sql。会存在sql注入的问题。
3.使用时机:
*参数传递都是用#{}
*如果要对表名、列名惊醒动态设置,只能使用${}进行sql拼接
-->
<!-- CDATA区对特殊字符进行处理,使用时属性为纯文本 -->
select *
from tb_brand where id
<![CDATA[
=
]]>#{id};
</select>
<!--resultMap的使用-->
<!-- id :是resultMap的唯一标识
type :为封装的数据类型
-->
<resultMap id="brandResultMap" type="Brand">
<!-- id:完成主键字段的映射
result:完成非主键字段的映射
column;在数据库里的列名
property;实体类的属性名
-->
<result column="brand_name" property="brandName"></result>
<result column="company_name" property="companyName"></result>
</resultMap>
</mapper>
(9)mapper代理方式增删改查的步骤
1.编写接口方法
2.参数:所有查询条件
3.结果:List<Brand>(因为我的实体类有Brand类)
4.编写sql语句:sql映射文件
5.执行方法
(10)条件查询——多条件查询 (Mybatis如何接收多个参数)
1.使用注解的方式,对应sql语句中的占位符
这个是在接口中的方法:
@Param(sql语句占位符相同的名字)
List<Brand>selectByCondition(@Param("status") int status,@Param("companyName")String companyName,@Param("brandName")String brandName);
这是测试代码:
@Test
public void testSelectBy() throws IOException {
/***
* 散装接受方式接收数据
* mapper
*参数
*结果集合
* 编写sql语句:sql映射
* 执行方法,测试
*/
int status = 1;
String companyName = "华为";
String brandName = "华为";
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
//第一步加载Mybatis核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession对象并执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);//注解的方式找到对应的占位符
System.out.println(brands);
}
2.使用封装对象的方法,把接收的数据传入Brand对象
这个是在接口中的方法:
//对象接受
List<Brand>selectByCondition(Brand brand);
这是测试代码:
@Test
public void testSelectByBrand() throws IOException {
/***mapper
*参数
*结果集合
* 编写sql语句:sql映射
* 执行方法,测试
*/
int status = 1;
String companyName = "华为";
String brandName = "华为";
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
Brand brand = new Brand();
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setStatus(status);
//第一步加载Mybatis核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession对象并执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
List<Brand> brands = brandMapper.selectByCondition(brand);
System.out.println(brands);
}
关键在于利用Set方法把数据封装成对象。(类似于JDBC把查到的数据封装成对象)
3.使用Map对象
这个是在接口中的方法:
//map集合
List<Brand>selectByCondition(Map map);
这是测试代码:
@Test
public void testSelectByMap() throws IOException {
/***
* brand对象方式接收对象
* mapper
*参数
*结果集合
* 编写sql语句:sql映射
* 执行方法,测试
*/
int status = 1;
String companyName = "华为";
String brandName = "华为";
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
Map map = new HashMap();
map.put("status",status);
map.put("companyName",companyName);
map.put("brandName",brandName);
//第一步加载Mybatis核心配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession对象并执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
List<Brand> brands = brandMapper.selectByCondition(map);
System.out.println(brands);
}
例如map.put("status",status);
我们要把put方法中map的键设为同名的占位符.
(11)条件查询——动态条件查询
<1>前言:首先我们看为啥要动态查询
<select id="selectByCondition" resultMap="brandResultMap">
select * from tb_brand where
status = #{status}
and company_name like#{companyName}
and brand_name like#{brandName}
</select>
<案例一> 有没有一种可能:我们接受数据的时候,用户没有三个都传入,而是传了其中一个或者两个。这样系统编译时候,执行sql的时候就会出错。
例如:就上述代码,我们只传入了status,那么sqlSession在执行sql时得到的SQL语句就是:
select * from tb_brand where
status = #{status}
and company_name like %null%
and brand_name like %null%
这种情况显然在数据库里是没有对应的信息的。
<2>接下来引入 <where>和<if>标签
1. 关于不参与数据传入的占位符我们使用 <if test = " 逻辑表达式" > 进行判断。
<!-- test里面放逻辑表达式
test的判断对象名应是对应实体类的属性
-->
<!--注意是字符串还要判断是不是空字符串-->
<select id="selectByCondition" resultMap="brandResultMap">
select * from tb_brand
where
<if test="status != null">
status = #{status}
</if>
<if test="brandName != null and brandName != ''">
and brand_name like #{brandName}
</if>
<if test="companyName != null and companyName != ''">
and company_name like #{companyName}
</if>
</select>
<案例二>但是着这种情况还有新的bug产生,那就是如果我们where表达式的第一位status是空的。那么编译时候得到的
sql表达式也会出现了语法的错误:你看 where and 连在一起了
select * from tb_brand
where and brand_name like #{brandName}
and company_name like #{companyName}
<3>我们引入<where>标签
针对<案例二>的解决方案<where>标签:我们用<where>包裹住sql语句即可,它会自动修正你的非致命sql语句格式
<select id="selectByCondition" resultMap="brandResultMap">
select * from tb_brand
<where>
<if test="status != null">
status = #{status}
</if>
<if test="brandName != null and brandName != ''">
and brand_name like #{brandName}
</if>
<if test="companyName != null and companyName != ''">
and company_name like #{companyName}
</if>
</where>
</select>
(12)条件查询——动态条件查询——单条件查询
应用场景:此时我们只能三选一,但是sql应该做好三条都能被识别的准备
*choose--->switch
*when------>Case
*otherwise--->default
+++ when包裹着部分sql,when后面的test需要写逻辑表达式确认是否参与sql语句
+++<choose>包裹着所有的<when>
+++<otherwise>包裹着其他选择
<!-- 单条件查询选择时候需要注意,此时的逻辑表达式在when后面的test里 -->
<select id="selectByCondition" resultMap="brandResultMap">
select * from tb_brand
<where>
<choose>
<when test="status != null">
status = #{status}
</when>
<when test="brandName != null and brandName != ''">
and brand_name like #{brandName}
</when>
<when test="companyName != null and companyName != ''">
and company_name like #{companyName}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
(13)完成添加功能
1.在接口添加方法
// 添加方法
void sqlAdd(Brand brand);
2.在sql映射里写方法(没有返回值)
<!--在 insert 标签上添加如下属性:
useGeneratedKeys:是够获取自动增长的主键值。true表示获取
keyProperty :指定将获取到的主键值封装到哪儿个属性里-->
<mapper namespace="com.mapper.brandMapper">
<insert id="sqlAdd" >
insert into tb_brand(brand_name,company_name)
values (#{brandName},#{companyName})
</insert>
3.如何返回主键id:
在 insert 标签上添加如下属性:
useGeneratedKeys:是够获取自动增长的主键值。true表示获取
keyProperty :指定将获取到的主键值封装到哪儿个属性里。
<!--在 insert 标签上添加如下属性:
useGeneratedKeys:是够获取自动增长的主键值。true表示获取
keyProperty :指定将获取到的主键值封装到哪儿个属性里-->
<mapper namespace="com.mapper.brandMapper">
<insert id="sqlAdd" useGeneratedKeys="true" keyProperty="id">
insert into tb_brand(brand_name,company_name)
values (#{brandName},#{companyName})
</insert>
之后调用get方法就可以看到id了。
(14)完成改功能
1.接口方法,返回值可以为int 和 void
// 修改的方法
void Update(Brand brand);
2.sql映射
*****备注:如果没有使用set标签,因为set后面的 “ , ”可能会导致运行错误******
<set>标签引入:set 标签可以用于动态包含需要更新的列,忽略其它不更新的列。
下面的代码基本通用:
<!-- set 标签可以用于动态包含需要更新的列,忽略其它不更新的列。-->
<update id="Update">
update tb_brand
<set>
<if test="status != null">
status = #{status},
</if>
<if test="brandName !=null and brandName != ''">
brand_name = #{brandName},
</if>
<if test="companyName !=null and companyName != ''">
company_name = #{companyName},
</if>
<if test="ordered != null">
ordered = #{ordered},
</if>
<if test="description !=null and description != ''">
description = #{description},
</if>
<if test="status != null">
status = #{status}
</if>
</set>
where id = #{id}
</update>
3.执行代码
(15)完成删除功能-----foreach标签遍历数据
<1>删除单个数据
1.接口方法,返回值类型void
// 删除一个数据
void delectById(int id);
2.sql映射
<!-- 删除一个数据据,通过id-->
<delete id="delectById">
delete from tb_brand where
id = #{id}
</delete>
3.参数(略)
4.运行(略)
<2>批量删除数据-----foreach标签遍历数组
原理:基本原理就是同时接收多个id,把这些id信息放进一个数组里,在sql语句中
使用in关键字,然后在in(遍历数组)。
接下来我们引入必备知识:
<foreach>标签:作用是在Mybatis里遍历数据。
1.接口方法:
// 批量删除
void DelectByIds(@Param("ids") int[] ids);
//过程1 arrmy = ids
//过程2 ids <--arrmy
!!!!备注:Mybatis会把数组参数封装成一个Map集合arrmy。若是在foreach中填写collection时使用数组名,则需要使用@param注解他数组名注解成要写的数组名,否则collection就必须写arrmy!!!!
具体使用方法如下代码:
2.sql映射
<!-- <foreach>标签可以遍历数据,但是Mybati会把数组参数
封装成一个Map集合:*** arrmy = ints
*** 使用@param注解绑定ints @param("ints")
-->
<delete id="DelectByIds">
delete from tb_brand where
id in (
<foreach collection="ids" item="id" separator=",">
#{id}
</foreach>
)
</delete>
3.参数传递过程
要把参数放进一个数组里:
(16)参数传递
备注 :以下情况的参数传递都要使用@param注解,原因和(15)里的int[] ids 一样。
(17)注解开发
备注:此开发适用于简单的查询。复杂的查询尽量用sql映射文件完成。
我的代码示例:
mapper接口:
@Select("select * from tb_user where id = #{id}")
List<tbUser> selectByID(int id);
@Insert("insert tb_user(username,password) values(#{userName},#{password}) ")
void Add(tbUser user);
@Select("select * from tb_user")
List<tbUser>selectall();
在主方法里的使用方法不变。