1. MyBatis学习
1. 为什么要学习mybatis
- MyBatis 是⼀一款优秀的持久层框架,它⽀支持⾃自定义 SQL、存储过程以及⾼高级映射。MyBatis 免除了了⼏几乎 所有的 JDBC 代码以及设置参数和获取结果集的⼯工作。MyBatis 可以通过简单的 XML 或注解来配置和映 射原始类型、接⼝口和 Java POJO(Plain Old Java Objects,普通⽼老老式 Java 对象)为数据库中的记录。
其前身为apache的ibatis后来迁移到Gihub并更更名为MyBatis - mybatis是封装jdbc代码 使代码变得易于维护。
2.Mybatis在结构中的位置
可以看出MyBatis处在DAO(数据访问对象)的位置,回顾⼀一下DAO的⼯工作职责:
- 连接数据库
接收输⼊入数据
拼接并执⾏行行SQL
解析并返回结果
3. 编写步骤
1. mybatis-config.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>
<!--加载jdbc配置文件-->
<properties resource="jdbc.properties"/>
<environments default="development">
<!-- 可配置多个环境 并指定默认使用的环境-->
<environment id="development">
<!-- 指定事务管理器-->
<transactionManager type="JDBC"/>
<!-- 指定数据源 就是数据来自哪里 这里默认使用MyBatis自带的连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 指定要加载的映射文件-->
<mappers>
<!-- 2.也可以指定绝对路径或者相对路径-->
<mapper resource="mapper/ProductsMapper.xml"/>
<!-- 3. 通过指定接口自动查找mapper 要求:mapper文件必须要与接口处于同一目录 并且文件名称必须保持一致 -->
<!-- <mapper class="com.wei.mapper.ProductsMapper"/>-->
<!-- 4.通过指定包来会扫描包下的所有接口 与第三种有同样的要求-->
</mappers>
</configuration>
2. ProductsMapper.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">
<!-- 1.名称空间 用来区分多个不同包下的相同语句 通常是对应的包名称-->
<!--查询语句句
id⽤用于标识这条sql
parameterType 表示 sql语句句接受⼀一个整数参数
resultType表示 将结果映射到Products对象中
#{} 表示⼀一个站位符等同于 ? -->
<mapper namespace="com.wei.mapper.ProductsMapper">
<!-- 在使用指定参数传入时,#{} 里面最好命名为参数名称 方便记忆 -->
<select id="selectById" parameterType="java.lang.String" resultType="com.wei.pojo.Products">
select * from products where pid = #{pid}
</select>
<select id="selectNandP" parameterType="map" resultType="com.wei.pojo.Products">
select * from products where pname = #{pname} and price = #{price};
</select>
<!-- 3.使用模糊查询-->
<select id="selectByName" resultType="com.wei.pojo.Products" parameterType="java.lang.String">
select * from products where pname like "%${name}%"
</select>
<!-- 4.更新操作-->
<update id="updateById" parameterType="com.wei.pojo.Products" >
update products set pname = #{pname},price = #{price},pdate = #{pdate},cid = #{cid} where pid = #{pid}
</update>
<!-- 5. 删除操作-->
<delete id="delById" parameterType="int" >
delete from products where pid = #{pid}
</delete>
<!-- 6.插入-->
<insert id="insertBy" parameterType="com.wei.pojo.Products">
insert into products value (null,#{pname},#{price},#{pdate},#{cid})
</insert>
<!--
1. parameterType 是什么
输入的参数类型
2. resultType 是什么
是期望的返回结果类型
3. #{} 用于取值
4.在字符串中获取参数,必须将#换成$
5.在CRUD中需要提交事物 sqlSession.commit(); 也可以 sqlSession = factory.openSession(true);
-->
</mapper>
3.log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4. jdbc.properties
username = root
password = 611611
url = jdbc:mysql:///mybatisDB?serverTimezone=Asia/Shanghai&characterEncoding=utf8
5. 编写测试代码
5.1 查询数据
//具有相同的方法 用于初始化
@Before
public void before() throws Exception {
//1.读取文件的输入流 创建会话工厂
factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
}
@Test
public void myTest() {
//2.创建一个会话
SqlSession sqlSession = factory.openSession();
//3.执行sql
Products pro = sqlSession.selectOne("selectById","3");
//4.打印输出结果
System.out.println(pro);
}
5.2 模糊查询
对应sql 模糊查询
<select id="selectProductLikeName" parameterType="string" resultType="com.kkb.pojo.Products">
select *from products where pname like "%${name}%"
</select>
测试代码
@Test public void selectTest2() throws IOException {
//获得会话
SqlSession sqlSession = factory.openSession();
//执⾏行行sql
List<Products> products = sqlSession.selectList("selectProductLikeName", "新 疆");
System.out.println(products);
sqlSession.close(); }
- 需要注意的是:在mapper中当需要做将参数进⾏行行字符串串拼接时则不不能在使⽤用#{} 需更更换为${}表示将 参数结果提取并拼接到字符串串中
5.3 查询带有多个参数
- 多个参数可使parameterType=“map” 返回集合类型
<select id="selectNandP" parameterType="map" resultType="com.wei.pojo.Products">
select * from products where pname = #{pname} and price = #{price};
</select>
@Test
public void myTest02() {
try{
//2.创建一个会话
sqlSession = factory.openSession();
//创建map
HashMap<String,Object> map = new HashMap<>();
map.put("pname","十三香");
map.put("price","10.0");
//3.执行sql
Products pro = sqlSession.selectOne("selectNandP",map);
//4.打印输出结果
System.out.println(pro);
//关闭资源
}finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
5.4 插入
<!-- insert没有返回值--> <insert id="insertBy" parameterType="com.kkb.pojo.Products">
insert into products values(null,#{pname},#{price},#{pdate},#{cid})
</insert>
//插入测试
@Test
public void insTest() {
try{
sqlSession = factory.openSession(true);
Products products = new Products();
products.setPname("长沙臭豆腐");
products.setPrice(10.0);
products.setPdate(new Date());
products.setCid("s1");
int insertBy = sqlSession.insert("insertBy", products);
System.out.println(insertBy);
}finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
5.5 更新
<!-- 4.更新操作-->
<update id="updateById" parameterType="com.wei.pojo.Products" >
update products set pname = #{pname},price = #{price},pdate = #{pdate},cid = #{cid} where pid = #{pid}
</update>
//更新操作
@Test
public void update() {
try{
sqlSession = factory.openSession(true);
//先查出对象
Products selectById = sqlSession.selectOne("selectById", "2");
//修改
selectById.setPrice(299);
//3.执行sql
int pro = sqlSession.update("updateById",selectById);
//4.打印输出结果
System.out.println(pro);
// sqlSession.commit();
}finally {
if (sqlSession != null) {
sqlSession.close();
}
}