I want to insert two rows into master and detail table.
Master and detail table with autoincremented id.
CREATE TABLE MI_User (
id_user NUMBER(11) NOT NULL,
age NUMBER(3),
name_user varchar2(128),
constraint USER_PK PRIMARY KEY (id_user));
CREATE TABLE Friends (
id_friend NUMBER(11) not null,
name VARCHAR2(64),
id_user NUMBER(11) NOT NULL,
constraint FRIEND_PK PRIMARY KEY (id_friend)
);
Model classes are:
public class User {
private String id;
private Integer age;
private String name;
private ArrayList<Friend> friends;
}
public class Friend {
private Long id_user;
private String name;
}
There is example from Hibernate:
tx = session.beginTransaction();
User user = new User(name, age);
employeeID = (Integer) session.save(employee);
tx.commit();
I try to insert with JDBS:
conn = DriverManager
.getConnection("jdbc:oracle:thin:#localhost:1521:xe", "hr", "hr");
ps = conn
.prepareStatement("INSERT INTO MI_USER (BALANCE, AGE, NAME_USER, GENDER, COMPANY, EMAIL, ADDRESS)\n" +
" VALUES (?, ?, ?, ?, ?, ?, ?)");
ps.setDouble(1, user.getDoubleBallans());
ps.setInt(2, user.getAge());
ps.setString(3, user.getName());
ps.executeUpdate();
How to get id_user and insert row into detail table?
I think you can use ps.getGeneratedKeys() method and send Statement.RETURN_GENERATED_KEYS as second parameter in conn.prepareStatement() method.
Related
For example if I add new Department(new BigInteger("50"), "ODD", "SPB"), all work, it values are insert into database. But if I want again insert for example new Department(new BigInteger("50"), "ODDMOD", "SPBMOD"), appear java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: unique constraint or index violation; SYS_PK_10092 table: DEPARTMENT. I know that can not insert values with the same primary key, but how can update values if primary key exists or other solutions?
public Department save(Department department) throws SQLException {
Connection connection = ConnectionSource.instance().createConnection();
String sql = "insert into department values (?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setLong(1, Long.parseLong(String.valueOf(department.getId())));
statement.setString(2, department.getName());
statement.setString(3, department.getLocation());
statement.executeUpdate();
PreparedStatement st = connection.prepareStatement("select * from department where id = ? ");
st.setLong(1, Long.parseLong(String.valueOf(department.getId())));
ResultSet resultSet = st.executeQuery();
resultSet.next();
Department demper = new Department(
new BigInteger(String.valueOf(resultSet.getInt("id"))),
resultSet.getString("name"),
resultSet.getString("location")
);
return demper;
}
You want an upsert here:
public Department save(Department department) throws SQLException {
Connection connection = ConnectionSource.instance().createConnection();
String sql = "MERGE INTO department d1 " +
"USING (VALUES ?, ?, ?) d2 (id, name, location) " +
" ON (d1.id = d2.id) " +
" WHEN MATCHED THEN UPDATE SET " +
" d1.name = d2.name, d1.location = d2.location " +
" WHEN NOT MATCHED THEN INSERT (id, name, location) VALUES (d2.id, d2.name, d2.location)";
PreparedStatement statement = connection.prepareStatement(sql);
// execute merge here as before
statement.setLong(1, Long.parseLong(String.valueOf(department.getId())));
statement.setString(2, department.getName());
statement.setString(3, department.getLocation());
statement.executeUpdate();
// ...
}
A MERGE behaves by doing an insert if the department id does not already exist in the table. Otherwise it will do an update. Note that if you shift to JPA/Hibernate from pure JDBC, the JPA save() method can upsert automatically for you under the hood.
I have a customer table and an address table. I'm trying to automatically insert the primary key value into the address table. Initially, I had it the other way around and it worked, however, the relationship was wrong since I wasn't able to delete cascade when a customer was deleted. Information inserts into the customer table but not the address table. This is what I have. Any insight would be appreciated.
/**
* Add a new customer.
* #param customer The customer to be added.
* #return customerId.
* #throws SQLException If an error happens.
*/
public int addCustomer(Customer customer) throws SQLException {
// first insert the address of the customer
//int addressId = addAddress(customer.getAddress());
// next insert the customer
var sql = "INSERT INTO customer (customerId, customerName, active, createdBy)" +
" VALUES (?, ?, ?, ?)";
var statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
statement.setInt(1, 0);
statement.setString(2, customer.getName());
//statement.setInt(3, addressId);
statement.setBoolean(3, customer.isActive());
statement.setString(4, customer.getCreatedBy());
statement.execute();
var generatedKeys = statement.getGeneratedKeys();
generatedKeys.next();
return (int) generatedKeys.getLong(1);
}
/**
* Add a new address to the database.
* #param address The address to be added.
* #throws SQLException if an error happens.
*/
public void addAddress(Address address) throws SQLException {
int customerId = addCustomer(address.getCustomer());
var sql = "INSERT INTO address (addressId, customerId, address, address2, cityId, countryId, postalCode, phone, createdBy) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
var statement = connection.prepareStatement(sql);
statement.setInt(1, 0);
statement.setInt(2, customerId);
statement.setString(3, address.getAddress());
statement.setString(4, address.getAddress2());
statement.setInt(5, address.getCity().getId());
statement.setInt(6, address.getCountry().getId());
statement.setString(7, address.getPostalCode());
statement.setString(8, address.getPhone());
statement.setString(9, address.getCreatedBy());
statement.execute();
}
Got some help with just updating the delete customer method so it deletes the associated address along with the customer.
enter code here
public void deleteCustomer(Customer customer) throws Exception {
var appointments =
appointmentRepository.findCustomerAppointments(customer.getId());
if(!appointments.isEmpty()){
throw new RuntimeException("Constraint Violation");
}
var deleteAddress = "DELETE FROM address WHERE addressId = ?";
var statementDeleteAddress = connection.prepareStatement(deleteAddress);
statementDeleteAddress.setInt(1, customer.getAddress().getId());
statementDeleteAddress.execute();
var sql = "DELETE FROM customer WHERE customerId = ?";
var statement = connection.prepareStatement(sql);
statement.setInt(1, customer.getId());
statement.execute();
My app allows users to create an account (stored in database) and place orders.
When a client registers himself, I want to generate a primary key named CLIENT_CODE to identify him, starting from x value and increment it with y value. (I'm using oracle 11g atm)
I've tried this so far:
private void jButton6ActionPerformed(java.awt.event.ActionEvent evt) {
String fname = jTextField9.getText();
String lname = jTextField10.getText();
String city = jTextField11.getText();
String street = jTextField13.getText();
String number = jTextField14.getText();
String userClient = jTextField15.getText();
String pass1 = String.valueOf(jPasswordField5.getPassword());
String pass2 = String.valueOf(jPasswordField6.getPassword());
if(verifyFields()){
if(!checkUsername(userClient)){
OraclePreparedStatement ps;
OracleResultSet rs;
String registerClient = "insert into CLIENT (FNAME_CL, LNAME, CITY, STREET, NUMBER, MONEY, CLIENT_CODE, USER_CLIENT, PASS) values (?, ?, ?, ?, ?, ?, ?, ?, ?)";
try {
ps = (OraclePreparedStatement) JavaConnectDb.ConnectDb().prepareStatement(registerClient);
ps.setString(1, fname);
ps.setString(2, lname);
ps.setString(3, city);
ps.setString(4, street);
ps.setString(5, number);
ps.setDouble(6, 0.0);
ps.setInt(7, ???); <--- here should be the generated primary key
ps.setString(8, userClient);
ps.setString(9, pass1);
if(ps.executeUpdate() != 0){
JOptionPane.showMessageDialog(null, "Account created!");
} else{
JOptionPane.showMessageDialog(null, "Error: Check your info");
}
} catch (SQLException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Don't do it in Java; handle the primary key value creation in the database using a sequence:
CREATE SEQUENCE CLIENT__CLIENT_CODE__SEQ
START WITH 1
INCREMENT BY 1
Then just use your sequence in the INSERT statement and use the RETURNING clause to get the generated value as an OUT parameter of your prepared statement.
insert into CLIENT (
FNAME_CL,
LNAME,
CITY,
STREET,
NUMBER,
MONEY,
CLIENT_CODE,
USER_CLIENT,
PASS
) values (
?,
?,
?,
?,
?,
?,
CLIENT__CLIENT_CODE__SEQ.NEXTVAL,
?,
?
) RETURNING CLIENT_CODE INTO ?
If you were using Oracle 12c then you could use GENERATED AS IDENTITY in the table's CREATE DDL statement to generate the values without creating a separate sequence.
I have an EMPLOYEE table that has 4 fields; ID, NAME, AGE, SALARY. ID is unique and auto-increment.
Below is the code to insert a row in the table, using Spring's JDBCTemplate. Please suggest, how can I auto increment ID field.
String sql = "insert into employee values (?,?,?,?)"
jdbcTemplate.update( sql, ID, bean.getName(), bean.getAge(), bean.getSalary())
I see, you tag your question Oracle, use Oracle sequence then.
String sql = "insert into Employee values (id_seq.nextval, ?, ?, ?)";
jdbcTemplate.update(sql, bean.getName(), bean.getAge(), bean.getSalary());
Ref: How to create Sequence in Oracle.
Just add following code to your domain:
Ref: http://docs.spring.io/spring/docs/2.5.x/reference/jdbc.html#jdbc-auto-genereted-keys
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
final String INSERT_SQL = "insert into my_test (name) values(?)";
final String name = "Rob";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps =
connection.prepareStatement(INSERT_SQL, new String[] {"id"});
ps.setString(1, name);
return ps;
}
},
keyHolder);
Trying to create CRUD application using jdbc and mysql. I have Person.class and two tables in Database:
class Person {
String name;
String surname;
List<String> phones;
}
Tables:
`phone`
(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`owner` INT UNSIGNED NOT NULL,
`number` VARCHAR(50) NOT NULL,
CONSTRAINT `PK_phone` PRIMARY KEY (`id`)
)
`person`
(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`surname` VARCHAR(150) NOT NULL,
`name` VARCHAR(150) NOT NULL,
CONSTRAINT `PK_phonebook` PRIMARY KEY (`id`)
)
ALTER TABLE `phone`
ADD CONSTRAINT `FK_phone_person`
FOREIGN KEY (`owner`) REFERENCES `person` (`id`) ON DELETE Cascade ON UPDATE Cascade
;
SET FOREIGN_KEY_CHECKS=1 ;
How i can add person with field List phones to database using Servlets???
For example: Harry Smith +37521987902
+56727172713
+45679012214
The idea is simple, you can use this way
Insert your person
get the id of that person
insert the list of phone
You can use it like this :
try {
Class.forName(driver);
Connection connection = DriverManager.getConnection(DB_URL, DB_username, DB_password);
String query = "INSERT INTO person (surname, name) values(?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, "hello");
preparedStatement.setString(2, "jdbc");
int affectedRows = preparedStatement.executeUpdate();
long id = 0;
if (affectedRows > 0) {
ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
if (generatedKeys.next()) {
id = generatedKeys.getLong(1);
} else {
throw new SQLException("Creating user failed, no ID obtained.");
}
}
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement("INSERT INTO phone (owner, number) values(?, ?)");
for (String phone : listePhone) {
preparedStatement.setLong(1, id);
preparedStatement.setString(2, phone);
ps.addBatch();
}
ps.executeBatch();
connection.commit();
}
You can learn how to execute multiple statement in one shot, using statement-batching