- ①. JDBC的缺点(了解)
- ②. Mybatis概述及优缺点
- ③. 快速搭建Mybatis工程
- ④. MyBatis的增删改查 *** 作
- ⑤. 映射文件总结
- ①. 原始jdbc *** 作(查询数据)
- ②. 原始jdbc *** 作(插入数据)
- ③. 原始jdbc开发存在的问题如下:
- 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能
- sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql 变动需要改变java代码
- 查询 *** 作时,需要手动将结果集中的数据手动封装到实体中。插入 *** 作时,需要手动将实体的数据设置到sql语句的占位符位置
- ④. 应对上述问题给出的解决方案:
- 使用数据库连接池初始化连接资源
- 将sql语句抽取到xml配置文件中
- 使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射
-
①. mybatis是一个优秀的基于java的持久层框架/半自动的ORM,支持自定义SQL、储存过程以及高级映射。
-
②. Mybatis的优点:
- 与JDBC相比,减少了50%的代码量
- SQL代码从程序中彻底分离出来,可以分离
- 提供XML标签,支持写动态SQL
- 提供映射标签,支持对象与数据库的ORM字段关系映射
- ③. Mybatis的缺点:
- SQL语句编写工作量大,熟练度很高
- 数据库移植性比较差,如果切换数据库的话,SQL语句会有很大的差异
- ④. mybatis的工作原理
- 读取MyBatis配置文件mybatis-config.xml。mybatis-config.xml作为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,其中主要内容是获取数据库连接
- 加载映射文件Mapper.xml。Mapper.xml文件即SQL映射文件,该文件中配置了 *** 作数据库的SQL语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml可以加载多个配置文件,个配置文件对应数据库中的一张表
- 创建会话工厂,通过MyBatis的环境等配置信息构造会话工厂SqlSessionFactory
- 创建SqlSession对象。由会话工厂创建SqlSession对象,该对象中包含了执行SQL的所有方法
- MyBatis底层定义了一个Executor接口来 *** 作数据库,它会根据SqlSession传递的形参的所有方法
- 在Execuotor接口的执行方法中,包含了一个MappedStatement类型的参数,该参数是对映射信息
的封装,用来存储要映射的SQL语句的id、参数等。Mapper.xml文件中的一个SQL对应一个
MappedStatement对象,SQL的id是MappedStatement的id - 输入参数映射。在执行方法时,MapperStatement对象会对用户执行SQL语句的输入参数进行定义(可以定义为Map、List、基本数据类型和POJO类型),Executor执行器会通过MappedStatement对象在执行SQL前,将输入的Java对象映射到SQL语句中。这里对输入参数的映射过程就类似于JDBC编程中对PreparedStatement对象设置参数的过程
- 输出结果映射。在数据库中执行完SQL语句后,MappedStatement对象会对SQL执行输出的结果进行定义(可以定义为Map和List类型、基本类型、POJO类型),Executor执行器会通MappedSt atement对象在执行SQL语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程
- ①. 输入官网网址
- ②. 导入依赖
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.5version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.26version>
<scope>runtimescope>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.12version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.16.12version>
dependency>
- ③. 通过官网写mybatis的配置文件
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://localhost:3306/ssm_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/xiaozhi/mapper/UserMapper.xml"/>
mappers>
configuration>
- ④. 编写实体类及MyBatis核心文件
@Data
@ToString
public class User {
private Integer id;
private String userName;
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaozhi.dao.UserMapper">
<select id="findEmpById" resultType="com.xiaozhi.entity.User" parameterType="Integer">
select * from user where id=#{id};
select>
mapper>
- ⑤. 编写测试代码
public class EmpTest {
/*通过id查询*/
@Test
public void test1()throws Exception{
//1.加载配置文件
InputStream inputStream= Resources.getResourceAsStream("sqlMapConfig.xml");
//2.获取工厂对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//3.创建会话对象
SqlSession sqlSession=sqlSessionFactory.openSession();
//4.执行 *** 作 namespace+id
User emp =sqlSession.selectOne("com.xiaozhi.dao.UserMapper.findEmpById",1);
System.out.println(emp);
//5.释放资源
sqlSession.close();
}
}
- ⑥. 加入日志文件,可以看到打印的SQL log4j.properties
# log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=D:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout
④. MyBatis的增删改查 *** 作
- ①. 抽取工具类
public class MybatisUtils {
/*私有构造方法*/
private MybatisUtils(){}
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//1.加载配置文件
InputStream inputStream= Resources.getResourceAsStream("sqlMapConfig.xml");
//2.给SqlSessionFactory工厂赋值
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//3.获取sqlSession会话对象
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
- ②. 查询(查询所有、通过id进行查询、模糊查询)
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaozhi.dao.UserMapper">
<select id="findAll" resultType="com.xiaozhi.entity.User">
select * from user
select>
<select id="findUserById" parameterType="Integer" resultType="com.xiaozhi.entity.User">
select * from user where id=#{id}
select>
<select id="findUserByName" parameterType="String" resultType="com.xiaozhi.entity.User">
select * from user where username like concat('%',#{value},'%')
select>
mapper>
/*1.查询所有*/
@Test
public void SelectAll()throws Exception{
//1.加载配置文件
InputStream inputStream=Resources.getResourceAsStream("sqlMapConfig.xml");
//2.获取SqlSesiionFactory会话工厂
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//3.创建sqlSession会话对象
SqlSession sqlSession=sqlSessionFactory.openSession();
//4.执行 *** 作
List<User> list=sqlSession.selectList("userMapper.findAll");
System.out.println(list);
//5.释放资源
sqlSession.close();
}
/*2.通过id查询用户信息*/
@Test
public void selectById()throws Exception{
//1.加载配置文件
InputStream inputStream=Resources.getResourceAsStream("sqlMapConfig.xml");
//2.创建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//3.创建SqlSession会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.执行sql
User user=sqlSession.selectOne("userMapper.findUserById",1);
System.out.println(user);
//5.释放资源
sqlSession.close();
}
/*3.根据姓名进行模糊查询*/
@Test
public void selectByName()throws Exception{
//1.获取会话对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.执行sql
List<User> list = sqlSession.selectList("userMapper.findUserByName", "x");
System.out.println(list);
}
- ③. 添加一个用户
#{id}:从输入user对象中获取id属性值
<insert id="insertUser" parameterType="com.xiaozhi.entity.User">
insert into user(id,username)values(#{id},#{username})
insert>
/*4.新增一条User记录*/
@Test
public void add()throws Exception{
//1.获取会话对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.执行sql
//2.1 创建User对象
User user=new User();
user.setId(2);
user.setUsername("xiaozhi");
int row=sqlSession.insert("userMapper.insertUser",user);
System.out.println(row);
//3.进行事务的提交
sqlSession.commit();
//4.释放资源
sqlSession.close();
}
- ④. 修改一条记录
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{username},password=#{password} where id=#{id}
update>
/*5.修改*/
@Test
public void update()throws Exception{
//1.获取会话对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.执行sql
User user=new User();
user.setId(2);
user.setUsername("xiaoxing");
int result=sqlSession.update("userMapper.updateUser",user);
System.out.println(result);
//3.进行事务的提交
sqlSession.commit();
//4.释放资源
sqlSession.close();
}
- ⑤. 通过id进行删除
<delete id="deleteById" parameterType="java.lang.Integer">
delete from user where id=#{id}
delete>
/*6.删除*/
@Test
public void delete()throws Exception{
//1.获取会话对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//2.执行sql
int result=sqlSession.delete("userMapper.deleteById",1);
System.out.println(result);
//3.进行事务的提交
sqlSession.commit();
//4.释放资源
sqlSession.close();
}
⑤. 映射文件总结
-
①. namespace命名空间:作用就是对sql进行分类化管理,理解sql隔离。通常会设置成包名+sql映射文件名注意:使用namespace代理方式开发,namespace有特殊的作用
-
②. 通过select执行数据查询
- id:标识映射文件的sql,称为statement的id
(将sql语句封装mappedStatement对象中,所以将id称为statement的id ) - #{}:表示占位符,相当于?
- #{id}:其中的id表示接收输入的参数,参数名称是id,如果输入参数是简单类型,#{}中的参数名可以任意,可以value或其他名称
- parameterType:指定输入参数类型,这里指定int型
- resultType:指定sql输出结果的映射的java类型,resultType表示将单条记录映射成的java对象
<mapper namespace="test">
<select id="findCustomerById" parameterType="Integer"
resultType="com.itcast.mybatis.po.User">
select * from user where id = #{id}
select>
mapper>
- ③. parameterType 和 resultType
- parameterType:在映射文件中通过parameterType指定输入参数的类型
- resultType:在映射文件中通过resultType指定输出结果的类型
- ④. selectOne(statement,parament)和selectList(statement,parament)
- 第一个参数statement:映射文件中statement的id,等于=namaspace+statementId
- 第二个参数parament:指定和映射文件中所匹配paramtype类型的参数(输入参数)
- session.selectOne 结果是与映射文件中所匹配的resultType类型的对象
- ⑤. selectOne和selectList
- selectOne:表示查询出一条记录进行映射。如果使用了selectOne可以实现,那么使用selectLis也可以实现 (List中只有一个对象)
- selectList:表示查询出一个列表(多个列表)进行映射,如果使用了,如果使用selectList要查询多天记录,不能使用selectOne
- ⑥. 模糊查询注意事项
# 第一种情况是字符串的拼接,会引起sql注入,不推荐使用
1.select * from user where username like ‘%${value}%’
2.select * from user where username like concat('%',#{value},'%')
- ⑦. #{ } 和 ${ }
#{}:
1. #{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo等
2. 如果接受简单类型,#{}里面的可以写成value或其他的
3. #{}接受的是pojo。要通过user.user.username的形式获取
${}:
1.表示一个拼接符号,会引起sql注入,所以不建议使用
2.${} 接受输入参数,类型可以是简单类型,pojo等
3.${} 接受的是pojo。要通过 user.user.username的形式获取
# 如:需要执行如下的SQL,#{}是预编译处理,是占位符
select * from user where name = #{userName};设userName=TANG
# 看日志我们可以看到解析时将#{userName}替换成了?
select * from user where name = ?;
# 然后再把TANG放进去,外面加上单引号
# 如:需要执行如下的SQL,${}是字符串替换,是拼接符
select * from user where name = #{userName};设userName=yuze
# 看日志可以发现就是直接把值拼接上去了
select * from user where name = yuze;
# 这极有可能发生sql注入,下面举了一个简单的sql注入案例
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)