JDBC
public static void main(String[] args) {
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
Connection connection = null;
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 创建数据库连接
String url = "jdbc:mysql://127.0.0.1:3306/mybatis_0505";
String user = "root";
String password = "123456";
connection = DriverManager.getConnection(url, user, password);
// 创建statmenet
String sql = "SELECT * FROM tb_user WHERE id = ?";
preparedStatement = connection.prepareStatement(sql);
// 设置参数、执行sql,2个参数,第一个是参数的下标,从1开始,第二个参数数据查询条件数据
preparedStatement.setLong(1, 1L);
resultSet = preparedStatement.executeQuery();
// 遍历结果集
while (resultSet.next()) {
System.out.println("ID: " + resultSet.getLong("id"));
System.out.println("userName: " + resultSet.getString("user_name"));
System.out.println("password: " + resultSet.getString("password"));
System.out.println("name: " + resultSet.getString("name"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放连接(资源)
if (null != resultSet) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(null != preparedStatement){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(null != connection){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
存在问题
1、 驱动包硬编码到java代码中,更换数据库必须修改java文件重新编写,解决:定义到配置文件中。
2、 数据库连接字符串、用户名、密码硬编码到java代码中,解决:定义到配置文件中。
3、 Sql语句硬编码到java代码中
a) 修改sql,必须修改java文件、重新编译
b) 无法达到代码重用的作用
c) 解决方案:能否将sql写到配置文件中?
4、 设置参数有问题
a) 参数写死了,解决方案:传递进来即可
b) 需要判断参数类型,解决方案:能否自动判断?
c) 需要手动判断参数的位置,解决:能否自动判断?
5、 遍历结果集存在问题
a) 需要判断类型
b) 手动指定字段名
c) 解决:能否直接将结果集映射为java对象?
6、 释放资源存在问题,频繁的创建连接和关闭连接,造成资源的浪费,影响系统的性能,解决:使用连接池
关于pom war jar

jar是java工程, war 是web工程,pom是聚合工程
Mybatis的整体架构

问:如何获取sqlSessionFactory ?
答: 分两种情况,1.不存在spring 时候直接new sqlSessionFactoryBuild 2.存在spring_mybatise整合包时候,直接在水平bean得到
问:sql为什么没有List类型
答:把对象放到list,不可能把list映射到数据中
总结:
1、 mybatis的配置文件有2类
a) mybatisconfig.xml,配置文件的名称不是固定的,配置了全局的参数的配置,全局只能有一个配置文件。
b) Mapper.xml 配置多个statemement,也就是多个sql,整个mybatis框架中可以有多个Mappe.xml配置文件。
2、 通过mybatis配置文件得到SqlSessionFactory
3、 通过SqlSessionFactory得到SqlSession,得到SqlSession就可以操作数据了。
4、 SqlSession通过底层的Executor(执行器),执行器有2类实现:
a) 基本实现
b) 带有缓存功能的实现

5、 MappedStatement是通过Mapper.xml中定义statement生成的对象。
6、 参数输入,无需手动判断参数类型和参数下标位置
a) HashMap,KV格式的数据类型
b) Java的基本数据类型
c) POJO,java的对象
7、 结果集输出,自动将查询的结果集映射为java对象(POJO)
a) HashMap,KV格式的数据类型
b) Java的基本数据类型
c) POJO,java的对象
http://www.mybatis.org/mybatis-3/zh/index.html mybatise中文文档

1.编写main方法实例化SqlSessionFactory

配置mybatis-config.xml

执行sql查询总结
1、 配置UserMapper.xml,配置sql

2、 需要将UserMapper.xml添加到mybatis-config.xml中
3、 通过SqlSession执行

4、 测试

使用mybatis实现CRUD
定义UserDAO接口
public interface UserDAO {
/**
* 根据id查询用户数据
*
* @param id
* @return
*/
public User queryUserById(Long id);
/**
* 新增user数据
*
* @param user
*/
public void saveUser(User user);
/**
* 更新user数据
*
* @param user
*/
public void updateUser(User user);
/**
* 根据id删除用户数据
*
* @param id
*/
public void deleteUserById(Long id);
}
编写接口的实现类
public class UserDAOImpl implements UserDAO{
private SqlSessionFactory sqlSessionFactory;
public UserDAOImpl(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User queryUserById(Long id) {
SqlSession session = this.sqlSessionFactory.openSession();
User user = session.selectOne("userDAO.queryUserById", id);
session.close();
return user;
}
@Override
public void saveUser(User user) {
SqlSession session = this.sqlSessionFactory.openSession();
session.insert("userDAO.saveUser", user);
//提交事物
session.commit();
session.close();
}
@Override
public void updateUser(User user) {
SqlSession session = this.sqlSessionFactory.openSession();
session.update("userDAO.updateUser", user);
//提交事物
session.commit();
session.close();
}
@Override
public void deleteUserById(Long id) {
SqlSession session = this.sqlSessionFactory.openSession();
session.delete("userDAO.deleteUserById", id);
//提交事物
session.commit();
session.close();
}
}
编写UserDAOMapp.xml
<mapper namespace="userDAO">
<select id="queryUserById" resultType="cn.itcast.mybatis.pojo.User">
SELECT *,user_name userName FROM tb_user WHERE id = #{id}
</select>
<insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
INSERT INTO tb_user (
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
NULL,
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
</insert>
<update id="updateUser" parameterType="cn.itcast.mybatis.pojo.User">
UPDATE tb_user
SET
user_name = #{userName},
password = #{password},
name = #{name},
age = #{age},
sex = #{sex},
birthday = #{birthday},
updated = NOW()
WHERE
id = #{id}
</update>
<delete id="deleteUserById">
DELETE FROM tb_user WHERE id = #{id}
</delete>
</mapper>
加入到mybatis-config.xml中

public class UserDAOImplTest {
private UserDAO userDAO;
@Before
public void setUp() throws Exception {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
this.userDAO = new UserDAOImpl(sqlSessionFactory);
}
@Test
public void testQueryUserById() {
User user = this.userDAO.queryUserById(1L);
System.out.println(user);
}
@Test
public void testSaveUser() {
User user = new User();
user.setAge(20);
user.setBirthday(new Date());
user.setName("test_1");
user.setPassword("123456");
user.setSex(1);
user.setUserName("test_username_1");
this.userDAO.saveUser(user);
}
@Test
public void testUpdateUser() {
User user = this.userDAO.queryUserById(2L);
user.setAge(30);
this.userDAO.updateUser(user);
}
@Test
public void testDeleteUserById() {
this.userDAO.deleteUserById(6L);
}
}
字段名不对应 用resultMap
<!--
根据id查询得到一个order对象,使用这个查询是可以正常查询到我们想要的结果的,
这是因为我们通过<resultMap>映射实体类属性名和表的字段名一一对应关系 --> 参数parameterTye 传进来参数类型 resultType 结果的类型
<select id="selectOrderResultMap" parameterType="int" resultMap="orderResultMap">
select * from orders where order_id=#{id}
</select>
<!--通过<resultMap>映射实体类属性名和表的字段名对应关系 --> <!-- type是结果映射的java对象类型 相当于resultType -->
<resultMap type="me.gacl.domain.Order" id="orderResultMap">
<!-- 用id属性来映射主键字段 -->
<id property="id" column="order_id"/>
<!-- 用result属性来映射非主键字段 -->
<result property="orderNo" column="order_no"/>
<result property="price" column="order_price"/>
</resultMap>
一对多
<?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
例如namespace="me.gacl.mapping.classMapper"就是me.gacl.mapping(包名)+classMapper(classMapper.xml文件去除后缀)
-->
<mapper namespace="me.gacl.mapping.classMapper">
<!--
根据班级id查询班级信息(带老师的信息)
##1. 联表查询
SELECT * FROM class c,teacher t WHERE c.teacher_id=t.t_id AND c.c_id=1;
##2. 执行两次查询
SELECT * FROM class WHERE c_id=1; //teacher_id=1
SELECT * FROM teacher WHERE t_id=1;//使用上面得到的teacher_id
-->
<!--
方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
封装联表查询的数据(去除重复的数据)
select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=1
-->
<select id="getClass" parameterType="int" resultMap="ClassResultMap">
select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}
</select>
<!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" javaType="me.gacl.domain.Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
</association>
</resultMap>
<!--
方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
SELECT * FROM class WHERE c_id=1;
SELECT * FROM teacher WHERE t_id=1 //1 是上一个查询得到的teacher_id的值
-->
<select id="getClass2" parameterType="int" resultMap="ClassResultMap2">
select * from class where c_id=#{id}
</select>
<!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
<resultMap type="me.gacl.domain.Classes" id="ClassResultMap2">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" column="teacher_id" select="getTeacher"/>
</resultMap>
<select id="getTeacher" parameterType="int" resultType="me.gacl.domain.Teacher">
SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
</select>
</mapper>
分页插件
public PageInfo<User> selectDocByPage1(int currentPage, int pageSize) {
PageHelper.startPage(currentPage, pageSize);
List<User> user = docMapper.selectByPageAndSelections();
PageInfo<User> pageInfo = new PageInfo<>(user);
return pageInfo;
}
public ServerResponse<PageInfo> getProductList(int pageNum,int pageSize){
//startPage--start
//填充自己的sql查询逻辑
//pageHelper-收尾
PageHelper.startPage(pageNum,pageSize);
List<Product> productList = productMapper.selectList();
List<ProductListVo> productListVoList = Lists.newArrayList();
for(Product productItem : productList){
ProductListVo productListVo = assembleProductListVo(productItem);
productListVoList.add(productListVo);
}
PageInfo pageResult = new PageInfo(productList);
pageResult.setList(productListVoList);
return ServerResponse.createBySuccess(pageResult);
}
面试题:#{}与${}的区别


来源:https://www.cnblogs.com/hudj/p/7568336.html