一、数据库
1.1mysql的安装
官网自行下载
下载完后再系统高级配置中配置相应的路径和环境变量,命名 MYSQL_HOME = “path”
【mysql】
default-character-set=utf8
【mysqld】
character-set-server=utf8
default-storage-engine=INNODB
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_
ENGINE_SUBSTITUTION
在mysql文件夹下创建文件my.ini(注意扩展名为.ini),将上面的代码复制到该文件中
1.2 mysql使用
mysqld --initialize-insecure
会在目录中生成一个data文件夹,数据文件夹,存储的是数据信息
mysqld -install
注册mysql服务
net start mysql
net stop mysql
启动
注销
mysqladmin -u root -p 12345
修改密码 ,密码可以改成你的密码
mysql -uroot -p12345
登录mysql
1.3操作数据库(DDL)
show databases;//查询
create database database_name;//创建
create database if exists database_name;//创建数据库,是否存在
drop database database_name;//删除数据库
drop database if exists database_name;//同上
select database();//查看当前使用的数据库
use database_name;//使用数据库
1.4操作表(DDL)
1.4.1查询 创建
创建
查询
1.4.2数据类型
char的存储性能更高,定长,自动用空格补齐
varchar存储性能低,节约空间
create table student(
id int,
name varchar(10),
gender char(1),
birthday date,
score double(5,2),
email varchar(64),
tel varchar(15),
status tinyint
);
1.4.3删除,修改
drop table table_name --删除
alter table table_name rename to new_name; --修改表的名称
alter table table_name add row_name; --添加列名
alter table table_name modify row_name varchar(50); --修改列数据类型
alter table table_name change row_name new_name varchar(50); --修改列名和数据类型
alter table table_name drop row_name; --删除列
1.4.4DML添加,修改
1.4.5DQL分组查询
1.4.6DQL分组查询
1.4.7DQL分页查询
起始页码 = (当前页码 - 1) * 每页显示的条数
1.5约束
CREATE TABLE emp (
id INT PRIMARY KEY auto_increment,
-- 员工id,主键且自增长
ename VARCHAR (50) NOT NULL UNIQUE,
-- 员工姓名,非空并且唯一
joindate DATE NOT NULL,
-- 入职日期,非空
salary DOUBLE (7, 2) NOT NULL,
-- 工资,非空
bonus DOUBLE (7, 2) DEFAULT 0 -- 奖金,如果没有奖金默认为0
);
auto_increment缺省时自动填充
外键约束
-- 删除表
DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;
-- 部门表
CREATE TABLE dept(
id int primary key auto_increment,
dep_name varchar(20),
addr varchar(20)
);
-- 员工表
CREATE TABLE emp(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int,
-- 添加外键 dep_id,关联 dept 表的id主键
CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES dept(id)
);
-- 添加 2 个部门
insert into dept(dep_name,addr) values
('研发部','广州'),('销售部', '深圳');
-- 添加员工,dep_id 表示员工所在的部门
INSERT INTO emp (NAME, age, dep_id) VALUES
('张三', 20, 1),
('李四', 20, 1),
('王五', 20, 1),
('赵六', 20, 2),
('孙七', 22, 2),
('周八', 18, 2);
-- ------------------
select * from emp;
1.6数据库的设计
对表的设计
1.6.1一对多
1.6.2多对多
/*
多对多:
* 如:订单 和 商品
* 一个商品对应多个订单,一个订单包含多个商品
实现方式:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
*/
-- 删除表
DROP TABLE IF EXISTS tb_order_goods;
DROP TABLE IF EXISTS tb_order;
DROP TABLE IF EXISTS tb_goods;
-- 订单表
CREATE TABLE tb_order(
id int primary key auto_increment,
payment double(10,2),
payment_type TINYINT,
status TINYINT
);
-- 商品表
CREATE TABLE tb_goods(
id int primary key auto_increment,
title varchar(100),
price double(10,2)
);
-- 订单商品中间表
CREATE TABLE tb_order_goods(
id int primary key auto_increment,
order_id int,
goods_id int,
count int
);
-- 建完表后,添加外键
alter table tb_order_goods add CONSTRAINT fk_order_id FOREIGN key(order_id) REFERENCES tb_order(id);
alter table tb_order_goods add CONSTRAINT fk_goods_id FOREIGN key(goods_id) REFERENCES tb_goods(id);
映射模型
1.6.3一对一
1.7多表查询
DROP TABLE IF EXISTS emp;
DROP TABLE IF EXISTS dept;
# 创建部门表
CREATE TABLE dept(
did INT PRIMARY KEY AUTO_INCREMENT,
dname VARCHAR(20)
);
# 创建员工表
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
gender CHAR(1), -- 性别
salary DOUBLE, -- 工资
join_date DATE, -- 入职日期
dep_id INT,
FOREIGN KEY (dep_id) REFERENCES dept(did) -- 外键,关联部门表(部门表的主键)
);
-- 添加部门数据
INSERT INTO dept (dNAME) VALUES ('研发部'),('市场部'),('财务部'),('销售部');
-- 添加员工数据
INSERT INTO emp(NAME,gender,salary,join_date,dep_id) VALUES
('孙悟空','男',7200,'2013-02-24',1),
('猪八戒','男',3600,'2010-12-02',2),
('唐僧','男',9000,'2008-08-08',2),
('白骨精','女',5000,'2015-10-07',3),
('蜘蛛精','女',4500,'2011-03-14',1),
('小白龙','男',2500,'2011-02-14',null);
select * from emp;
-- 多表查询
select * from emp , dept;
-- 笛卡尔积 : 有 A ,B两个集合 取 A,B所有的组合情况,产生了笛卡尔积。
-- 消除无效数据
-- 查询emp 和 dept 的数据 ,emp.dep_id = dept.did
select * from emp , dept where emp.dep_id = dept.did;
内链接;
-- 内链接
SELECT emp. NAME,emp.gender,dept.dname FROM emp, dept WHERE emp.dep_id = dept.did;
-- 外连接
SELECT * FROM emp INNER JOIN dept ON emp.dep_id = dept.did
-- 左外链接
SELECT * FROM emp LEFT JOIN dept ON emp.dep_id = dept.did
-- 右外链接
SELECT * FROM emp RIGHT JOIN dept ON emp.dep_id = dept.did
一般使用左外链接
子查询
-- 单行单列
SELECT * FROM emp WHERE salary > (SELECT salary from emp WHERE name = '猪八戒');
-- 查询财务部和市场部的员工信息
-- 多行单列
SELECT * from emp WHERE dep_id in (SELECT did from dept WHERE dname in ("财务部","市场部"))
-- 查询入职日期时 ‘2011-11-11’ 之后的员工信息和部门信息
-- 多行多列
SELECT * FROM emp,dept WHERE emp.dep_id = dept.did AND emp.join_date > '2011-11-11';
SELECT * FROM (SELECT * FROM emp WHERE join_date > '2011-11-11') t1 JOIN dept WHERE t1.dep_id = dept.did
1.7事务
1.一种机制,一种操作序列,一组数据库操作命令。
2.所有命令要么同时成功,要么同时失败
3.事务是一个不可分割的工作逻辑单元
-- 开启事务
BEGIN;
UPDATE account set money = money + 500 WHERE name = '李四';
UPDATE account set money = money + 500 WHERE name = '张三';
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
二、JDBC
2.1JDBC简介
2.2JDBC快速入门
package com.itheimal.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
* JDBC快速入门
*/
public class JDBCdemo {
public static void main(String[] args) throws Exception {
// 1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2. 获取连接
String url = "jdbc:mysql://127.0.0.1:3306/db2?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
//3. 定义sql
String sql = "update account set money = 2000 where id = 1";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5. 执行sql
int count = stmt.executeUpdate(sql);//受影响的行数
//6. 处理结果
System.out.println(count);
//7. 释放资源
stmt.close();
conn.close();
}
}
2.3api详解
2.3.1DriverManager
1.驱动
DriverManager.driver()
静态代码块注册驱动,5之后的不用class.forname()方法,在java.sql.driver有。
2.获取数据库链接
useSSL=false:禁用安全链接,配置后性能会降低20%
2.3.2connection
interface connection:是一个接口
1.获取sql对象
2.事务管理
try {
conn.setAutoCommit(false);//开启事务
//5. 执行sql
int count1 = stmt.executeUpdate(sql1);//受影响的行数
//6. 处理结果
System.out.println(count1);
int i = 3 / 0;
//5. 执行sql
int count2 = stmt.executeUpdate(sql2);//受影响的行数
//6. 处理结果
System.out.println(count2);
conn.commit();
} catch (Exception throwables) {
//回滚事务
conn.rollback();//提交事务
throwables.printStackTrace();
}
2.3.3Result.set
//1.定义sql
String sql = "select * from account";
//2.获取sql对象
Statement stmt = conn.createStatement();
//3.执行sql
ResultSet rs = stmt.executeQuery(sql);
//4.处理结果
//光标向下移动一行,并判断是否有数据
while (rs.next()){
int id = rs.getInt(1);
String name = rs.getString(2);
double money = rs.getDouble(3);
System.out.println(id);
System.out.println(name);
System.out.println(money);
System.out.println("----------");
}
rs.close();
stmt.close();
conn.close();
}
2.4prepareStatement
SQL注入
@Test
public void Test_login_inject() throws Exception{
String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
//3. 定义sql
String name = "jighiagfer";
String pwd = "' or '1' = '1";
String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5. 执行sql
ResultSet rs = stmt.executeQuery(sql);//受影响的行数
//6. 处理结果
if(rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//7. 释放资源
rs.close();
stmt.close();
conn.close();
}
登录成功
String name = "jighiagfer";
String pwd = "' or '1' = '1";
String sql = "select * from tb_user where username = ? and password = ?";
//4. 获取执行sql的对象 Statement
PreparedStatement pstmt = conn.prepareStatement(sql);
//设置问号的值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
//5. 执行sql
ResultSet rs = pstmt.executeQuery();//受影响的行数
//6. 处理结果
if(rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//7. 释放资源
rs.close();
pstmt.close();
conn.close();
}
登录失败
原理:
2.4数据库连接池
-
数据库连接池是个容器,负责分配、管理数据库连接(Connection)
-
它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;
-
释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
-
好处
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
连接池是在一开始就创建好了一些连接(Connection)对象存储起来。用户需要连接数据库时,不需要自己创建连接,而只需要从连接池中获取一个连接进行使用,使用完毕后再将连接对象归还给连接池;这样就可以起到资源重用,也节省了频繁创建连接销毁连接所花费的时间,从而提升了系统响应的速度。
/**
* 查询所有
* 1. SQL:select * from tb_brand;
* 2. 参数:不需要
* 3. 结果:List<Brand>
*/
@Test
public void testSelectAll() throws Exception {
//1. 获取Connection
//3. 加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
//4. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5. 获取数据库连接 Connection
Connection conn = dataSource.getConnection();
//2. 定义SQL
String sql = "select * from tb_brand;";
//3. 获取pstmt对象
PreparedStatement pstmt = conn.prepareStatement(sql);
//4. 设置参数
//5. 执行SQL
ResultSet rs = pstmt.executeQuery();
//6. 处理结果 List<Brand> 封装Brand对象,装载List集合
Brand brand = null;
List<Brand> brands = new ArrayList<>();
while (rs.next()){
//获取数据
int id = rs.getInt("id");
String brandName = rs.getString("brand_name");
String companyName = rs.getString("company_name");
int ordered = rs.getInt("ordered");
String description = rs.getString("description");
int status = rs.getInt("status");
//封装Brand对象
brand = new Brand();
brand.setId(id);
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setOrdered(ordered);
brand.setDescription(description);
brand.setStatus(status);
//装载集合
brands.add(brand);
}
System.out.println(brands);
//7. 释放资源
rs.close();
pstmt.close();
conn.close();
}
三、maven
1.1简介
- 项目对象模型 (Project Object Model)
- 依赖管理模型(Dependency)
- 插件(Plugin)
如上图所示就是Maven的模型,而我们先看紫色框框起来的部分,他就是用来完成 标准化构建流程
。如我们需要编译,Maven提供了一个编译插件供我们使用,我们需要打包,Maven就提供了一个打包插件提供我们使用等。
1.2 仓库
大家想想这样的场景,我们创建Maven项目,在项目中使用坐标来指定项目的依赖,那么依赖的jar包到底存储在什么地方呢?其实依赖jar包是存储在我们的本地仓库中。而项目运行时从本地仓库中拿需要的依赖jar包。
仓库分类:
-
本地仓库:自己计算机上的一个目录
-
中央仓库:由Maven团队维护的全球唯一的仓库
- 地址: https://repo1.maven.org/maven2/
-
远程仓库(私服):一般由公司团队搭建的私有仓库
今天我们只学习远程仓库的使用,并不会搭建。
当项目中使用坐标引入对应依赖jar包后,首先会查找本地仓库中是否有对应的jar包:
-
如果有,则在项目直接引用;
-
如果没有,则去中央仓库中下载对应的jar包到本地仓库。
如果还可以搭建远程仓库,将来jar包的查找顺序则变为:
本地仓库 --> 远程仓库–> 中央仓库
1.3 Maven 常用命令
compile :编译
clean:清理
test:测试
package:打包
install:安装
1.4maven生命周期
1.5 Maven 坐标详解
什么是坐标?
- Maven 中的坐标是资源的唯一标识
- 使用坐标来定义项目或引入项目中需要的依赖
Maven 坐标主要组成
- groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.itheima)
- artifactId:定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
- version:定义当前项目版本号
如下图就是使用坐标表示一个项目:
注意:
- 上面所说的资源可以是插件、依赖、当前项目。
- 我们的项目如果被其他的项目依赖时,也是需要坐标来引入的。
1.6依赖范围
通过设置坐标的依赖范围(scope),可以设置 对应jar包的作用范围:编译环境、测试环境、运行环境。
如下图所示给 junit
依赖通过 scope
标签指定依赖的作用范围。 那么这个依赖就只能作用在测试环境,其他环境下不能使用。
那么 scope
都可以有哪些取值呢?
依赖范围 | 编译classpath | 测试classpath | 运行classpath | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | logback |
test | - | Y | - | Junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc驱动 |
system | Y | Y | - | 存储在本地的jar包 |
- compile :作用于编译环境、测试环境、运行环境。
- test : 作用于测试环境。典型的就是Junit坐标,以后使用Junit时,都会将scope指定为该值
- provided :作用于编译环境、测试环境。我们后面会学习
servlet-api
,在使用它时,必须将scope
设置为该值,不然运行时就会报错 - runtime : 作用于测试环境、运行环境。jdbc驱动一般将
scope
设置为该值,当然不设置也没有任何问题
注意:
- 如果引入坐标不指定
scope
标签时,默认就是 compile 值。以后大部分jar包都是使用默认值。
四、mybatis
4.1Mapper代理开发
Brandmapper:接口文件,其中含有相应的sql函数
package com.jth.mapper;
import com.jth.pojo.Brand;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @author 42450
* @description 针对表【tb_brand】的数据库操作Mapper
* @createDate 2022-10-03 09:39:26
* @Entity com.jth.pojo.Brand
*/
public interface BrandMapper {
//查询所有
public List<Brand> selectAll();
//查询id
public Brand selectByIdBrand(int id);
//条件查询
// public List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
public List<Brand> selectByCondition(Brand brand);
//public List<Brand> selectByCondition(Map map);
public List<Brand> selectByConditionSingle(Brand brand);
}
BrandMapper.xml:存放了接口中的函数的对应sql语句
<?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.jth.mapper.BrandMapper">
<!--
id:"唯一标识",完成主键字段的映射
result:"一般字段的映射"
-->
<resultMap id="BaseResultMap" type="com.jth.pojo.Brand">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="brandName" column="brand_name" jdbcType="VARCHAR"/>
<result property="companyName" column="company_name" jdbcType="VARCHAR"/>
<result property="ordered" column="ordered" jdbcType="INTEGER"/>
<result property="description" column="description" jdbcType="VARCHAR"/>
<result property="status" column="status" jdbcType="INTEGER"/>
</resultMap>
<!-- <sql id="Base_Column_List">-->
<!-- id,brand_name as brandName,company_name as companyName,-->
<!-- ordered,description,status-->
<!-- </sql>-->
<!-- <select id="selectAll" resultType="com.jth.pojo.Brand">-->
<!-- select <include refid="Base_Column_List"></include> from tb_brand;-->
<!-- </select>-->
<select id="selectAll" resultMap="BaseResultMap">
select * from tb_brand;
</select>
<select id="selectByIdBrand" resultMap="BaseResultMap">
select * from tb_brand where id <![CDATA[
<
]]> #{id}
</select>
<!--条件查询-->
<!-- <select id="selectByCondition" resultMap="BaseResultMap">-->
<!-- select * from tb_brand where status = #{status} and company_name like #{companyName} and brand_name like #{brandName}-->
<!-- </select>-->
<!-- 动态条件查询-->
<select id="selectByCondition" resultMap="BaseResultMap">
select * from tb_brand <where>
<if test="status != null">and status = #{status}</if>
<if test="companyName != null and companyName != ''">and company_name like #{companyName}</if>
<if test="brandName != null and brandName != ''">and brand_name like #{brandName}</if>
</where>
</select>
<!-- 单条件查询-->
<select id="selectByConditionSingle" resultMap="BaseResultMap">
select * from tb_brand
<where>
<choose>
<when test="status != null">status = #{status}</when>
<when test="companyName != null and companyName != ''">company_name like #{companyName}</when>
<when test="brandName != null and brandName != ''">brand_name like #{brandName}</when>
<!-- <otherwise>-->
<!-- 1 = 1-->
<!-- </otherwise>-->
</choose>
</where>
</select>
</mapper>
logback.xml
相应的日志配置文件
<?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>
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>
<!--
envirment 配置数据库连接环境信息,可以配置多个envirment,通过default属性切换不同的数据库
-->
<typeAliases>
<package name="com.jth.pojo"/>
</typeAliases>
<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:///mybatis?characterEncoding=utf8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 加载sql映射文件-->
<!-- <mapper resource="com/jth/mapper/userMapper.xml"/>-->
<!--mapper代理-->
<package name="com.jth.mapper"/>
<!--将这个目录下的mapper文件引入--->
</mappers>
</configuration>
4.2查询
4.2.1条件查询
<select id="selectByIdBrand" resultMap="BaseResultMap">
select * from tb_brand where id <![CDATA[
<
]]> #{id}
</select>
public List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);//散装参数
public List<Brand> selectByCondition(Brand brand);//实体类封装参数
public List<Brand> selectByCondition(Map map);//map集合
4.2.2动态查询
<!-- 动态条件查询-->
<select id="selectByCondition" resultMap="BaseResultMap">
select * from tb_brand <where>
<if test="status != null">and status = #{status}</if>
<if test="companyName != null and companyName != ''">and company_name like #{companyName}</if>
<if test="brandName != null and brandName != ''">and brand_name like #{brandName}</if>
</where>
</select>
标签可以动态实现sql,
当不加标签时,且后面的条件都不满足,其执行的sql为
select * from tb_brand where语法错误
加了后可以动态的添加where
变为select * from tb_brand
4.2.3单条件查询
<!-- 单条件查询-->
<select id="selectByConditionSingle" resultMap="BaseResultMap">
select * from tb_brand
<where>
<choose>
<when test="status != null">status = #{status}</when>
<when test="companyName != null and companyName != ''">company_name like #{companyName}</when>
<when test="brandName != null and brandName != ''">brand_name like #{brandName}</when>
<!-- <otherwise>-->
<!-- 1 = 1-->
<!-- </otherwise>-->
</choose>
</where>
</select>
如图所示,choose相当于swith,when相当于条件,当都满足时只会执行第一个,
otherwise相当于default
不加时会报错,除非加一个where标签
4.3添加数据
<insert id="add">
insert into tb_brand(brand_name,company_name,ordered,description,status)
values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
brandMapper.add(brand);
//提交事务
sqlSession.commit();
sqlSession.close();
注意必须要提交事务,不加提交的话,由于自动设为autoCommit = false,所以他无提交事务,会自动回滚,导致数据库不会改变
//获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
也可以在openSession中为true,设置自动提交
添加,主键返回
<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>
添加这几个值就可以获取主键
Integer id = brand.getId();
4.4修改
4.4.1修改全部字段
<update id="update">
update tb_brand
set
brand_name = #{brandName},
company_name = #{companyName},
ordered = #{ordered},
description = #{description},
status = #{status}
where id = #{id}
</update>
4.4.2动态修改
<update id="update">
update tb_brand
<set>
<if test="brandName != null and brandName != ''">
brand_name = #{brandName},
</if>
<if test="companyName != null and companyName != ''">
company_name = #{companyName},
</if>
<if test="ordered != null and ordered != ''">
ordered = #{ordered},
</if>
<if test="description != null and description != ''">
description = #{description},
</if>
<if test="status != null and status != ''">
status = #{status}
</if>
</set>
where id = #{id}
</update>
4.4删除
单个删除
<delete id="deleteById">
delete from tb_brand where id = #{id}
</delete>
批量删除
void deleteByIds(@Param("ids") int[] ids);//后面xml识别ids
<delete id="deleteByIds">
delete from tb_brand where id
in (
<foreach collection="ids" item = "id" separator=",">
#{id}
</foreach>
)
</delete>
由于mybties会把数组封装为map集合,默认key = array
可以加parms
也可以写array
4.5参数传递
mybatis参数封装
单个参数
- 1.pojo类型 直接使用 键名和 参数占位符一致
- 2.map集合 直接使用 键名和 参数占位符一致
- 3.collection,封装为map集合 可以使用@parm注解,替换arg0的键名
map.put(“arg0”,clooection集合)
map.put(“collection”,clooection集合) - 4.list封装为map集合 可以使用@parm注解,替换arg0的键名
map.put(“arg0”,clooection集合)
map.put(“collection”,list集合)
map.put(“lsit”,list集合) - 5.array封装为map集合 可以使用@parm注解,替换arg0的键名
map.put(“arg0”,数组)
map.put(“array”,数组) - 6.其他类型 直接使用 键名和 参数占位符一致
多个参数 封装为@parm注解,替换默认的arg键名 - map.put(“arg0”,参数一)
- map.put(“param1”,参数一)
- map.put(“arg01”,参数二)
- map.put(“param1”,参数二)
paramNameResovler.java自己去debug(手动狗头保命)