目录
二、创建在resources目录下的配置文件,起个名 mybatisconf.xml
三、SQL Session Factory创建SQL Session
七、sql 多表关联查询,结果保存在Map,Map的key对应数据库表的字段名,value对应字段值,Map:key-value,数据库表:字段名-字段值。
八、sql 查询,ResultMap结果映射,保存在Map中。
十、MyBatis的selectKey和useGeneratedKeys区别
mybatis开发流程,六大步骤
一、引入依赖
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
二、创建在resources目录下的配置文件,起个名 mybatisconf.xml
首先准备好数据库,利用idea自带工具,执行数据库脚本
mybatisconf.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="dev">
<environment id="dev">
<!-- 采用JDBC方式对数据库事务commit和rollback操作-->
<transactionManager type="JDBC"></transactionManager>
<!-- 连接池方式管理数据库连接-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/babytun?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="pro">
<!-- 采用JDBC方式对数据库事务commit和rollback操作-->
<transactionManager type="JDBC"></transactionManager>
<!-- 连接池方式管理数据库连接-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.1.1:3306/babytun?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
</configuration>
三、SQL Session Factory创建SQL Session
下面是一个测试类,就演示工厂调用buid方法读取配置文件mybatisconf.xml,创建sql会话。
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 org.junit.Test;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
/**
* @author Aiver
* @date 2022/11/27 16:33
*/
public class MyBatisTest {
@Test
public void testSqlFactory() throws IOException {
Reader resourceAsReader = Resources.getResourceAsReader("mybatisconf.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println(sqlSession);
Connection connection = sqlSession.getConnection();
System.out.println(connection);
if (sqlSession != null) {
sqlSession.close();
}
}
}
一个工具类创建SQL Session Factory和SQL Session,都用static修饰或者在static块生成,保证全局唯一,就是说只有一个工厂,创建SQL Session 的Factory。
package org.qiu.utils;
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.Reader;
/**
* @author Aiver
* @date 2022/11/27 16:06
* 工具类基本都是static
*/
public class MyBatisUtils {
//static 保证 sqlSessionFactory 全局唯一
private static SqlSessionFactory sqlSessionFactory = null;
//利用static 静态块在类初始化就已经实例化了sqlSessionFactory,全局唯一
static {
try {
Reader resourceAsReader = Resources.getResourceAsReader("mybatisconf.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
}
/**
* 打开sqlSession,创建一个新的sqlSession对象
* @return SqlSession
*/
public static SqlSession openSqlSession(){
return sqlSessionFactory.openSession();
}
/**
* 关闭sqlSession
* @param sqlSession
*/
public static void closeSqlSession(SqlSession sqlSession){
if (sqlSession != null) {
sqlSession.close();
}
}
}
测试一下工具类,没毛病老铁,干就完了。
package org.qiu.utils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.sql.Connection;
import static org.junit.Assert.*;
/**
* @author Aiver
* @date 2022/11/27 16:31
*/
public class MyBatisUtilsTest {
@Test
public void openSqlSession() {
SqlSession sqlSession = MyBatisUtils.openSqlSession();
System.out.println(sqlSession);
Connection connection = sqlSession.getConnection();
System.out.println(connection);
if (sqlSession != null) sqlSession.close();
}
@Test
public void closeSqlSession() {
}
}
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 org.junit.Test;
import org.qiu.utils.MyBatisUtils;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
/**
* @author Aiver
* @date 2022/11/27 16:33
*/
public class MyBatisTest {
@Test
public void testSqlFactory() throws IOException {
Reader resourceAsReader = Resources.getResourceAsReader("mybatisconf.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);
SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println(sqlSession);
Connection connection = sqlSession.getConnection();
System.out.println(connection);
if (sqlSession != null) {
sqlSession.close();
}
}
@Test
public void testMybatisUtils(){
SqlSession sqlSession = MyBatisUtils.openSqlSession();
Connection connection = sqlSession.getConnection();
System.out.println(connection);
MyBatisUtils.closeSqlSession(sqlSession);
}
}
四、MaBatis数据查询
创建实体类:get和set方法没有复制过来,太长了
package org.qiu.entity;
/**
* @author Aiver
* @date 2022/12/9 16:01
*/
public class Goods {
private Integer goodsId;//商品编号
private String title;//标题
private String subTitle;//子标题
private Float originalCost;//原始价格
private Float currentPrice;//当前价格
private Float discount;//折扣率
private Integer isFreeDelivery;//是否包邮 ,1-包邮 0-不包邮
private Integer categoryId;//分类编号
// private List<GoodsDetail> goodsDetails;
}
resource文件夹下创建mappers文件夹的goods.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">
<mapper namespace="goods">
<select id="selectAll" resultType="org.qiu.entity.Goods">
select * from t_goods order by goods_id desc limit 8
</select>
</mapper>
在配置文件mybatisconf.xml,注册goods.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>
<mappers>
<mapper resource="mappers/goods.xml"></mapper>
</mappers>
</configuration>
编写查询的测试用例,核心还是sqlSession
@Test
public void testSelectGoodsAll(){
SqlSession sqlSession = MyBatisUtils.openSqlSession();
List<Goods> selectList = sqlSession.selectList("goods.selectAll");
for (Goods goods : selectList) {
System.out.println(goods.getTitle());
}
MyBatisUtils.closeSqlSession(sqlSession);
}
sqlSession.selectList("goods.selectAll");对应的是mappers的goods.xml下面的
配置文件mybatisconf.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>
<settings>
<!-- 数据库表中字段 goods_id ==> Java的命名规范,属性名称 goodsId 驼峰命名转换 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<configuration>
五、sql 单个参数传参查询,goods.xml文件中插入
<select id="selectById" parameterType="Integer" resultType="org.qiu.entity.Goods">
select * from t_goods where goods_id = #{value}
</select>
<?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="goods">
<select id="selectById" parameterType="Integer" resultType="org.qiu.entity.Goods">
select * from t_goods where goods_id = #{value}
</select>
</mapper>
查询语句在同一个goods.xml文件,上面已经注册过了,无需再注册。
编写测试用例。 sqlSession.selectOne("goods.selectById",1601) 与
<select id="selectById" parameterType="Integer" resultType="org.qiu.entity.Goods">
select * from t_goods where goods_id = #{value}
</select> 相互对应
@Test
public void testSelectGoodsById(){
SqlSession sqlSession = MyBatisUtils.openSqlSession();
Goods goods = sqlSession.selectOne("goods.selectById",1601);
System.out.println(goods);
MyBatisUtils.closeSqlSession(sqlSession);
}
六、sql 多个参数传参查询,多参数保存在Map中。
在goods.xml文件中插入
<select id="selectByPriceRange" parameterType="Map" resultType="org.qiu.entity.Goods">
select * from t_goods
where
current_price between #{low} and #{hight}
order by current_price
limit 0,#{limit}
</select>
<?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="goods">
<select id="selectAll" resultType="org.qiu.entity.Goods">
select * from t_goods order by goods_id desc limit 8
</select>
<select id="selectById" parameterType="Integer" resultType="org.qiu.entity.Goods">
select * from t_goods where goods_id = #{value}
</select>
<select id="selectByPriceRange" parameterType="Map" resultType="org.qiu.entity.Goods">
select * from t_goods
where
current_price between #{low} and #{hight}
order by current_price
limit 0,#{limit}
</select>
</mapper>
编写测试用例:
@Test
public void testSelectGoodsByPriceRange(){
SqlSession sqlSession = MyBatisUtils.openSqlSession();
Map<String,Integer> map = new HashMap<>();
map.put("low",12);
map.put("hight",120);
map.put("limit",10);
List<Goods> goodsList = sqlSession.selectList("goods.selectByPriceRange",map);
for (Goods goods : goodsList) {
System.out.println(goods);
}
MyBatisUtils.closeSqlSession(sqlSession);
}
<select id="selectByPriceRange" parameterType="Map" resultType="org.qiu.entity.Goods"> select * from t_goods
where current_price between #{low} and #{hight}
order by current_price limit 0,#{limit}
</select>
与
Map<String,Integer> map = new HashMap<>();
map.put("low",12); map.put("hight",120); map.put("limit",10);
List<Goods> goodsList = sqlSession.selectList("goods.selectByPriceRange",map);
相对应
七、sql 多表关联查询,结果保存在Map,Map的key对应数据库表的字段名,value对应字段值,Map:key-value,数据库表:字段名-字段值。
Map,查询结果为无序,按照哈希值排序,在goods.xml中加入:
<select id="selectGoodsMap" resultType="Map">
select g.*,c.category_name
from t_goods g,t_category c
where g.category_id = c.category_id;
</select>
编写测试用例:
@Test
public void testSelectGoodsMap(){
SqlSession sqlSession = MyBatisUtils.openSqlSession();
List<Map> list = sqlSession.selectList("goods.selectGoodsMap");
for (Map map : list) {
System.out.println(map);
}
MyBatisUtils.closeSqlSession(sqlSession);
}
LinkedHashMap,查询结果有序,按照插入时候顺序,g.*再到c.category_name,而g.*也就是数据库表字段原先顺序,goods.xml文件加入:
<select id="selectGoodsLinkedHashMap" resultType="LinkedHashMap">
select g.*,c.category_name
from t_goods g,t_category c
where g.category_id = c.category_id;
</select>
编写测试用例:
@Test
public void testSelectGoodsLinkedHashMap(){
SqlSession sqlSession = MyBatisUtils.openSqlSession();
List<Map> list = sqlSession.selectList("goods.selectGoodsLinkedHashMap");
for (Map map : list) {
System.out.println(map);
}
MyBatisUtils.closeSqlSession(sqlSession);
}
八、sql 查询,ResultMap结果映射,保存在Map中。
新建dto目录,创建GoodsDTO类
Data Transfer Object 数据传输对象,简称 DTO
dto是entity类的扩展,GoodsDTO就是entity类的Goods类的扩展,下面get和set方法不复制了
package org.qiu.dto;
import org.qiu.entity.Goods;
/**
* @author Aiver
* @date 2022/12/9 19:27
*/
//Data Transfer Object 数据传输对象
public class GoodsDTO {
private Goods goods = new Goods();
private String categoryName;
private String test;
}
在goods.xml 中加入
<resultMap id="dtoGoods" type="org.qiu.dto.GoodsDTO">
<!--设置主键字段与属性映射-->
<id property="goods.goodsId" column="goods_id"></id>
<!--设置非主键字段与属性映射-->
<result property="goods.title" column="title"></result>
<result property="goods.originalCost" column="original_cost"></result>
result property="goods.currentPrice" column="current_price"></result>
<result property="goods.discount" column="discount"></result>
<result property="goods.isFreeDelivery" column="is_free_delivery"></result>
<result property="goods.categoryId" column="category_id"></result>
<result property="categoryName" column="category_name"></result>
<result property="test" column="good_test"></result>
</resultMap>
<select id="selectGoodsDTO" resultMap="dtoGoods">
select g.*,c.category_name,'haha' as good_test
from t_goods g,t_category c
where g.category_id = c.category_id;
</select>
编写测试用例
@Test
public void testSelectGoodsDTO(){
SqlSession sqlSession = MyBatisUtils.openSqlSession();
List<GoodsDTO> list = sqlSession.selectList("goods.selectGoodsDTO");
for (GoodsDTO goodsDTO : list) {
System.out.println(goodsDTO.getGoods());
System.out.println(goodsDTO.getGoods().getTitle());
}
MyBatisUtils.closeSqlSession(sqlSession);
}
九、插入操作
在goods的xml文件加入,因为goods_id是在数据表设置自动增加的,所以不用人为插入数据了
<insert id="insertGoods" parameterType="org.qiu.entity.Goods">
insert into t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
values (#{title} , #{subTitle} , #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})
</insert>
编写测试用例
@Test
public void testInsertGoods(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSqlSession();
Goods goods = new Goods();
goods.setTitle("测试写的商品");
goods.setSubTitle("测试写的子标题");
goods.setOriginalCost(200f);
goods.setCurrentPrice(100f);
goods.setDiscount(0.5f);
goods.setIsFreeDelivery(1);
goods.setCategoryId(43);
int line = sqlSession.insert("goods.insertGoods", goods);
//返回成功插入记录
sqlSession.commit();//提交事务
System.out.println(goods.getTitle());
} catch (Exception e) {
if (sqlSession != null) {
sqlSession.rollback();//回滚事务
}
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
selectKey,在上面插入操作,在goods的xml文件加入,因为goods_id是在数据表设置自动增加的,所以不用人为插入数据了。但是数据表中自增字段 goods_id不会回添到Java对象Goods的属性GoodsId。所以如果想要把 goods_id回添到GoodsId,就要使用selectKey
<insert id="insertGoodsTwo" parameterType="org.qiu.entity.Goods">
insert into t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
values (#{title} , #{subTitle} , #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})
<selectKey resultType="java.lang.Integer" keyProperty="goodsId" order="AFTER">
select last_insert_id()
</selectKey>
</insert>
其中:
<selectKey resultType="java.lang.Integer" keyProperty="goodsId" order="AFTER">
select last_insert_id()
</selectKey>
order="AFTER"表示,在执行这条插入命令之后 ,把 select last_insert_id() 的结果回填到 keyProperty="goodsId" 。
select last_insert_id()函数 是myBatis自带的东西,表示获取当前数据库连接执行查询等操作最后产生的id号,该函数返回值是整型,所以resultType="java.lang.Integer" 。而keyProperty="goodsId" 就是Java对象Goods的属性GoodsId。
测试用例
@Test
public void testInsertGoodsTwo(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSqlSession();
Goods goods = new Goods();
goods.setTitle("测试写的商品Two");
goods.setSubTitle("测试写的子标题Two");
goods.setOriginalCost(20f);
goods.setCurrentPrice(10f);
goods.setDiscount(0.5f);
goods.setIsFreeDelivery(1);
goods.setCategoryId(44);
int line = sqlSession.insert("goods.insertGoodsTwo", goods);
//返回成功插入记录数,,受影响行数
sqlSession.commit();//提交事务
System.out.println(goods.getGoodsId());
} catch (Exception e) {
if (sqlSession != null) {
sqlSession.rollback();//回滚事务
}
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
十、MyBatis的selectKey和useGeneratedKeys区别
Oracle不支持“自增主键”
useGeneratedKeys:
<insert id="insertGoodsThree" parameterType="org.qiu.entity.Goods" useGeneratedKeys="true" keyProperty="goodsId" keyColumn="goods_id">
insert into t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
values (#{title} , #{subTitle} , #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})
</insert>
@Test
public void testInsertGoodsThree(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSqlSession();
Goods goods = new Goods();
goods.setTitle("测试写的商品Three");
goods.setSubTitle("测试写的子标题Three");
goods.setOriginalCost(20f);
goods.setCurrentPrice(101f);
goods.setDiscount(0.5f);
goods.setIsFreeDelivery(11);
goods.setCategoryId(54);
int line = sqlSession.insert("goods.insertGoodsThree", goods);//返回成功插入记录数,,受影响行数
sqlSession.commit();//提交事务
System.out.println(goods.getGoodsId());
} catch (Exception e) {
if (sqlSession != null) {
sqlSession.rollback();//回滚事务
}
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
十一、更新与删除操作
更新
<update id="updateGoods" parameterType="org.qiu.entity.Goods">
update t_goods
set title = #{title},sub_title = #{subTitle},original_cost = #{originalCost},current_price = #{currentPrice},discount = #{discount},is_free_delivery = #{isFreeDelivery},category_id = #{categoryId}
where goods_id = #{goodsId}
</update>
@Test
public void testUpdateGoods(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSqlSession();
Goods goods = sqlSession.selectOne("goods.selectById", 776);
goods.setTitle("更新标题,及你太美");
goods.setSubTitle("更新子标题,基尼实在是太美");
int updateLines = sqlSession.update("goods.updateGoodsById", goods);
System.out.println(updateLines);
sqlSession.commit();//提交事务哦
} catch (Exception e) {
if (sqlSession != null) {
sqlSession.rollback();//回滚事务
}
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
删除
<delete id="deleteGoodsById" parameterType="java.lang.Integer">
delete from t_goods where goods_id = #{id}
</delete>
@Test
public void testDeleteGoodsById(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSqlSession();
int deleteLine = sqlSession.delete("goods.deleteGoodsById", 777);
System.out.println(deleteLine);
sqlSession.commit();//提交事务哦
} catch (Exception e) {
if (sqlSession != null) {
sqlSession.rollback();//回滚事务
}
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
十二、SQL注入攻击,普通公鸡,鸡你太美
sql注入攻击就是利用sql语句中的传入参数使用的是 ${} , 没有预编译处理直接来个字符串拼接,解决方法就是 传参不用 ${},而是改为 #{}
使用${}
title 的值是包含 单引号的
'【德国】Aptamil爱他美奶粉1+段600g*1罐(12个月以上)'
而不是
【德国】Aptamil爱他美奶粉1+段600g*1罐(12个月以上)
<select id="selectGoodsByTitle" parameterType="java.util.Map" resultType="org.qiu.entity.Goods">
select * from t_goods where title = ${title}
</select>
@Test
public void testSelectGoodsByTitle(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSqlSession();
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("title"," '【德国】Aptamil爱他美奶粉1+段600g*1罐(12个月以上)'");
List<Goods> selectList = sqlSession.selectList("goods.selectGoodsByTitle", hashMap);
for (Goods goods : selectList) {
System.out.println(goods.getTitle()+" : "+goods.getSubTitle()+"---"+goods.getGoodsId());
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
如果黑客来了,进行sql注入攻击,那么把原来的
${title} 由
'【德国】Aptamil爱他美奶粉1+段600g*1罐(12个月以上)'
改为
' ' or 1=1 or title= '【德国】Aptamil爱他美奶粉1+段600g*1罐(12个月以上)'
那么就有
/*
${}原文传值
select * from t_goods
where title = '' or 1 =1 or title = '【德国】爱他美婴幼儿配方奶粉1段800g*2罐 铂金版'
*/
/*
#{}预编译
select * from t_goods
where title = "'' or 1 =1 or title = '【德国】爱他美婴幼儿配方奶粉1段800g*2罐 铂金版'"
*/
@Test
public void testSelectGoodsByTitle(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisUtils.openSqlSession();
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("title"," '' or 1 = 1 or title='【德国】Aptamil爱他美奶粉1+段600g*1罐(12个月以上)'");
List<Goods> selectList = sqlSession.selectList("goods.selectGoodsByTitle", hashMap);
for (Goods goods : selectList) {
System.out.println(goods.getTitle()+" : "+goods.getSubTitle()+"---"+goods.getGoodsId());
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSqlSession(sqlSession);
}
}
/*
${}原文传值
select * from t_goods
where title = '' or 1 =1 or title = '【德国】爱他美婴幼儿配方奶粉1段800g*2罐 铂金版'
*/
/*
#{}预编译
select * from t_goods
where title = "'' or 1 =1 or title = '【德国】爱他美婴幼儿配方奶粉1段800g*2罐 铂金版'"
*/
十三、总结