mybatis笔记整理
mybatis主要类的介绍
- Resources: mybatis中负责读取主配置文件
String config = "mybatis.xml";
InputStream in = Resources.getResourceAsStream(config);
- SqlSessionFactoryBuilder: 创建SqlSessionFactory对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
- SqlSessionFactory: 重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目一个就够了。
SqlSessionFactory是个接口,实现类是defaultSqlSessionFactory。作用是获取sqlSession对象。
openSession()方法说明:
openSession(): 无参,获取是非自动提交事务的sqlSession对象
openSession(boolean); openSession(true)获取自动提交事务的Sqlsession
SqlSession sqlSession = factory.openSession();
- SqlSession(核心方法)
SqlSession接口:定义了操作数据的方法,例如:selectOne(),selectList(),insert(),update(),delete(),commit(),rollback()
SqlSession的实现类DefaultSqlSession
使用要求:SqlSession对象线程不安全,需要在方法内使用,在执行sql语句之前,使用openSession()获取sqlSession对象。在执行完sql语句后,需要关闭它,执行SqlSession.close(),这样保证他的使用是线程安全的。
mybatis-mapper模板文件 dao映射文件
<?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="">
<select id="" resultType="">
</select>
</mapper
mybatis-config模板 resources主配置文件 mybatis.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>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<environments default="">
<environment id="">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/"/>
<property name="username" value="root"/>
<property name="password" value="137171"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource=""/>
</mappers>
</configuration>
<?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 控制mybatis全局行为-->
<settings>
<!--设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--环境配置:数据库的连接信息
default: 必须和某个environment的id值一样
告诉mybatis使用哪个数据库连接信息,也就是访问哪个数据库
-->
<environments default="mydev">
<!--environment 一个数据库信息的配置,环境
id 一个唯一值,自定义,表示当下环境的名称
-->
<environment id="mydev">
<!--
transactionManager: mybatis的事务类型
type: JDBC (表示使用jdbc中的Connection对象的commit,rollback做事务处理)
-->
<transactionManager type="JDBC"/>
<!--
daraSource: 表示数据源,连接数据库
type: 表示数据库的类型,POOLED表示使用连接池
-->
<dataSource type="POOLED">
<!--
driver,user,username,password 是固定的,不能自定义
-->
<!--数据库的驱动类名-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接数据库的url字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/ssh"/>
<property name="username" value="root"/>
<property name="password" value="137171"/>
</dataSource>
</environment>
<!--表示线上的数据库,是项目真实使用的库-->
<environment id="online">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/onlinedb"/>
<property name="username" value="root"/>
<property name="password" value="137171"/>
</dataSource>
</environment>
</environments>
<!--sql mappper(sql映射文件)的位置-->
<mappers>
<!-- 一个mapper标签指定一个文件的位置
从类路径开始的路径信息。target/classes(类路径)
-->
<mapper resource="com/zh/dao/Student01Dao.xml"/>
</mappers>
</configuration>
<!--
mybatis 的主配置文件 定义了数据库的配置信息,sql映射文件的位置
1.约束文件
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
mybatis-3-config.dtd 约束文件的名称
2.configuration 根标签
-->
动态代理
mybatis帮你创建dao接口的实现类,在实现类中调用SqlSession的方法执行sql语句
使用动态代理方式
1.获取SqlSession对象,SqlSessionFactory.openSession()
2.使用getMapper方法获取某个接口的对象,sqlSession.getMapper(接口.class)
3.使用dao接口的方法,调用方法就执行了mapper文件中的sql语句
使用动态代理的要求
1.dao接口和mapper文件放在一起,同一个目录
2.dao接口和mapper文件名称一致
3.mapper文件中的namespace的值是dao接口的全限定名称
4.mapper文件中的<select>,<insert>,<update>,<delete>等的id是接口中方法名称
5.dao接口中不要使用重载方法,不要使用同名的,不同参数的方法
1)自己创建实现类的方式
实现类
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudents() {
//获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
String sqlId = "com.zh.dao.StudentDao.selectStudents";
//执行sql语句,用SqlSession类里面的方法
List<Student> students = sqlSession.selectList(sqlId);
//关闭事务
sqlSession.close();
return students;
}
}
测试类
public class TestMyBatis {
@Test
public void testSelectStudent(){
StudentDao Dao = new StudentDaoImpl();
List<Student> students = Dao.selectStudents();
for (Student student: students){
System.out.println(student);
}
}
}
- 使用JDK动态代理机制,不用创建实现类,直接调用==SqlSession.getMapper(dao接口.class)==j,就可以得到dao接口的实现类
public class TestMyBatis {
@Test
public void testSelectStudent(){
/*
* 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口.class)
* getMapper能获取dao接口对应的实现类对象
*
* */
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class); //重点
System.out.println("dao="+dao.getClass().getName());//dao=com.sun.proxy.$Proxy2,JDK动态代理
List<Student> students = dao.selectStudents();
for (Student student : students){
System.out.println("学生"+student);
}
}
}
传入参数
从java代码中把数据传入到mapper文件的sql语句中
注意:parameterType
parameterType: dao接口中方法参数的数据类型
parameterType它的值是java的数据类型全限定名称或者是Mybatis定义的别名
例如:parameterType="java.lang.Integer"
parameterType="int"
注意:parameterType不是强制的,mybatis通过反射机制能够发现接口参数的数据类型,
所以可以没有,一般不写。
传入参数的几种方式
1 一个简单类型的参数:#{任意字符}
2 多个简单类型的参数,使用@Param("自定义名称")
3 使用一个java对象,对象的属性值作为mapper文件找到参数,#{java对象的属性值名称}
- 一个简单类型的参数
简单类型:mybatis把java的基本数据类型和String都叫简单类型
在mapper文件获取简单类型的一个参数的值,使用#{任意字符}
接口
public Student selectStudentById(Integer id);
mapper映射查询语句
<select id="selectStudentById" resultType="com.zh.entity.Student" parameterType="java.lang.Integer">
select id,name,email,age from student where id=#{id}
</select>
- 传递多个参数,在形参定义的前面加入 @Param(“自定义参数名称”) ★★★
接口
public List<Student> selectMulitParam(@Param("myname") String name,@Param("myage") String age)
mapper文件
<select>
select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>
- 传递多个参数,使用java对象作为接口中方法的参数 ★★★
自定义实体类 QueryParam.java
package com.zh.vo;
public class QueryParam {
private String paramName;
private Integer paramAge;
public String getParamName() {return paramName;}
public void setParamName(String paramName) {this.paramName = paramName;}
public Integer getParamAge() {return paramAge;}
public void setParamAge(Integer paramAge) { this.paramAge = paramAge;}}
}
接口
List<Student> selectMultiObject(QueryParam param);
mapper文件
<select id="selectMultiObject" resultType="com.zh.entity.Student">
select * from Student where name=#{paramName} or age=#{paramAge}
</select>
“#” 和 “$” 的区别
1 #是占位符,表示列值的,放在等号右侧
2 $是占位符,表示字符串的连接,把sql语句连接成一个字符串
3 #使用JDBC指定PreparedStatement对象执行SQL语句,效率高,没有sql注入的风险
4 $使用Starement对象执行sql,效率低,有sql注入的风险
封装Mybatis输出结果
- resultType
resultType 执行 sql 得到 ResultSet 转换的类型,使用类型的全限定名或别名。注意如果返回的是集合,那应该设置集合包含的类型。resultType 和 resultMap ,不能同时使用。
1 resultType 结果类型,指sql语句执行完成后,数据转为java对象,java类型是任意的
resultType 结果类型,它的值
1、类型的全限定名称
2、类型的别名,例如 java.lang.Integer的别名为int
接口方法
public Student selectStudentById(Integer id);
mapper映射
<select id="selectStudentById" resultType="com.zh.entity.Student" >
select id,name,email,age from student where id=#{id}
</select>
测试方法
@Test
public void testSelectStudentById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = dao.selectStudentById(2);
System.out.println("student="+student);
}
- resultMap
resultMap 可以自定义sql的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。常用在列名和 java 对象属性名不一样的情况。
定义自定义类型的别名
1 在mybatis主配置文件中定义,使用<typeAlias>定义别名
2 可以在resultType中使用自定义别名
resultMap 结果映射,指定列名和java对象属性的对应关系
1 你自定义列值赋值给哪个属性
2 当你的列名和属性名不一样时,一定使用resultMap
接口
//使用resultMap定义映射关系
List<Student> selectAllStudent();
mapper映射文件
<resultMap id="StudentMap" type="com.zh.entity.Student">
<!--column 列名 property java类型的属性名 -->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="email" column="email"/>
<result property="age" column="age"/>
</resultMap>
<!--使用resultMap-->
<select id="selectAllStudent" resultMap="StudentMap">
select id,name,email,age from student
</select>
- 当查询的列名和类中属性名不一样时
方式一
自定义MyStudent.java
package com.zh.entity;
public class MyStudent {
private Integer stuid;
private String stuname;
private String stuemail;
private Integer stuage;
public Integer getStuid() { return stuid;}
public void setStuid(Integer stuid) { this.stuid = stuid;}
public String getStuname() {return stuname;}
public void setStuname(String stuname) { this.stuname = stuname;}
public String getEmail() { return stuemail;}
public void setEmail(String email) { this.stuemail = email;}
public Integer getStuage() {return stuage;}
public void setStuage(Integer stuage) { this.stuage = stuage;}
@Override
public String toString() {
return "myStudent{" +
"stuid=" + stuid +
", stuname='" + stuname + '\'' +
", email='" + stuemail + '\'' +
", stuage=" + stuage +
'}';
}
}
mapper映射
<!-- type映射地址是 com.zh.entity.MyStudent.java -->
<resultMap id="myStudentMap" type="com.zh.entity.MyStudent">
<!--
column:别名
property: java类型的属性名
-->
<id property="stuid" column="id"/>
<result property="stuname" column="name"/>
<result property="stuemail" column="email"/>
<result property="stuage" column="age"/>
</resultMap>
<!--要查的sql列名和 MyStudent.java 属性名不一样-->
<select id="selectMyStudent" resultMap="myStudentMap">
select id,name,email,age from student
</select>
方式二
mapper映射: 直接在sql语句中添加 ( as 对象属性名)
<!--resultType的默认原则是:同名的列值赋值给同名的属性,使用列别名(java对象属性名)--->
<select id="selectDiffColProperty" resultType="com.zh.entity.MyStudent">
select id as stuid,name as stuname,email as stuemail,age as stuage from student
</select>
- like 模糊查询
在java代码中指定like的内容
//第一种模糊查询,在java代码指定like的内容
List<Student> selectLikeOne(String name);
mapper文件
<!--第一种like,java代码指定like的内容-->
<select id="selectLikeOne" resultType="com.zh.entity.Student">
select id,name,email,age from student where name like #{name}
</select>
测试类
@Test
public void testSelectLikeOne(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//定义一个String类型的值
String name = "%周%";
List<Student> students = dao.selectLikeOne(name);
for (Student stu : students){
System.out.println(stu);
}
sqlSession.close();
}
动态sql
sql内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发生变化。
动态sql的实现,使用的是mybatis提供的标签,,,
- 是判断条件
语法
部分sql语句
2) 用来包含多个,当多个if有一个成立时,会自动生成一个WHERE关键字,并去掉if中多余的and,or等
接口
//where
List<Student> selectStudentWhere(Student student);
mapper
<!--where
<where>
<if></if>
<if></if>
</where>
-->
<select id="selectStudentWhere" resultType="com.zh.entity.Student">
select id,name,email,age from student
<where>
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age > 0">
or age = #{age}
</if>
</where>
</select>
测试
//where
@Test
public void testSelectStudentWhere(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setName("周润发");
student.setAge(20);
List<Student> students = dao.selectStudentWhere(student);
for (Student student1 : students){
System.out.println("Where="+student1);
}
sqlSession.close();
}
执行结果:
去掉一个student.setName(“周润发”);执行结果:
3) 循环java中的数组,list集合的。主要用在sql的in语句中。
用法一 根据id查询
接口
//foreach
List<Student> selectForeachOne(List<Integer> idlist);
mapper
<!--foreach 方式一-->
<select id="selectForeachOne" resultType="com.zh.entity.Student">
select * from student where id in
<foreach collection="list" item="myid" open="(" close=")" separator=",">
#{myid}
</foreach>
</select>
测试
//foreach 方式一
@Test
public void testSelectForeachOne() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//定义一个list数组
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
List<Student> students = dao.selectForeachOne(list);
for (Student student : students) {
System.out.println("foreach=" + student);
}
}
用法二 根据对象属性查询
接口
//foreach 用法二 根据对象属性查询
List<Student> selectForeachTwo(List<Student> stulist);
mapper
<!--foreach 方式二-->
<select id="selectForeachTwo" resultType="com.zh.entity.Student">
select * from student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
测试
//foreach 方式二
@Test
public void testSelectForeachTwo() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<Student> stuList = new ArrayList<>();
Student s1 = new Student();
s1.setId(1);
stuList.add(s1);
Student s2 = new Student();
s2.setId(2);
stuList.add(s2);
List<Student> students = dao.selectForeachTwo(stuList);
for (Student student : students) {
System.out.println("foreach=" + student);
}
}
结果:
定义sql代码片段,替代相同sql语句
mapper
<!--定义sql片段-->
<sql id="studentSql">
select id,name,email,age from student
</sql>
<select id="selectStudentIf" resultType="com.zh.entity.Student">
-- select id,name,email,age from student
<include refid="studentSql"/>
where id > 0
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age >0">
or age > #{age}
</if>
</select>
数据库的属性配置文件,把数据库连接信息放到一个单独的文件中。便于修改,保存,处理多个数据库信息。
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssh
jdbc.username=root
jdbc.password=137171
mybatis.xml
<!--指定properties文件位置,从根路径开始找文件-->
<properties resource="jdbc.properties"/>
<environments default="one">
<environment id="one">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="#{jdbc.driver}"/>
<property name="url" value="#{jdbc.url}"/>
<property name="username" value="#{jdbc.username}"/>
<property name="password" value="#{jdbc.password}"/>
</dataSource>
</environment>
mybatis.xml 主配置文件中 sql映射文件读取书写说明:
<!--sql映射文件的位置-->
<mappers>
<!--方法一:指定多个mapper文件-->
<mapper resource="com/zh/dao/StudentDao.xml"/>
<!--方法二:使用包名
name:mapper文件所在的包名,包中所有xml一次性加载
要求:
1 mapper文件名需要和接口名一样
2 mapper文件和dao接口在同一目录下
-->
<package name="com.zh.dao"/>
</mappers>
本文地址:https://blog.csdn.net/weixin_40350981/article/details/109570137