Java 程序中使用Map实现动态传参
在 Java 编程中,我们常常需要将数据传递给 SQL 查询,特别是在动态生成 SQL 语句时,通常会用到 Map 这种集合类。Map 可以将多个键值对传递给 SQL 语句的占位符,完成动态参数绑定的功能。我们下面详细讲解图中的知识点。
1. Map 的基本用法
Map 是 Java 集合框架中的一种数据结构,它以键值对 (key-value) 的形式存储数据。Map 中的键唯一且不能重复,而值可以重复。常用的实现类包括 HashMap、TreeMap 等。
示例代码:
Map map = new HashMap<>();
map.put("k1", "1111");
map.put("k2", "比亚迪汉");
map.put("k3", 10.0);
map.put("k4", "2020-11-11");
map.put("k5", "电车");
这里我们创建了一个 HashMap,并通过 put 方法将一些数据存入 Map。键是 String 类型,值是 Object 类型,意味着可以存放不同类型的数据(如字符串、数字、日期等)。
2. 占位符 #{} 的使用
在执行 SQL 语句时,为了防止 SQL 注入和简化代码,我们经常使用占位符将 SQL 参数动态地传入。(? 是 JDBC 中的占位符,用于预编译 SQL 语句中的参数。在使用 JDBC 时,SQL 语句通常是预编译的,? 用于表示一个位置,在执行时由具体的参数替换。)占位符 #{} 这一语法主要用于一些持久化框架,如 MyBatis。
SQL 语句示例:
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
values(null, #{k1}, #{k2}, #{k3}, #{k4}, #{k5});
在这个 SQL 语句中,#{k1}、#{k2} 等占位符将会在运行时被替换为 Map 中对应的值。框架会根据占位符的键来查找 Map 中的值并动态替换。如果键不存在,则返回 null。这个语句通常配置在通常用于 MyBatis 的 SQL 映射的XML文件中
注意:
3. Map 键名与数据库字段名的对应关系
为了使代码更加易读、维护更加方便,我们通常建议将 Map 中的键名与数据库字段名保持一致。这样一来,不仅能够直观地映射参数,还能避免因键名不统一而导致的问题。
map.put("carNum", "1111");
map.put("brand", "比亚迪汉2");
map.put("guidePrice", 10.0);
map.put("produceTime", "2020-11-11");
map.put("carType", "电车");
在这个例子中,我们将 Map 的键名改为 carNum、brand 等,和数据库表的列名一致。这样一来,代码就更容易理解和维护。
SQL 语句:
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
values(null, #{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType});
POJO 类实现动态传参 1. POJO 类与 SQL 占位符传递
POJO(Plain Old Java Object) 是指普通的 Java 对象,通常用作数据传输对象。在 Java 应用中,我们可以通过 POJO 类的属性来传递 SQL 语句中的参数。
Car car = new Car(null, "3333", "比亚迪秦", 30.0, "2020-11-11", "新能源");
在这个例子中,Car 是一个 POJO 类,包含一些车辆信息的属性。通过实例化这个类,我们可以将具体的值传入到 SQL 语句中的占位符。
2. 占位符 #{} 的使用
在 MyBatis 等持久化框架中,使用占位符 #{} 来表示将 POJO 的属性值注入到 SQL 语句中。大括号 {} 里面填写的内容是 POJO 类的属性名(严格意义上来说:如果使用P0J0对象传递值的话,这个{}里面写的是get方法的方法名去掉get,然后将剩下的单词首字母小写,然后放进去。)
SQL 语句示例:
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
values(null, #{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType});
3. 占位符与属性对应的规则
MyBatis 会自动根据 POJO 类中的属性名来查找对应的 getter 方法。如果 POJO 类中没有提供对应的 getter 方法,则会报错。
错误示例:
There is no getter for property named 'xyz' in 'class com.powernode.mybatis.pojo.Car'
这是因为 MyBatis 尝试通过 getXyz() 方法来获取 xyz 属性的值,但 POJO 类中没有定义这个方法。为了避免这种错误,我们需要在 POJO 类中提供每个属性的 getter 和 setter 方法。
4. 如何解决没有 getter 方法的问题?
如果遇到没有对应 getter 方法的情况,可以通过在 POJO 类中手动添加相应的 getter 方法来解决。比如:
public String getXyz() {
return xyz;
}
5. 占位符 #{} 的使用规则
通过这个错误示例,我们可以总结出占位符的使用规则:MyBatis 是通过反射机制来调用 getter 方法。也就是说,在 #{} 占位符中写的内容(如 #{carNum})并不直接对应 POJO 的属性名,而是对应属性的 getter 方法。
规则:
占位符 #{} 中的内容确实是与 POJO 类的属性相关,但 MyBatis 实际上是通过 调用 POJO 类的 getter 方法 来获取这些值的,而不是直接访问属性本身。因此,为了确保 MyBatis 能正确地映射 SQL 参数,POJO 类中的 getter 方法必须与占位符中的名字相匹配。
删除DELETE操作: 1. 删除操作的实现
int count = sqlSession.delete("deleteById", 59);
这行代码展示了通过 sqlSession.delete() 方法来执行删除操作,其中:
2. MyBatis Mapper 文件中的SQL语句
delete from t_car where id = #{fdsfd}
这是在MyBatis的Mapper XML文件中定义的删除操作,具体解释如下:
3. 占位符的说明
注意:如果占位符只有一个,那么 #{} 的大括号里可以随意。但是最好见名知意。
这里说明了 #{} 是MyBatis的占位符,用于绑定参数。虽然在某些情况下可以随意使用参数名(如 fdsfd),但是为了代码的可读性和维护性,建议使用有意义的名称,比如 id。
例如,改为:
delete from t_car where id = #{id}
这样更直观,容易理解。
4. 整体流程总结 更新操作: 1. 更新操作的SQL语句
update t_car set
car_num=#{carNum},
brand=#{brand},
guide_price=#{guidePrice},
produce_time=#{produceTime},
car_type=#{carType}
where
id = #{id}
这是在MyBatis的Mapper XML文件中定义的更新操作。解释如下:
这里使用 #{} 作为MyBatis的占位符,类似于之前的删除操作。它会在执行时将参数替换为实际值。具体字段说明:
2. Java代码中的更新操作
Car car = new Car(4L, "9999", "凯美瑞", 30.3, "1999-11-10", "燃油车");
int count = sqlSession.update("updateById", car);
然后调用 sqlSession.update("updateById", car); 进行更新操作。MyBatis会将 car 对象的属性传递给对应的SQL语句中的占位符,生成最终的SQL语句并执行更新。
3. 详细流程说明 select查找操作 1. MyBatis 中的 select 标签 2. resultType 属性
注意事项:
3. MyBatis 映射配置:起别名
在这个配置中:
这样,通过使用 AS 设置别名,可以直接在 SQL 语句中将数据库的列名与 Java 类的属性名进行对应,而无需修改数据库或 Java 类。
3. selectOne 方法
Car car = sqlSession.selectOne("selectById", 1);
select查所有的数据
sql语句
在这个查询中,使用了别名将数据库表中的列名映射到 Java 类 Car 中的属性名:
Java 代码中的 selectList 调用
List cars = sqlSession.selectList("selectAll");
注意事项