Universe Infinity inc.
看似缓慢,实则迅捷。在处理事务时,我总在寻找最佳路径。在学习知识时,我曾试图通过捷径提高效率。但后来我发现,这些方法虽然看似快速,但在实际应用中效率却很低。相反,遵循最基本的方法,脚踏实地地提升,才能真正提高代码能力。因为代码能力最终还是要靠不断地编写和实践中提升的。
Mybatis开发几步内容
注意${}和#{}的区别
drop table `t_emp`;
CREATE TABLE `t_emp` (
emp_id INT AUTO_INCREMENT,
emp_name CHAR(100),
emp_salary DOUBLE(10 , 5 ),
PRIMARY KEY (emp_id)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("jerry",666.66);
INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("andy",777.77);
public class Employee {
private Integer empId;
private String empName;
private Double empSalary;
}
public interface EmployeeMapper {
//1、单个传参形式
Employee selectByEmpId(Integer empId);
Employee selectByEmpName(String empName);
//2、多个传参形式。自定义参数名时,要用@Param和mapper.xml中的参数匹配
int updateEmployee(@Param("empName") String empName, @Param("empSalary") Double empSalaryByMe);
//int updateEmployee(String empName, Double empSalaryByMe);
//3、实体传参时
int insertByEmployee(Employee employee);
//4、map类型传参
int updateEmployeeByMap(Map<String, Object> paramMap);
int insertEmployeeByMap(Map<String,Object> map);
}
<!-- namespace等于mapper接口类的全限定名,这样实现对应 -->
<mapper namespace="com.tang.springmybatis1.mapper.EmployeeMapper">
<!-- 查询使用 select标签
id = 方法名
resultType = 返回值类型
标签内编写SQL语句
-->
<!-- 1、单个简单数据类型传参-->
<select id="selectByEmpId" resultType="com.tang.springmybatis1.pojo.Employee">
<!-- #{empId}代表动态传入的参数,并且进行赋值!后面详细讲解 -->
select emp_id empId,emp_name empName, emp_salary empSalary from
t_emp where emp_id = ${empId} <!--${}这种形式非必要不用,会显式的出现在日志中,一般用于动态表名-->
</select>
<select id="selectByEmpName" resultType="com.tang.springmybatis1.pojo.Employee">
<!-- #{empId}代表动态传入的参数,并且进行赋值!后面详细讲解 -->
select emp_id empId,emp_name empName, emp_salary empSalary from
t_emp where emp_name = #{empName} <!--#{}这种形式在日志中的显式是?,保护数据安全-->
</select>
<!--2、多个简单类型传参-->
<update id="updateEmployee">
update t_emp set emp_salary=#{empSalary} where emp_name=#{empName}
</update>
<!--3、实体类类型传参
传入的Employee类
自动提取其成员变量的getXxx方法 注意#{}中的明明要和成员变量相同
-->
<insert id="insertByEmployee"> <!-- 插入数据使用insert标签-->
insert into t_emp(emp_name,emp_salary) values (#{empName},#{empSalary})
</insert>
<!--4、map类型传参。有很多零散的参数需要传递,但是没有对应的实体类类型可以使用.#{}中写Map中的key-->
<update id="updateEmployeeByMap">
update t_emp set emp_salary=#{empSalary} where emp_id=#{empId}
</update>
<insert id="insertEmployeeByMap">
insert into t_emp(emp_name,emp_salary) values (#{empName},#{empSalary})
</insert>
</mapper>
public class EmployeeTest2 {
private SqlSession session;
//junit5会在每一个@Test方法前执行@BeforeEach方法
@BeforeEach
public void init() throws IOException {
session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")).openSession();
}
//1、简单类型传参
@Test
public void testSelectByEmpId(){
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Employee employee = mapper.selectByEmpId(1);
System.out.println(employee);
}
@Test
public void testSelectByEmpName(){
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Employee employee = mapper.selectByEmpName("tang");
System.out.println(employee);
}
//2、多个简单类型传参
@Test
public void testUpdateEmployee(){
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
mapper.updateEmployee("tang",9999.0);
System.out.println(mapper.selectByEmpName("tang"));
}
//3、实体类型传参
@Test
public void testInsertByEmployee(){
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Employee employee = new Employee();
employee.setEmpName("wang");
employee.setEmpSalary(123.0);
int i = mapper.insertByEmployee(employee);
System.out.println(i);
System.out.println(mapper.selectByEmpName("wang"));
}
//4、mapper类型传参
@Test
public void testUpdateEmpNameByMap() {
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("empSalary", 999.99);
paramMap.put("empId", 5);
int result = mapper.updateEmployeeByMap(paramMap);
System.out.println(result);
}
@Test
public void testInsertEmployeeByMap(){
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
HashMap<String, Object> map = new HashMap<>();
map.put("empName","chen");
map.put("empSalary","98734.00");
int i = mapper.insertEmployeeByMap(map);
System.out.println(i);
}
//junit5会在每一个@Test方法后执行@AfterEach方法
@AfterEach
public void clear() {
session.commit();
session.close();
}
<configuration>
<settings>
<!-- SLF4J 选择slf4j输出! -->
<setting name="logImpl" value="SLF4J"/>
</settings>
<!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 -->
<environments default="development">
<!-- environment表示配置Mybatis的一个具体的环境 -->
<environment id="development">
<!-- Mybatis的内置的事务管理器 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源 -->
<dataSource type="POOLED">
<!-- 建立数据库连接的具体信息 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/>
<property name="username" value="tang"/>
<property name="password" value="pass"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
<!-- mapper标签:配置一个具体的Mapper映射文件 -->
<!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 -->
<!-- 对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 -->
<mapper resource="mapper/EmployeeMapper.xml"/>
<mapper resource="mapper/CategoriesMapper.xml"/>
</mappers>
</configuration>
其中使用了SLF4J作为输入,其配置如下。这里配置了debug的输出日志,用于日常测试
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
drop table `t_categories`;
CREATE TABLE `t_categories` (
category_id INT AUTO_INCREMENT,
category_name CHAR(10),
category_desc CHAR(100),
PRIMARY KEY (category_id)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
show create table t_categories;
INSERT INTO `t_categories` (category_name, category_desc)
VALUES
('手机', '各种品牌和型号的手机'),
('笔记本电脑', '各种品牌和型号的笔记本电脑'),
('图书', '各种类别和作者的图书'),
('电视', '各种尺寸和品牌的电视'),
('吸尘器', '各种型号和功率的吸尘器');
public class Categories {
private int categoryId;
private String categoryName;
private String categoryDesc;
}
public interface CategoriesMapper {
//1、返回为实体类形式
Categories selectCategoriesByName(String categoryName);
//2、返回Map类型,返回多个参数且没有实体类对应
@MapKey("categoryId")
Map<String,Object> selectCategoriesById(int categoryId);
//使用@MapKey注解后可以查询多个实体对象,其输出是一个列表形式
@MapKey("categoryId")
Map<String,Object> selectCategoriesAllByMap();
//3、返回List类型。查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回
List<Categories> selectCategoriesAllByList();
//4、返回主键值-自增型主键
int insertCategories(Categories categories);
int deleteCategoriesByName(String categoryName);
}
<!--namespace和具体的mapper接口类关联,使用全限定符-->
<mapper namespace="com.tang.springmybatis1.mapper.CategoriesMapper">
<!--1、返回为实体类形式,使用resultType指定对应的实体类-->
<select id="selectCategoriesByName" resultType="com.tang.springmybatis1.pojo.Categories">
select category_id categoryId,category_name categoryName,category_desc categoryDesc
from t_categories where category_name=#{categoryName};
</select>
<!--2、查询结果返回多个参数没有实体类对应时-->
<select id="selectCategoriesById" resultType="map">
select category_id categoryId,category_name categoryName,category_desc categoryDesc
from t_categories where category_id=#{categoryId};
</select>
<select id="selectCategoriesAllByMap" resultType="map">
select category_id categoryId,category_name categoryName,category_desc categoryDesc
from t_categories;
</select>
<!--3、查询结果返回List类型-->
<select id="selectCategoriesAllByList" resultType="com.tang.springmybatis1.pojo.Categories">
select category_id categoryId,category_name categoryName,category_desc categoryDesc
from t_categories;
</select>
<!--4、返回主键值-->
<!-- useGeneratedKeys属性字面意思就是“使用生成的主键” -->
<!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
<insert id="insertCategories" useGeneratedKeys="true" keyProperty="categoryId">
insert into t_categories(category_name,category_desc) values (#{categoryName},#{categoryDesc});
</insert>
<delete id="deleteCategoriesByName">
delete from t_categories where category_name=#{categoryName};
</delete>
</mapper>
public class CategoriesTest3 {
private SqlSession session;
//junit5会在每一个@Test方法前执行@BeforeEach方法
@BeforeEach
public void init() throws IOException {
session = new SqlSessionFactoryBuilder()
.build(
Resources.getResourceAsStream("mybatis-config.xml"))
.openSession();
}
//1、返回单个实体类
@Test
public void testSelectCategoriesByName() {
CategoriesMapper mapper = session.getMapper(CategoriesMapper.class);
Categories categories = mapper.selectCategoriesByName("手机");
System.out.println(categories);
}
//2、返回Map类型
@Test
public void testSelectCategoriesById(){
CategoriesMapper mapper =session.getMapper(CategoriesMapper.class);
Map<String, Object> stringObjectMap = mapper.selectCategoriesById(1);
System.out.println(stringObjectMap);
}
@Test
public void testSelectCategoriesAllByMap(){
CategoriesMapper mapper = session.getMapper(CategoriesMapper.class);
Map<String, Object> stringObjectMap = mapper.selectCategoriesAllByMap();
System.out.println(stringObjectMap);
}
//3、返回List类型
@Test
public void testSelectCategoriesAllByList(){
CategoriesMapper mapper = session.getMapper(CategoriesMapper.class);
List<Categories> categories = mapper.selectCategoriesAllByList();
System.out.println(categories);
for (Categories category : categories) {
System.out.println(category);
}
}
//4、返回主键值
@Test
public void testInsertCategories() {
CategoriesMapper mapper = session.getMapper(CategoriesMapper.class);
mapper.deleteCategoriesByName("公司");
Categories categories = new Categories();
categories.setCategoryName("公司");
categories.setCategoryDesc("公司也是能卖的");
int i = mapper.insertCategories(categories);
System.out.println(i);
System.out.println("返回的主键:" + categories.getCategoryId());
}
//junit5会在每一个@Test方法后执行@@AfterEach方法
@AfterEach
public void clear() {
session.commit();
session.close();
}
}
<mappers>
<!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
<!-- mapper标签:配置一个具体的Mapper映射文件 -->
<!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 -->
<!-- 对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 -->
<mapper resource="mapper/CategoriesMapper.xml"/>
</mappers>